7 Replies Latest reply on Nov 26, 2006 3:05 PM by gavin.king

    Seam exception handling failing

    zzzz8

      I've had a short history and issue in getting Seam exception handling working for me. It's important because I truly want to get this working since I would really want to handle exceptions the Seam way. I previously had issues that I thought might be due to Tiles eating the exceptions, so I switched to Facelets. Unfortunately, I'm seeing similar problems right now - i.e. the user is not redirected to the specified exception handling page.

      My current configuration is JBoss AS 4.0.5, Seam 1.1 CR1, and Facelets 1.1.11.

      Here is the stack trace I receive (the normal Tomcat stack trace) in the logs:

      2006-11-25 14:15:11,406 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[/myapp].[Faces Servlet]] Servlet.service() for servlet Faces Servlet threw exception
      java.lang.IllegalArgumentException: exception invoking: retrieveStatus
       at org.jboss.seam.util.Reflections.invokeAndWrap(Reflections.java:112)
       at org.jboss.seam.Component.callComponentMethod(Component.java:1759)
       at org.jboss.seam.Component.getInstanceFromFactory(Component.java:1647)
       at org.jboss.seam.Component.getInstance(Component.java:1590)
       at org.jboss.seam.Component.getInstance(Component.java:1567)
       at org.jboss.seam.jsf.SeamVariableResolver.resolveVariable(SeamVariableResolver.java:45)
       at org.apache.myfaces.config.LastVariableResolverInChain.resolveVariable(LastVariableResolverInChain.java:42)
       at com.sun.facelets.el.LegacyELContext$LegacyELResolver.getValue(LegacyELContext.java:134)
       at com.sun.el.parser.AstIdentifier.getValue(AstIdentifier.java:65)
       at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:192)
       at com.sun.facelets.el.TagValueExpression.getValue(TagValueExpression.java:71)
       at com.sun.facelets.el.LegacyValueBinding.getValue(LegacyValueBinding.java:56)
       at javax.faces.component.UIData.getValue(UIData.java:1019)
       at javax.faces.component.UIData.createDataModel(UIData.java:785)
       at javax.faces.component.UIData.getDataModel(UIData.java:765)
       at javax.faces.component.UIData.getRowCount(UIData.java:191)
       at org.apache.myfaces.shared_impl.renderkit.html.HtmlTableRendererBase.encodeInnerHtml(HtmlTableRendererBase.java:210)
       at org.apache.myfaces.shared_impl.renderkit.html.HtmlTableRendererBase.encodeChildren(HtmlTableRendererBase.java:123)
       at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:524)
       at com.sun.facelets.tag.jsf.ComponentSupport.encodeRecursive(ComponentSupport.java:234)
       at com.sun.facelets.tag.jsf.ComponentSupport.encodeRecursive(ComponentSupport.java:239)
       at com.sun.facelets.tag.jsf.ComponentSupport.encodeRecursive(ComponentSupport.java:239)
       at com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:554)
       at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:384)
       at javax.faces.webapp.FacesServlet.service(FacesServlet.java:138)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
       at org.jboss.seam.servlet.SeamRedirectFilter.doFilter(SeamRedirectFilter.java:32)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
       at org.jboss.seam.servlet.SeamExceptionFilter.doFilter(SeamExceptionFilter.java:46)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
       at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
       at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
       at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
       at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:175)
       at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74)
       at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
       at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
       at org.jboss.web.tomcat.tc5.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:156)
       at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
       at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
       at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
       at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
       at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
       at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
       at java.lang.Thread.run(Thread.java:595)
      Caused by: com.mycompany.connection.ConnectionException
       at com.mycompany.beans.status.StatusBean.retrieveStatus(StatusBean.java:78)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:112)
       at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
       at org.jboss.seam.intercept.EJBInvocationContext.proceed(EJBInvocationContext.java:37)
       at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:55)
       at org.jboss.seam.interceptors.BijectionInterceptor.bijectTargetComponent(BijectionInterceptor.java:51)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at org.jboss.seam.util.Reflections.invoke(Reflections.java:18)
       at org.jboss.seam.intercept.Interceptor.aroundInvoke(Interceptor.java:169)
       at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:64)
       at org.jboss.seam.interceptors.OutcomeInterceptor.interceptOutcome(OutcomeInterceptor.java:23)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at org.jboss.seam.util.Reflections.invoke(Reflections.java:18)
       at org.jboss.seam.intercept.Interceptor.aroundInvoke(Interceptor.java:169)
       at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:64)
       at org.jboss.seam.interceptors.ConversationInterceptor.endOrBeginLongRunningConversation(ConversationInterceptor.java:51)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at org.jboss.seam.util.Reflections.invoke(Reflections.java:18)
       at org.jboss.seam.intercept.Interceptor.aroundInvoke(Interceptor.java:169)
       at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:64)
       at org.jboss.seam.intercept.RootInterceptor.createSeamInvocationContext(RootInterceptor.java:144)
       at org.jboss.seam.intercept.RootInterceptor.invokeInContexts(RootInterceptor.java:129)
       at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:102)
       at org.jboss.seam.intercept.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:49)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:118)
       at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:126)
       at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:201)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77)
       at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:131)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:47)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.stateless.StatelessContainer.localInvoke(StatelessContainer.java:211)
       at org.jboss.ejb3.stateless.StatelessLocalProxy.invoke(StatelessLocalProxy.java:79)
       at $Proxy522.retrieveStatus(Unknown Source)
       at com.mycompany.beans.status.StatusLocal$$FastClassByCGLIB$$72d42c54.invoke(<generated>)
       at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
       at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:45)
       at org.jboss.seam.intercept.ClientSideInterceptor$1.proceed(ClientSideInterceptor.java:69)
       at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:55)
       at org.jboss.seam.interceptors.ExceptionInterceptor.handleExceptions(ExceptionInterceptor.java:28)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at org.jboss.seam.util.Reflections.invoke(Reflections.java:18)
       at org.jboss.seam.intercept.Interceptor.aroundInvoke(Interceptor.java:169)
       at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:64)
       at org.jboss.seam.intercept.RootInterceptor.createSeamInvocationContext(RootInterceptor.java:144)
       at org.jboss.seam.intercept.RootInterceptor.invokeInContexts(RootInterceptor.java:129)
       at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:102)
       at org.jboss.seam.intercept.ClientSideInterceptor.interceptInvocation(ClientSideInterceptor.java:78)
       at org.jboss.seam.intercept.ClientSideInterceptor.intercept(ClientSideInterceptor.java:47)
       at com.mycompany.beans.status.StatusLocal$$EnhancerByCGLIB$$3d25fd73.retrieveStatus(<generated>)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at org.jboss.seam.util.Reflections.invoke(Reflections.java:18)
       at org.jboss.seam.util.Reflections.invokeAndWrap(Reflections.java:102)
       ... 49 more


      Here's a snippet from my faces-config.xml:

      <application>
       <view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
      </application>
      
      <lifecycle>
       <phase-listener>
       org.jboss.seam.jsf.TransactionalSeamPhaseListener
       </phase-listener>
      </lifecycle>


      Here's a snippet from my web.xml:

      <context-param>
       <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
       <param-value>.xhtml</param-value>
      </context-param>
      
      <context-param>
       <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
       <param-value>client</param-value>
      </context-param>
      
      <context-param>
       <param-name>facelets.DEVELOPMENT</param-name>
       <param-value>false</param-value>
      </context-param>
      
      <context-param>
       <param-name>facelets.LIBRARIES</param-name>
       <param-value>/WEB-INF/tomahawk.taglib.xml</param-value>
      </context-param>
      
      <filter>
       <filter-name>Seam Exception Filter</filter-name>
       <filter-class>
       org.jboss.seam.servlet.SeamExceptionFilter
       </filter-class>
      </filter>
      
      <filter>
       <filter-name>Seam Redirect Filter</filter-name>
       <filter-class>
       org.jboss.seam.servlet.SeamRedirectFilter
       </filter-class>
      </filter>
      
      <filter-mapping>
       <filter-name>Seam Exception Filter</filter-name>
       <url-pattern>/*</url-pattern>
      </filter-mapping>
      
      <filter-mapping>
       <filter-name>Seam Redirect Filter</filter-name>
       <url-pattern>*.faces</url-pattern>
      </filter-mapping>
      
      <listener>
       <listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
      </listener>
      
      <listener>
       <listener-class>
       org.apache.myfaces.webapp.StartupServletContextListener
       </listener-class>
      </listener>
      
      <servlet>
       <servlet-name>Faces Servlet</servlet-name>
       <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
       <load-on-startup>1</load-on-startup>
      </servlet>
      
      <servlet-mapping>
       <servlet-name>Faces Servlet</servlet-name>
       <url-pattern>*.faces</url-pattern>
      </servlet-mapping>


      Here's a snippet from my components.xml:

      <component name="org.jboss.seam.core.init">
       <property name="debug">false</property>
       <property name="jndiPattern">myapp/#{ejbName}/local</property>
       </component>


      Here's my exceptions.xml:

      <exceptions>
       <exception
       class="com.mycompany.connection.ConnectionException">
       <redirect view-id="/ois.xhtml">
       Failure
       </redirect>
       <end-conversation />
       </exception>
       <exception>
       <redirect view-id="/ois.xhtml">Unexpected failure</redirect>
       <end-conversation />
       </exception>
      </exceptions>


      In terms of my code, I just simplified it (for testing) so that if the retrieveStatus method is called, it just throws an exception:

      @Stateful
      @Name("statusData")
      public class StatusBean implements StatusLocal {
      @DataModel("status")
      private List status = null;

      @Create
      @Factory("status")
      public final void retrieveStatus() throws ConnectionException {
      throw new ConnectionException();
      }

      @Remove
      @Destroy
      public final void destroy() {

      }
      }

        • 1. Re: Seam exception handling failing
          gavin.king

          What happens if you remove the @Create annotation? Its pretty much just plain wrong to have @Create @Factory together.

          Seam's exception handling kicks in when you invoke a component method, not during the instantiation cycle.

          • 2. Re: Seam exception handling failing
            zzzz8

            Hi Gavin,

            Thanks for the tip and help. Unfortunately, I get the same stack trace when I remove the @Create annotation...

            What's interesting (or maybe it's not that interesting) is that if I set the Facelets development property to true:

            <context-param>
             <param-name>facelets.DEVELOPMENT</param-name>
             <param-value>true</param-value>
            </context-param>


            then I get the Facelets debug page.

            • 3. Re: Seam exception handling failing
              gavin.king

              Oh, according to the stack trace this exception occurs in the render phase!

              Of course Seam can most certainly not do anything at all about an exception that occurs while rendering the view!

              This is obvious, right? (Servlet engine may already have flushed some of the response to the browser.)

              • 4. Re: Seam exception handling failing
                gavin.king
                • 5. Re: Seam exception handling failing
                  gavin.king

                  And so the correct way to solve your problem is to use a page action instead of an @Factory method, since page actions take place *before* rendering the view.

                  • 6. Re: Seam exception handling failing
                    zzzz8

                    Hi Gavin,

                    Thanks for the info. I was under the belief that the factory method would be called in the invoke application phase... Are you saying that instantiations take place in the render phase instead? I probably need to understand the JSF lifecyle some more and JSF/Seam in general (I'm still a beginner). But I'll definitely look into page actions.

                    The overall goal of this status component was that the retrieveStatus method called a Web service (via JAX-RPC) to retrieve the status of something - whose value (status) could be later retrieved. If there was an error in retrieving the status, the exception would be thrown and I thought it would be caught by (and dealt with) the Seam exception filter. I never thought it would take place in the render phase (but then again, I probably don't understand the lifecycle).

                    • 7. Re: Seam exception handling failing
                      gavin.king

                      It happens when the variable is first referenced. In this case, during the render phase.

                      Note that if this is a GET request, or a redirect, there is no invoke application phase.

                      Use a page action.