7 Replies Latest reply on Jun 21, 2005 11:34 PM by bbbear

    Stateful session bean activation

    bbbear Newbie

      Hi,

      I'm using JBoss 4.0 sp1 version. To my understanding, EJB references will be maintained while the stateful session bean is passivated, how about Serializable POJO references?

      Correct me if i'm wrong, I think it's not. Cause I get NullPointerException when the client call the method that used the variable.

      So, I re-instantiate the Serializable POJO, which is a class variable in the stateful session bean, in the ejbActivate() method. My bean successfully passivated and reactivated (I have a Passivation complete; and Activation complete; from the log file), however, I get the NullPointerException still.

      I try to log messages from the ejbActivate() method. It didn't show anything from the log nor at the console. It does show the messages from ejbPassivate() method though.

      Can someone point out what have I missed? Why is the ejbActivate() method doesn't seems to work?

      Any idea?

      Regards,
      bb

        • 1. Re: Stateful session bean activation
          bbbear Newbie

          I have read the EJB 2.1 spec, at 7.4.1 Instance Passivation and Conversational State, it states,

          "The Bean Provider is required to ensure that the ejbPassivate method leaves the instance fields ready to be serialized by the container. The objects must be one of the following: [A serializable object]"

          If my stateful session bean serialized all the Serializable POJOs during passivation, will the value in those POJOs be retained during activation? I've been testing all day and I have not been able to get back those values after activation.

          Please, I've been trying to search for a solution of how to keep the conversational state of the Serializable POJO in the stateful bean and somehow I'm stuck.

          What I do to get around now is I've changed the cache policy in the standardjboss.xml to NoPassivationCachePolicy. I hope there's someone could advise me of how to get around with this instead of changing the cache policy.

          Thank you.

          Regards,
          bb

          • 2. Re: Stateful session bean activation
            Darran Lofthouse Master

            Can you post the code from your session bean? Are you sure you have not made the fields transient?

            • 3. Re: Stateful session bean activation
              Scott Stark Master

              Create a bug report with a testcase that demonstrates the problem otherwise. A bug report without a testcase will be ignored.

              http://jira.jboss.com/jira/browse/JBAS

              • 4. Re: Stateful session bean activation
                bbbear Newbie

                Hi darranl,

                I'm sure I did not made the fields transient. Only the Log4J Logger object which is not Serializable that I made it transient. The rest is just normal instance variable declarations.

                I found something strange during activation process. JBoss throws exception saying my POJO class doesn't have valid constructor. I've tried to
                tweak my POJO class to include varies constructors, however, it still shows
                me "no valid constructor". Any idea?

                --------------------------------------------------------------------------------
                2005-06-21 15:35:22,815 DEBUG
                [org.jboss.ejb.plugins.StatefulSessionFilePersistenceManager] Attempting to
                activate; ctx=org.jboss.ejb.StatefulSessionEnterpriseContext@e823ac
                2005-06-21 15:35:22,815 DEBUG
                [org.jboss.ejb.plugins.StatefulSessionFilePersistenceManager] Reading session
                state
                from: /opt/jboss-4.0/server/default/tmp/sessions/TestStatefulSession-ea7suahx-9/ea7tj4hy-n.ser
                2005-06-21 15:35:22,842 DEBUG [org.jboss.ejb.plugins.AbstractInstanceCache]
                Activation failure
                javax.ejb.EJBException: Could not activate; failed to restore state;
                CausedByException is:
                        com.session.test.StatefulSessPojo; no valid constructor
                --------------------------------------------------------------------------------

                StatefulSessPojo is a POJO that extends StatefulSessAbs [an abstract class
                which implements StatefulSessInf (an interface)]

                The stateful session bean has 2 instance variables, a String and a HashMap.
                The HashMap stores StatefulSessPojo as the value. In the bean, it has a
                remote method to print the HashMap values and a remote method to print a
                String. Before passivation, the values are printed OK. It also passivated
                successfully. However, during activation, it throws javax.ejb.EJBException
                saying "StatefulSessPojo; no valid constructor". Even when I invoke the print String method first before the print HashMap method.

                That's my testing so far, and I'm stuck again. :)

                Below is the Stateful session bean class:

                public class SimpleStatefulSession implements SessionBean {

                /** The SessionContext */
                private SessionContext context;
                private transient Logger log = Logger.getLogger(getClass().getName());
                public EBTestLocalHome entityLocalHome;
                public Map groupMap = new HashMap();
                public String mapName = "";
                public boolean initialized = false;

                /**
                * @throws CreateException Thrown if the instance could not perform
                * the function requested by the container because of an system-level error.
                *
                * @ejb.create-method
                */
                public void ejbCreate() throws CreateException {
                Calendar now = Calendar.getInstance();
                log.info(now.getTime() + " [Creating] SimpleStatefulSession EJB");
                this.mapName = "Default";
                log.info("[Param] map name=" + mapName);
                init();
                }

                /**
                * @throws EJBException Thrown if the instance could not perform
                * the function requested by the container because of an system-level error.
                */
                public void ejbActivate() throws EJBException {
                log = Logger.getLogger(getClass().getName());
                Calendar now = Calendar.getInstance();
                log.info(now.getTime() + " [Activating] SimpleStatefulSession EJB");
                log.info(now.getTime() + " [Activating] Setting initialized to false");
                initialized = false;
                log.info(now.getTime() + " [Activating] Calling init()");
                init();
                }

                /**
                * @throws EJBException Thrown if the instance could not perform
                * the function requested by the container because of an system-level error.
                */
                public void ejbPassivate() throws EJBException {
                Calendar now = Calendar.getInstance();
                log.info(now.getTime() + " [Passivating] SimpleStatefulSession EJB");
                }

                /**
                * @throws EJBException Thrown if the instance could not perform
                * the function requested by the container because of an system-level error.
                */
                public void ejbRemove() throws EJBException {
                Calendar now = Calendar.getInstance();
                log.info(now.getTime() + " [Removing] SimpleStatefulSession EJB");
                }

                /**
                * @throws EJBException Thrown if the instance could not perform
                * the function requested by the container because of an system-level error.
                */
                public void setSessionContext(SessionContext newContext) throws EJBException {
                context = newContext;
                }

                /**
                * initialize method for the HashMap
                */
                public void init() throws EJBException {
                log.info("[Enter] public void init()");
                log.debug("[Param] initialized once? " + initialized);

                if (! initialized) {
                for (int i = 0; i < 4; i++) {
                log.debug("[Param] StatefulSessPojo x=" + i);
                StatefulSessPojo x = new StatefulSessPojo(i,i,i);
                log.debug("[Param] Adding to groupMap...");
                groupMap.put(new Integer(i), x);
                }
                initialized = true;
                }
                log.info("[Exit] public void init()");
                }

                /**
                * @ejb.interface-method view-type = "remote"
                */
                public void printGroupMap() throws EJBException {
                log.info("[Enter] public void printGroupMap()");
                try {
                for (Iterator iter= groupMap.entrySet().iterator(); iter.hasNext();) {
                Map.Entry entry = (Map.Entry) iter.next();
                StatefulSessPojo x = (StatefulSessPojo) entry.getValue();
                log.debug( "[Param] siteId=" + x.getSiteId() + ", modId=" + x.getModId() + ", itemId=" + x.getItemId());
                }
                log.info("[Exit] public void printGroupMap()");

                } catch (Exception e) {
                e.printStackTrace();
                }
                }

                /**
                * @ejb.interface-method view-type = "remote"
                */
                public String printNewMapName(String name) throws EJBException {
                log.info("[Enter] public String printNewMapName(String name)");
                log.debug( "[Param] name=" + name);
                mapName = name;
                log.info("[Exit] public String printNewMapName(String name)");
                return mapName;
                }

                /**
                * @ejb.interface-method view-type = "remote"
                */
                public void printMapName() throws EJBException {
                log.info("[Enter] public void printMapName()");
                log.debug( "[Param] mapName=" + mapName);
                log.info("[Exit] public void printMapName()");
                }
                }

                p/s: How to attach files to the forum?

                Regards,
                bb

                • 5. Re: Stateful session bean activation
                  bbbear Newbie

                  I posted the POJO class for your reference as well, just in case.

                  public class StatefulSessPojo extends StatefulSessAbs implements Serializable {
                  public transient Logger log = Logger.getLogger(getClass().getName());
                  public int siteId;

                  public StatefulSessPojo() {
                  super(-1, -1);
                  this.siteId = -1;
                  }

                  public StatefulSessPojo(int modId, long itemId) {
                  super(modId, itemId);
                  this.siteId = -1;
                  }

                  public StatefulSessPojo(int modId, long itemId, int siteId) {
                  super(modId, itemId);
                  this.siteId = siteId;
                  }

                  public int getSiteId() {
                  return siteId;
                  }

                  /**StatefulSessAbs method*/
                  public void printMap() {
                  log.info("[Enter] public void printMap()");
                  log.info("[Exit] public void printMap()");
                  }
                  }

                  • 6. Re: Stateful session bean activation
                    Darran Lofthouse Master

                    The class that requires the default constructor is the 'StatefulSessAbs' class. The constructor only needs to be visible to the 'StatefulSessPojo' class.

                    However as 'StatefulSessAbs' is not declared as being Serializable the data referenced by that class will not be serialized and restored. The only data that will be serialized is the data referenced by the 'StatefulSessPojo' class.

                    • 7. Re: Stateful session bean activation
                      bbbear Newbie

                      Thank you, darranl, for pointing that out. It does solved the "no valid constructor" problem.

                      Thanks again for the help.

                      Regards,
                      bb