9 Replies Latest reply on Jul 24, 2012 7:44 AM by suikast42

    Seam Catch ViewExpiredException and redirect

    andrewwheeler

      I want to redirect to page when a view has expired. I catch ViewExpiredException and the use the navigation handler to redirect. The problem is that weld tries to restore the current conversation during the redirect and fails. Is there a better way to redirect after exceptions are thrown?



           public void viewExpiredHandler(@Handles CaughtException<ViewExpiredException> event) {
                event.handled();
                messages.info("Your session has expired and you must login again.");
                redirect("login"); //=navigation.handleNavigation(facesContext, null, "login");
           }




      Caused by: java.lang.IllegalStateException: Unable to load current conversations from the associated request, something went badly wrong when associate() was called
           at org.jboss.weld.context.AbstractConversationContext.getCurrentConversation(AbstractConversationContext.java:410) [:20101031-0118]
           at org.jboss.weld.jsf.ConversationAwareViewHandler.getActionURL(ConversationAwareViewHandler.java:91) [:6.1.0-SNAPSHOT]
           at javax.faces.application.ViewHandlerWrapper.getActionURL(ViewHandlerWrapper.java:185) [:2.1.1-FCS]
           at com.sun.faces.application.view.MultiViewHandler.getRedirectURL(MultiViewHandler.java:381) [:2.1.1-FCS]
           at javax.faces.application.ViewHandlerWrapper.getRedirectURL(ViewHandlerWrapper.java:204) [:2.1.1-FCS]
           at javax.faces.application.ViewHandlerWrapper.getRedirectURL(ViewHandlerWrapper.java:204) [:2.1.1-FCS]
           at org.jboss.weld.jsf.ConversationAwareViewHandler.getRedirectURL(ConversationAwareViewHandler.java:134) [:6.1.0-SNAPSHOT]
           at javax.faces.application.ViewHandlerWrapper.getRedirectURL(ViewHandlerWrapper.java:204) [:2.1.1-FCS]
           at com.sun.faces.application.NavigationHandlerImpl.handleNavigation(NavigationHandlerImpl.java:166) [:2.1.1-FCS]
           at org.jboss.seam.faces.event.SeamPreNavigationHandler.handleNavigation(SeamPreNavigationHandler.java:48) [:3.0.0.Final]
           at org.jboss.weldx.faces.application.org$jboss$weld$beanProducerMethod-org$jboss$seam$faces$environment$NavigationHandlerProducermethod_getNavigationHandler()_$$_WeldClientProxy.handleNavigation(org$jboss$weld$beanProducerMethod-org$jboss$seam$faces$environment$NavigationHandlerProducermethod_getNavigationHandler()_$$_WeldClientProxy.java) [:]
           at volcanic.tephra.security.ExceptionHandler.redirect(ExceptionHandler.java:28) [:]
           at volcanic.tephra.security.ExceptionHandler.viewExpiredHandler(ExceptionHandler.java:52) [:]




      This issue is similar to this one.

        • 1. Re: Seam Catch ViewExpiredException and redirect
          lightguard

          For this I would look into the Seam Conversation project and call doDissociate, doDeactivate, or doInvalidate on SeamConversationContext instance. I know that module is a little rough around the edges, but it has great conversation control. Please give that a shot (please post if you run into problems using it) and let us know what you find.

          • 2. Re: Seam Catch ViewExpiredException and redirect
            andrewwheeler

            Thanks Jason for the reply. I had a brief look at Seam Conversation but I couldn't find any documentation on its purpose or how to use it. Do you have any documentation or example usage? I've read the code, but I'm afraid that doesn't paint the big picture for me.


            Cheers

            • 3. Re: Seam Catch ViewExpiredException and redirect
              lightguard

              I don't other than what's in my head :) Ales, the Weld Lead, wrote it. It allows control over the conversation. Sounds like we need to at least get a sample app running.

              • 4. Re: Seam Catch ViewExpiredException and redirect
                bleathem

                I wonder if this is related to WELD-855

                • 5. Re: Seam Catch ViewExpiredException and redirect
                  abrock17

                  Hi,


                  I am dealing with the exact same issue.  An example of illustrating how to use Seam Conversation would be extremely helpful.


                  Thanks in advance for anything you can offer.


                  - Tony

                  • 6. Re: Seam Catch ViewExpiredException and redirect
                    andrewwheeler

                    Brian, that JIRA looks like it describes it pretty well.


                    Jason, with regards to Seam Catch what is the recommended method to redirect to an error handling page? Should one use the faces navigation handler (in which case you can use outcomes) or the response from the external context (in which case you use page ids)?


                    A nice extension for Seam catch would be to annotate the error handler with an error view:



                         
                    @ErrorPage("error")
                    public void noConversationHandler(@Handles CaughtException<NonexistentConversationException> event) {
                       messages.info("The view you were editing has expired.");
                    }



                    This would redirect to the error page and appropriately handle the event if not explicitly handled.

                    • 7. Re: Seam Catch ViewExpiredException and redirect
                      lightguard

                      Andrew Wheeler wrote on May 28, 2011 15:57:


                      Brian, that JIRA looks like it describes it pretty well.

                      Jason, with regards to Seam Catch what is the recommended method to redirect to an error handling page? Should one use the faces navigation handler (in which case you can use outcomes) or the response from the external context (in which case you use page ids)?


                      I think Brian and I need to dig in figure out a good way of doing this. My gut feeling is if you are in any JSF phase but RenderResponse you'll be fine to use a navigation handler. If you have an exception that occurs during RenderResponse you're hosed. We'll have to see if this is really the case.



                      A nice extension for Seam catch would be to annotate the error handler with an error view:


                           
                      @ErrorPage("error")
                      public void noConversationHandler(@Handles CaughtException<NonexistentConversationException> event) {
                         messages.info("The view you were editing has expired.");
                      }



                      This would redirect to the error page and appropriately handle the event if not explicitly handled.


                      Feel free to add a JIRA to Faces, this wouldn't live in Seam Catch. Catch is a generic exception handling framework and doesn't deal with anything on the presentation side or other integrations. Seam Rest has something similar to this, feel free to look there for ideas on what could be done.

                      • 8. Re: Seam Catch ViewExpiredException and redirect
                        andrewwheeler

                        I've added a JIRA for this.

                        • 9. Re: Seam Catch ViewExpiredException and redirect
                          suikast42

                          Jason Porter schrieb:

                           

                          For this I would look into the Seam Conversation project and call doDissociate, doDeactivate, or doInvalidate on SeamConversationContext instance. I know that module is a little rough around the edges, but it has great conversation control. Please give that a shot (please post if you run into problems using it) and let us know what you find.

                          I'm in trouble wtih this module.

                           

                          I try ti start conversation like this:

                           

                          @Singleton

                          @Startup

                          public class ControllerRepo implements Serializable {

                           

                            @Inject

                            WeldBoundSeamConversationContext conversation;

                           

                            @PostConstruct

                            private void init(){

                              //    conversation.begin();

                              Map<String, Object> requestMap = new HashMap<>();

                              conversation.associate(new MutableBoundRequest(new HashMap<String,Object>(), requestMap));

                              conversation.activate("Test");

                           

                              // test Controller names

                              controllerNames.add("Controller1");

                              controllerNames.add("Controller2");

                              controllerNames.add("Controller3");

                             

                              for (String controllerName : controllerNames) {

                                AbstractController controller = ServiceLocatorFactory.getServiceLocator().getBeanByName(AbstractController.class,

                                    controllerName); //  DI is not enoough here

                                requestMap.put(controllerName, controller);

                              }

                             

                            }

                           

                            @PreDestroy

                            private void deinit(){

                              //    conversation.end();

                              conversation.deactivate();

                            }

                           

                          And I get this Exception:

                          Caused by: org.jboss.weld.context.NonexistentConversationException: WELD-000321 No conversation found to restore for id Test

                              at org.jboss.weld.context.AbstractConversationContext.activate(AbstractConversationContext.java:221)

                              at org.jboss.seam.conversation.plugins.weld.WeldBoundSeamConversationContext.doActivate(WeldBoundSeamConversationContext.java:48)

                              at org.jboss.seam.conversation.api.AbstractSeamConversationContext.activate(AbstractSeamConversationContext.java:54)

                              at com.siemag.seam.cron.beans.ControllerRepo.init(ControllerRepo.java:54)

                              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_03]

                              at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_03]

                              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_03]

                              at java.lang.reflect.Method.invoke(Method.java:601) [rt.jar:1.7.0_03]

                              at org.jboss.as.ee.component.ManagedReferenceLifecycleMethodInterceptorFactory$ManagedReferenceLifecycleMethodInterceptor.processInvocation(ManagedReferenceLifecycleMethodInterceptorFactory.java:130)

                              at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]

                              at org.jboss.invocation.WeavedInterceptor.processInvocation(WeavedInterceptor.java:53) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]

                              at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]

                              at org.jboss.as.weld.injection.WeldInjectionInterceptor.processInvocation(WeldInjectionInterceptor.java:73)

                              at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]

                              at org.jboss.as.ee.component.ManagedReferenceInterceptorFactory$ManagedReferenceInterceptor.processInvocation(ManagedReferenceInterceptorFactory.java:95)

                              at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]

                              at org.jboss.invocation.WeavedInterceptor.processInvocation(WeavedInterceptor.java:53) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]

                              at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]

                              at org.jboss.as.ee.component.NamespaceContextInterceptor.processInvocation(NamespaceContextInterceptor.java:50)

                              at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]

                              at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:228)

                           

                          Can you tell me what I'm doing wrong ?