4 Replies Latest reply on Oct 4, 2013 8:22 PM by jmsjr

    JBoss AS 7.1.3 - Serializing AsyncResult results in "java.io.NotSerializableException: org.jboss.as.ejb3.component.interceptors.AsyncFutureInterceptorFactory$1$1"

    jmsjr

      JBoss AS 7.1.3

       

      Using @Asychronous EJB method invocations where the method returns has Future<String> as the method's return signature ...and code returns new AsyncResult<String>("somevalue").

      The call to the asynchronous method is from a JSF @ViewScoped bean, so that the Future<String> is serialized in the JSF view state, and the JSF state saving method is set to client

      This, however, results in the exception below. Why was the anonymous class not Serializable ? Was there a reason to do so ? It simply prevents any Future<V> to be serialized. I need it to be serialized so that I can call the Future<String>.isDone() on a subsequent post back to the same view.

       

      If I change the JSF state saving method to server, or I use @Sessionscoped bean, the exception does not occur .. That is only because the view state is not YET being serialized .. well not until it is needed to be passivated. When it is passivated, then the exception occurs as well.

       

       

      11:45:16,756 SEVERE [javax.enterprise.resource.webcontainer.jsf.application] (http-localhost/127.0.0.1:8080-1) Error Rendering View[/progress.xhtml]: javax.faces.FacesException: java.io.NotSerializableException: org.jboss.as.ejb3.component.interceptors.AsyncFutureInterceptorFactory$1$1

        at com.sun.faces.renderkit.ResponseStateManagerImpl.getViewState(ResponseStateManagerImpl.java:137) [jsf-impl-2.1.11-jbossorg-3.jar:]

        at javax.faces.application.StateManager.getViewState(StateManager.java:555) [jboss-jsf-api_2.1_spec-2.0.4.Final.jar:2.0.4.Final]

        at com.sun.faces.context.PartialViewContextImpl.renderState(PartialViewContextImpl.java:416) [jsf-impl-2.1.11-jbossorg-3.jar:]

        at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:300) [jsf-impl-2.1.11-jbossorg-3.jar:]

        at org.richfaces.context.ExtendedPartialViewContextImpl.processPartial(ExtendedPartialViewContextImpl.java:199) [richfaces-core-impl-4.2.3.Final.jar:4.2.3.Final]

        at javax.faces.component.UIViewRoot.encodeChildren(UIViewRoot.java:981) [jboss-jsf-api_2.1_spec-2.0.4.Final.jar:2.0.4.Final]

        at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1779) [jboss-jsf-api_2.1_spec-2.0.4.Final.jar:2.0.4.Final]

        at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:409) [jsf-impl-2.1.11-jbossorg-3.jar:]

        at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:125) [jsf-impl-2.1.11-jbossorg-3.jar:]

        at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:288) [jboss-jsf-api_2.1_spec-2.0.4.Final.jar:2.0.4.Final]

        at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121) [jsf-impl-2.1.11-jbossorg-3.jar:]

        at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) [jsf-impl-2.1.11-jbossorg-3.jar:]

        at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139) [jsf-impl-2.1.11-jbossorg-3.jar:]

        at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594) [jboss-jsf-api_2.1_spec-2.0.4.Final.jar:2.0.4.Final]

        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.17.Final.jar:]

        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.17.Final.jar:]

        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.17.Final.jar:]

        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.17.Final.jar:]

        at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:165) [jboss-as-web-7.1.3.Final.jar:7.1.3.Final]

        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.17.Final.jar:]

        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.17.Final.jar:]

        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.17.Final.jar:]

        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:372) [jbossweb-7.0.17.Final.jar:]

        • 1. Re: JBoss AS 7.1.3 - Serializing AsyncResult results in "java.io.NotSerializableException: org.jboss.as.ejb3.component.interceptors.AsyncFutureInterceptorFactory$1$1"
          sfcoy

          Let's just think this through...

           

          1. Request processing finishes and the serialised Future<V> is sent to the browser;
          2. The server completes the asynchronous operation and updates the state of the in-memory copy of the Future<V>;
          3. Browser sends another request containing the serialised old state of the Future<V> and deserializes the reference into a new instance of it;
          4. You have now lost the state that was changed in (2)

           

          So the Future would not only need to be java.io.Serializable, but implement java.io.Externalizable as well.

           

          I can see in the current source that neither of these conditions is in place right now, probably because the spec does not specify that a serializable Future<V> be returned (even from a remote invocation).

           

          Stashing a Future<V> in the HttpSession (directly or indirectly) has other problems as well. What should happen if HttpSession replication is enabled between nodes? Some containers (notably WebSphere) will even passivate the HttpSession to disk, which will yield the same problems.

           

          Therefore, either use the "server" state saving method, or maintain your own application level map of Future<V> objects (which you will need anyway if you ever opt to use session replication).

          1 of 1 people found this helpful
          • 2. Re: JBoss AS 7.1.3 - Serializing AsyncResult results in "java.io.NotSerializableException: org.jboss.as.ejb3.component.interceptors.AsyncFutureInterceptorFactory$1$1"
            jmsjr

            Stephen Coy wrote:

             

            Let's just think this through...

             

            1. Request processing finishes and the serialised Future<V> is sent to the browser;
            2. The server completes the asynchronous operation and updates the state of the in-memory copy of the Future<V>;
            3. Browser sends another request containing the serialised old state of the Future<V> and deserializes the reference into a new instance of it;
            4. You have now lost the state that was changed in (2)

             

            So the Future would not only need to be java.io.Serializable, but implement java.io.Externalizable as well.

             

            I can see in the current source that neither of these conditions is in place right now, probably because the spec does not specify that a serializable Future<V> be returned (even from a remote invocation).

             

            Stashing a Future<V> in the HttpSession (directly or indirectly) has other problems as well. What should happen if HttpSession replication is enabled between nodes? Some containers (notably WebSphere) will even passivate the HttpSession to disk, which will yield the same problems.

             

            Therefore, either use the "server" state saving method, or maintain your own application level map of Future<V> objects (which you will need anyway if you ever opt to use session replication).

             

            Thanks. I'll have to rethink how one can use Future in a JSF webapp across multiple JSF lifecycles.

             

            From what you said, even maintaining my own application level map of Future<V> objects will still end up with the same NotSerializable exception when used with session replication.

            Same thing with JSF server state saving method ... The NotSerializable exception will occur when the view state is passivated anyway.


            Having the JSF view bean call a SFSB which in turn calls the SLSB @Asynchronous methods and stashing the Future in the SFSB will potentially have the same issue when the SFSB is replicated or passivated, unless I declare the Future transient so that it all works as long as the SFSB is not passivated ( e.g. I continually call a method on the SFSB that calls the Future<V>.isDone() every 2 to 5 seconds ) and there is no failover occurring.

             

            I'm trying to avoid using JMS to do this type of thing if possible, but it looks like it's not easy. Any replication / passivation which will include the Future<V> in the object graph will trigger this exception.

            • 3. Re: JBoss AS 7.1.3 - Serializing AsyncResult results in "java.io.NotSerializableException: org.jboss.as.ejb3.component.interceptors.AsyncFutureInterceptorFactory$1$1"
              sfcoy

              I was thinking application level as in javax.servlet.ServletContext#setAttribute(java.lang.String, java.lang.Object). I don't believe that this is ever involved in replication.

               

              You could maintain a java.util.Map<String, Future<?>> in this keyed on the session id. If your expected Future disappears from the map then maybe you have changed nodes.

               

              Careful coding would be necessary to ensure it doesn't leak.

              • 4. Re: JBoss AS 7.1.3 - Serializing AsyncResult results in "java.io.NotSerializableException: org.jboss.as.ejb3.component.interceptors.AsyncFutureInterceptorFactory$1$1"
                jmsjr

                Stephen Coy wrote:

                 

                I was thinking application level as in javax.servlet.ServletContext#setAttribute(java.lang.String, java.lang.Object). I don't believe that this is ever involved in replication.

                 

                You could maintain a java.util.Map<String, Future<?>> in this keyed on the session id. If your expected Future disappears from the map then maybe you have changed nodes.

                 

                Careful coding would be necessary to ensure it doesn't leak.

                 

                Ah, of course! Wonderful.

                 

                Hello from down-under ( looked at your profile ).... will see the Navy Review this weekend.