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

    Seam Catch ViewExpiredException and redirect

    Andrew Wheeler Newbie

      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
          Jason Porter Master

          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
            Andrew Wheeler Newbie

            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
              Jason Porter Master

              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
                Brian Leathem Master

                I wonder if this is related to WELD-855

                • 5. Re: Seam Catch ViewExpiredException and redirect
                  Anthony Brock Newbie

                  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
                    Andrew Wheeler Newbie

                    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
                      Jason Porter Master

                      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.

                      • 9. Re: Seam Catch ViewExpiredException and redirect
                        Sueleyman Vurucu Expert

                        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 ?