glassfish
  1. glassfish
  2. GLASSFISH-20309

Cannot passivate SFSB which injects a JMSContext

    Details

    • Type: Improvement Improvement
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 4.0
    • Fix Version/s: 4.1
    • Component/s: jms
    • Labels:
      None

      Description

      Think about how to add passivation support for injectable JMSContext.

      We can also suppress the WELD warning which was introduced with latest WELD integration update.

      [2013-04-13T15:26:48.628+0800] [glassfish 4.0] [WARNING] [] [org.jboss.weld.Bootstrap] [tid: _ThreadID=33 _ThreadName=admin-listener(1)] 
      [timeMillis: 1365838008628] [levelValue: 900] 
      [[ WELD-001473 javax.enterprise.inject.spi.Bean implementation org.glassfish.jms.injection.JMSCDIExtension$LocalBean@148bb71 
      declared a normal scope but does not implement javax.enterprise.inject.spi.PassivationCapable. 
      It won't be possible to inject this bean into a bean with passivating scope (@SessionScoped, @ConversationScoped). 
      This can be fixed by assigning the Bean implementation a unique id by implementing the PassivationCapable interface.]]
      

        Activity

        Hide
        Nigel Deakin added a comment - - edited

        I created a test that used a stateful session bean which used an injected JMSContext with request scope and set a short <cache-idle-timeout-in-seconds> to force passivation.

        This failed with

        WARNING:   Error during passivation: [StatefulSessionBeanBMT; id: 190c00500a81f-1327b0bf-1f];
        [java.io.NotSerializableException: org.jboss.weld.context.ejb.EjbRequestContextImpl]
        

        followed by

        SEVERE:   [beans.StatefulSessionBeanBMT]: Cannot load from  BACKUPSTORE FOR Key: <[190c00500a81f-1327b0bf-1f]>
        WARNING:   EJB5184:A system exception occurred during an invocation on EJB StatefulSessionBeanBMT, method: 
        public void beans.StatefulSessionBeanBMT.sendMessageInUT(java.lang.String,java.lang.String,java.lang.String) throws java.lang.Exception
        WARNING:   javax.ejb.NoSuchObjectLocalException: The EJB does not exist. session-key: 190c00500a81f-1327b0bf-1f
        	at com.sun.ejb.containers.StatefulSessionContainer._getContext(StatefulSessionContainer.java:1625)
        	at com.sun.ejb.containers.BaseContainer.getContext(BaseContainer.java:2516)
        	at com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:1906)
        	at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:210)
        	at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88)
        	at com.sun.proxy.$Proxy268.sendMessageInUT(Unknown Source)
        	at beans.__EJB31_Generated__StatefulSessionBeanBMT__Intf____Bean__.sendMessageInUT(Unknown Source)
        	at beans.MyMDB.onMessage(MyMDB.java:72)
        
        Show
        Nigel Deakin added a comment - - edited I created a test that used a stateful session bean which used an injected JMSContext with request scope and set a short <cache-idle-timeout-in-seconds> to force passivation. This failed with WARNING: Error during passivation: [StatefulSessionBeanBMT; id: 190c00500a81f-1327b0bf-1f]; [java.io.NotSerializableException: org.jboss.weld.context.ejb.EjbRequestContextImpl] followed by SEVERE: [beans.StatefulSessionBeanBMT]: Cannot load from BACKUPSTORE FOR Key: <[190c00500a81f-1327b0bf-1f]> WARNING: EJB5184:A system exception occurred during an invocation on EJB StatefulSessionBeanBMT, method: public void beans.StatefulSessionBeanBMT.sendMessageInUT(java.lang.String,java.lang.String,java.lang.String) throws java.lang.Exception WARNING: javax.ejb.NoSuchObjectLocalException: The EJB does not exist. session-key: 190c00500a81f-1327b0bf-1f at com.sun.ejb.containers.StatefulSessionContainer._getContext(StatefulSessionContainer.java:1625) at com.sun.ejb.containers.BaseContainer.getContext(BaseContainer.java:2516) at com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:1906) at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:210) at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88) at com.sun.proxy.$Proxy268.sendMessageInUT(Unknown Source) at beans.__EJB31_Generated__StatefulSessionBeanBMT__Intf____Bean__.sendMessageInUT(Unknown Source) at beans.MyMDB.onMessage(MyMDB.java:72)
        Hide
        agksmehx added a comment -

        the warning had me wondering if something was wrong with my code

        Show
        agksmehx added a comment - the warning had me wondering if something was wrong with my code
        Hide
        Nigel Deakin added a comment - - edited

        I re-ran my test to see if this had been fixed in the released version of GlassFish 4.0, and I can confirm that I no longer see this error.

        I tested with GlassFish Version: GlassFish Server Open Source Edition 4.0 (build 89)

        My test case used a stateful session bean which had a business method which uses an injected JMSContext to send a message without a transaction. This means the injected JMSContext had request scope. I set <cache-idle-timeout-in-seconds> to 2 seconds.

        I then called the same stateful session bean several times within the same request, with a pause of 20 seconds between each call (i.e. longer than the specified <cache-idle-timeout-in-seconds>) to encourage passivation to take place in between calls.

        I used log statements to confirm that the bean was indeed passivated in between two such calls, and that after the bean was activated the injected JMSContext was proxied to the same underlying JMSContextImpl.

        JMSContextImpl is not Serializable and this test confirms that it does not need to be. Even though a stateful session bean may be passivated in the middle of a request, this does not causes any problems if the bean uses an injected, request-scoped JMSContext. This is because although the field in question is serialized, this is just a proxy generated by Weld. The underlying JMSContextImpl is not serialized but continues to be managed by Weld. After the bean is activated, this proxy is deserialized just fine, and when it is next used Weld makes sure that it is fixed-up to point to the correct JMSContextImpl instance for the current request.

        I think that this issue can be marked as resolved.

        Show
        Nigel Deakin added a comment - - edited I re-ran my test to see if this had been fixed in the released version of GlassFish 4.0, and I can confirm that I no longer see this error. I tested with GlassFish Version: GlassFish Server Open Source Edition 4.0 (build 89) My test case used a stateful session bean which had a business method which uses an injected JMSContext to send a message without a transaction. This means the injected JMSContext had request scope. I set <cache-idle-timeout-in-seconds> to 2 seconds. I then called the same stateful session bean several times within the same request, with a pause of 20 seconds between each call (i.e. longer than the specified <cache-idle-timeout-in-seconds> ) to encourage passivation to take place in between calls. I used log statements to confirm that the bean was indeed passivated in between two such calls, and that after the bean was activated the injected JMSContext was proxied to the same underlying JMSContextImpl . JMSContextImpl is not Serializable and this test confirms that it does not need to be. Even though a stateful session bean may be passivated in the middle of a request, this does not causes any problems if the bean uses an injected, request-scoped JMSContext . This is because although the field in question is serialized, this is just a proxy generated by Weld. The underlying JMSContextImpl is not serialized but continues to be managed by Weld. After the bean is activated, this proxy is deserialized just fine, and when it is next used Weld makes sure that it is fixed-up to point to the correct JMSContextImpl instance for the current request. I think that this issue can be marked as resolved.
        Hide
        marina vatkina added a comment -

        The 1st failure had been fixed with GLASSFISH-20325; the 2nd with GLASSFISH-20318.

        Show
        marina vatkina added a comment - The 1st failure had been fixed with GLASSFISH-20325 ; the 2nd with GLASSFISH-20318 .
        Hide
        David Zhao added a comment - - edited

        TransactedJMSContextManager doesn't need to be PassivationCapable, but LocalBean needs. So change TransactedJMSContextManager not implement PassivationCapable.

        Show
        David Zhao added a comment - - edited TransactedJMSContextManager doesn't need to be PassivationCapable, but LocalBean needs. So change TransactedJMSContextManager not implement PassivationCapable.

          People

          • Assignee:
            David Zhao
            Reporter:
            David Zhao
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: