Spring WebFlow (seemingly) randomly stops working in Spring Boot app -


i have flow seemed working fine until yesterday, when started getting following exception in html page maps first state in flow:

org.springframework.expression.spel.spelevaluationexception: el1007e:(pos 0): property or field 'flowscope' cannot found on null 

the offending line of code was:

<h3 th:text="${flowrequestcontext.flowscope}"/> 

further investigation showed none of flow variables available anymore. furthermore if put print statements service flow makes various calls to, can see none of these methods being called anymore - it's flow isn't running @ all.

this was working fine previously. reverted of local changes stable version of code, , same issue happening there well. thing seemed temporarily around problem restart computer - problem disappeared short while came back.

to honest i'm out of ideas have started causing such intermittent problem. thinking along lines of stale java process running in background interfering future runs of application, have checked , killed off remaining process in between deploys no avail.

i have included hope relevant file below. resolving issue appreciated.

checkout.xml

<?xml version="1.0" encoding="utf-8"?> <flow xmlns="http://www.springframework.org/schema/webflow"     xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"     xsi:schemalocation="http://www.springframework.org/schema/webflow             http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">      <on-start>         <set name="flowscope.paymentmethods" value="checkoutwidgetservice.getpaymentmethods()"/>         <set name="flowscope.deliveryaddress" value="checkoutwidgetservice.getdeliveryaddress()"/>         <set name="flowscope.sessionid" value="externalcontext.nativerequest.session.id"/>     </on-start>      <view-state id="payment-methods" view="payment-methods">         <transition on="selectpaymentmethod" to="new-details">             <evaluate expression="checkoutwidgetservice.getcarddetails(requestparameters.type)" result="flowscope.carddetails"/>         </transition>     </view-state>      <view-state id="new-details" view="new-details">         <transition on="submitdetails" to="summary">             <evaluate expression="checkoutwidgetservice.buildcarddetails(requestparameters)" result="flowscope.carddetails"/>         </transition>     </view-state>      <view-state id="summary" view="summary">         <transition on="completecheckout" to="redirect">             <evaluate expression="checkoutwidgetservice.completecheckout(externalcontext.nativerequest.session, flowrequestcontext, flowscope.carddetails)"/>         </transition>         <transition on="cancelcheckout" to="redirect">             <evaluate expression="checkoutwidgetservice.cancelcheckout(externalcontext.nativerequest.session, flowrequestcontext)"/>         </transition>     </view-state>      <end-state id="redirect" view="externalredirect:contextrelative:/payments/checkout-widgets/end"/> </flow> 

webflowconfig.java

@configuration @autoconfigureafter(mvcconfig.class) public class webflowconfig extends abstractflowconfiguration {      @autowired     private springtemplateengine templateengine;      @bean     public flowexecutor flowexecutor() {         return getflowexecutorbuilder(flowregistry())                 .addflowexecutionlistener(new securityflowexecutionlistener())                 .build();     }      @bean     public flowdefinitionregistry flowregistry() {         return getflowdefinitionregistrybuilder(flowbuilderservices())                 .addflowlocation("classpath:/templates/checkout.xml", "payments/checkout-widget/start")                 .build();     }      @bean     public flowbuilderservices flowbuilderservices() {         return getflowbuilderservicesbuilder()                 .setviewfactorycreator(mvcviewfactorycreator())                 .setdevelopmentmode(true)                 .build();     }      @bean     public flowcontroller flowcontroller() {         flowcontroller flowcontroller = new flowcontroller();         flowcontroller.setflowexecutor(flowexecutor());         return flowcontroller;     }      @bean     public flowhandlermapping flowhandlermapping() {         flowhandlermapping flowhandlermapping = new flowhandlermapping();         flowhandlermapping.setflowregistry(flowregistry());         flowhandlermapping.setorder(-1);         return flowhandlermapping;     }      @bean     public flowhandleradapter flowhandleradapter() {         flowhandleradapter flowhandleradapter = new flowhandleradapter();         flowhandleradapter.setflowexecutor(flowexecutor());         flowhandleradapter.setsaveoutputtoflashscopeonredirect(true);         return flowhandleradapter;     }      @bean     public ajaxthymeleafviewresolver thymeleafviewresolver() {         ajaxthymeleafviewresolver viewresolver = new ajaxthymeleafviewresolver();         viewresolver.setviewclass(flowajaxthymeleafview.class);         viewresolver.settemplateengine(templateengine);         return viewresolver;     }      @bean     public mvcviewfactorycreator mvcviewfactorycreator() {         list<viewresolver> viewresolvers = new arraylist<>();         viewresolvers.add(thymeleafviewresolver());          mvcviewfactorycreator mvcviewfactorycreator = new mvcviewfactorycreator();         mvcviewfactorycreator.setviewresolvers(viewresolvers);         mvcviewfactorycreator.setusespringbeanbinding(true);         return mvcviewfactorycreator;     }  } 

checkoutwidgetsessionmvccontroller.java

@controller @requestmapping("/payments/checkout-widgets") public class checkoutwidgetsessionmvccontroller {      @inject     private checkoutwidgetservice service;      @requestmapping(value = {"/start"}, method = requestmethod.get)     public modelandview paymentmethods() {         return new modelandview("payment-methods", null);     }      @requestmapping(value = "/end", method = requestmethod.get)     public string invalidatesession(httpsession session) {         service.invalidatesession(session);         return "dummy-redirect-post";     } } 

checkoutwidgetservice.java

public interface checkoutwidgetservice {      list<paymentmethod> getpaymentmethods();      carddetails getcarddetails(string name);      carddetails buildcarddetails(localparametermap params);      string getdeliveryaddress();      void completecheckout(httpsession session, requestcontext context, carddetails carddetails);      void cancelcheckout(httpsession session, requestcontext context);      void invalidatesession(httpsession session); } 

checkoutwidgetserviceimpl.java

@service("checkoutwidgetservice") public class checkoutwidgetserviceimpl implements checkoutwidgetservice {      @inject     private checkoutwidgetsessionservice sessionservice;      private final list<paymentmethod> paymentmethods = new arraylist<>();      private final string deliveryaddress;      public checkoutwidgetserviceimpl() {         paymentmethods.add(new paymentmethod("paypal", "/images/paypal-logo.png"));          paymentmethods.add(new paymentmethod("mastercard", "/images/mc-logo.png"));         paymentmethods.add(new paymentmethod("visa", "/images/visa-logo.png"));         paymentmethods.add(new paymentmethod("amex", "/images/amex-logo.png"));         paymentmethods.add(new paymentmethod("google checkout", "/images/google-logo.png"));         deliveryaddress = "xxxxx";     }     @override     public list<paymentmethod> getpaymentmethods() {         system.out.println("returning paymentmethods: " + paymentmethods);         return paymentmethods;     }      @override     public carddetails getcarddetails(string name) {         carddetails carddetails = new carddetails();         carddetails.setcardtype(name);         return carddetails;     }      @override     public carddetails buildcarddetails(localparametermap params) {         carddetails carddetails = new carddetails();         carddetails.setcardnumber(params.get("cardnumber"));         carddetails.setexpirymonth(params.get("expirymonth"));         carddetails.setexpiryyear(params.get("expiryyear"));         carddetails.setnameoncard(params.get("nameoncard"));         carddetails.setcvv2(params.get("cvv2"));         return carddetails;     }      @override     public string getdeliveryaddress() {         return deliveryaddress;     }      @override     public void invalidatesession(httpsession session) {         session.invalidate();     }      private redirecturls getredirecturls(string sessionid) {         checkoutwidgetsession widgetsession = sessionservice.getcheckoutwidgetsession(sessionid).get();         return widgetsession.getredirecturls();     }      @override     public void completecheckout(httpsession session, requestcontext context, carddetails carddetails) {         redirecturls redirects = getredirecturls(session.getid());          context.getflowscope().remove("paymentmethods");          uribuilder uribuilder = uribuilder.fromuri(uri.create(redirects.getsuccessurl()));         string forwardurl = uribuilder.queryparam("transactionid", "12345").tostring();         context.getflowscope().put("forwardurl", forwardurl);         context.getflowscope().put("target", "_top");     }      @override     public void cancelcheckout(httpsession session, requestcontext context) {         redirecturls redirects = getredirecturls(session.getid());          context.getflowscope().remove("paymentmethods");          string forwardurl = redirects.getcancelurl();         context.getflowscope().put("forwardurl", forwardurl);         context.getflowscope().put("target", "_top");     } } 

application.java

@enableautoconfiguration @componentscan(basepackages = {"com.pay.widgets.checkout"}) @import(jerseyautoconfiguration.class) public class application extends springbootservletinitializer {      @override     protected springapplicationbuilder configure(springapplicationbuilder application) {         return application.sources(application.class);     }      public static void main(string[] args) {         springapplication.run(application.class, args);      } } 

okay stupid mistake on part, problem turned out down typo in @requestparameter annotation on controller:

payments/checkout-widgets 

which didn't line in webflowconfig defined flowregistry:

payments/checkout-widget 

i can assume resource cached tomcat why took long issue manifest , threw me off scent in terms of suspecting own changes responsible.


Comments

Popular posts from this blog

javascript - Any ideas when Firefox is likely to implement lengthAdjust and textLength? -

matlab - "Contour not rendered for non-finite ZData" -

delphi - Indy UDP Read Contents of Adata -