AnsweredAssumed Answered

XML-based Web-Service issues with JSF validation

Question asked by rovo on Jun 21, 2012
Hello,

for a tech-demo we created a business process which contains different methods of invoking web services, so we have a mixture of mocked SOAP and REST services which further use either JavaDelegates or ActivitiBehavoir or for a singe SOAP service the xml-based (experimental) invocation method. On unit-testing the whole process finishes without any errors but on integrating the process engine into a JSF 2.0 (Tomcat only) web server the xml-based invocation breaks the validation phase of JSF.

The setup is as follows:
We use a Sigleton class which initializes the Activiti Engine as standalone in memory and deploys the business process contained in the .war-file. The instance-id (and task-id) are past between views as request parameter and in-view via hidden fields to have access to them at validation level. We used FormService.submitTaskFormData(taskId, inputMap) to pass data to the Activiti engine. As we are unsure on how to retrieve the success of the executed task(s) we added an ExecutionListener listening to end-events to those task we need to check for their outcome (have loopbacks to the user task to correct the inputs; simple Validation Services like enough money on the saving account and so on). So we are effectivly executing the task at validation time and only redirect to the next user tasks formKey within the submit-method. If a validation fails a FacesMessage is created and further JSF lifecycle levels are omitted by calling FacesContext.renderResponse();

This approach does work for JavaDelegate and ActivitiBehavior based web services but fails for xml-based ones - but only on JSF-side as JUnit-Tests do not produce any errors on wrong inputs for the xml-based web service. The service itself takes a String as input and returns a Double as output - so a quite simple service - as of missing exception handling for the xml-based approach we return 0D for wrong inputs and later on have a XOR to branch the invalid inputs from the valid inputs. A following script just sets a ValidationError inside the ActivitEngine and defines an ExecutionListener too to broadcast the error to JSF - but on running Tomcat and entering a wrong input we end up with the following output:



FEIN: — SubmitTaskFormCmd finished ——————————————————–
21.06.2012 00:47:03 org.activiti.engine.impl.interceptor.LogInterceptor execute
FEIN:                                                                                                    
21.06.2012 00:47:03 org.activiti.engine.impl.interceptor.LogInterceptor execute
FEIN:                                                                                                    
21.06.2012 00:47:03 org.activiti.engine.impl.interceptor.LogInterceptor execute
FEIN: — starting TaskQueryImpl ——————————————————–
21.06.2012 00:47:03 org.activiti.engine.impl.db.DbSqlSession flush
FEIN: flush summary:
21.06.2012 00:47:03 org.activiti.engine.impl.db.DbSqlSession flush
FEIN: now executing flush…
21.06.2012 00:47:03 org.activiti.engine.impl.cfg.standalone.StandaloneMybatisTransactionContext commit
FEIN: firing event committing…
21.06.2012 00:47:03 org.activiti.engine.impl.cfg.standalone.StandaloneMybatisTransactionContext commit
FEIN: committing the ibatis sql session…
21.06.2012 00:47:03 org.activiti.engine.impl.cfg.standalone.StandaloneMybatisTransactionContext commit
FEIN: firing event committed…
21.06.2012 00:47:03 org.activiti.engine.impl.interceptor.LogInterceptor execute
FEIN: — TaskQueryImpl finished ——————————————————–
21.06.2012 00:47:03 org.activiti.engine.impl.interceptor.LogInterceptor execute
FEIN:                                                                                                    
21.06.2012 00:47:03 javax.faces.FactoryFinder$FactoryManager getFactory
SCHWERWIEGEND: Die Anwendung wurde bei Systemstart nicht einwandfrei initialisiert, Factory konnte nicht gefunden werden: javax.faces.component.visit.VisitContextFactory. Rügriff versucht.
21.06.2012 00:47:03 com.sun.faces.application.view.FaceletViewHandlingStrategy handleRenderException
SCHWERWIEGEND: Error Rendering View[/couponForm.xhtml]
java.lang.IllegalStateException: Kein Rügriff für javax.faces.component.visit.VisitContextFactory gefunden.
   at javax.faces.FactoryFinder$FactoryManager.getFactory(FactoryFinder.java:1011)
   at javax.faces.FactoryFinder.getFactory(FactoryFinder.java:343)
   at javax.faces.component.visit.VisitContext.createVisitContext(VisitContext.java:221)
   at com.sun.faces.application.view.FaceletPartialStateManagementStrategy.saveView(FaceletPartialStateManagementStrategy.java:436)
   at com.sun.faces.application.StateManagerImpl.saveView(StateManagerImpl.java:89)
   at com.sun.faces.application.view.WriteBehindStateWriter.flushToWriter(WriteBehindStateWriter.java:225)
   at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:436)
   at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:125)
   at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
   at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
   at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
   at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
   at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
   at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
   at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
   at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
   at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
   at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
   at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
   at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
   at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
   at java.lang.Thread.run(Thread.java:662)
which translates to: java.lang.IllegalStateException: Application was not properly initialized at startup, could not find Factory: javax.faces.component.visit.VisitContextFactory. Falling back

java.lang.IllegalStateException: No fallback for javax.faces.component.visit.VisitContextFactory found

Now: If we omit fc.renderResponse(); it continues with the update model and invoke application lifecycle levels and continues without any errors (ok, render response phase is never executed as the invocation phase executes the submit method where the page is redirected to the next page (as of a loopback we go back to the same form but we do have a new task id and a new view and no error message indicating the wrong input)). If we however leave out the submitTaskFormData()-Method and the Class which holds the data set by the ExecutionListener, the validation phase executes as expected and prints out the error-message we defined.

So there seems to be an issue with xml-based web service invocation and executing JSF at validation phase.

Anyone has experience something similar or may give advise on how to solve this issue?

Kind regards,
Roman

Outcomes