Skip to main content

Debugging passivation errors in JBoss AS

Posted in

The problem

Did you ever have issues passivating/serializing beans? Was the error/stacktrace very unclear? Do you want to know what exactly goes wrong in the passivation process? Passivation errors can be a real pain in the ass, ... but they can also be simply clarified.

An example

We were constantly getting the following stacktrace when one of our stateful session beans was passivated. The session bean was passivated after idling the application for 5 minutes. So you login into the application, you setup and use the bean. And then, you leave the bean for more then 5 minutes idle.

Example stacktrace:

        ....
        at org.jboss.serial.io.JBossObjectOutputStream.writeObjectOverride(JBossObjectOutputStream.java:181)
        at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
        at org.jboss.serial.io.MarshalledObject.<init>(MarshalledObject.java:51)
        at org.jboss.ejb3.stateful.StatefulBeanContext.writeExternal(StatefulBeanContext.java:1048)
        at org.jboss.serial.persister.ExternalizePersister.writeData(ExternalizePersister.java:58)
        at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.describeObject(ObjectDescriptorFactory.java:276)
        at org.jboss.serial.objectmetamodel.DataContainer$DataContainerDirectOutput.writeObject(DataContainer.java:206)
        at org.jboss.serial.io.JBossObjectOutputStream.writeObjectOverride(JBossObjectOutputStream.java:181)
        at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
        at org.jboss.ejb3.cache.simple.StatefulSessionFilePersistenceManager.passivateSession(StatefulSessionFilePersistenceManager.java:393)
        at org.jboss.ejb3.cache.simple.SimpleStatefulCache.passivate(SimpleStatefulCache.java:397)
        at org.jboss.ejb3.cache.simple.SimpleStatefulCache$SessionTimeoutTask.run(SimpleStatefulCache.java:301)
Caused by: java.lang.NoClassDefFoundError: org/jboss/wsf/spi/serviceref/ServiceRefMetaData
        at java.lang.Class.getDeclaredMethods0(Native Method)
        at java.lang.Class.privateGetDeclaredMethods(Class.java:2427)
        at java.lang.Class.getDeclaredMethod(Class.java:1935)
        at org.jboss.serial.classmetamodel.ClassMetaData.lookupMethodOnHierarchy(ClassMetaData.java:102)
        at org.jboss.serial.classmetamodel.ClassMetaData.lookupInternalMethods(ClassMetaData.java:432)
        at org.jboss.serial.classmetamodel.ClassMetaData.<init>(ClassMetaData.java:122)
        at org.jboss.serial.classmetamodel.ClassMetamodelFactory.getClassMetaData(ClassMetamodelFactory.java:350)
        at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.describeObject(ObjectDescriptorFactory.java:168)
        at org.jboss.serial.objectmetamodel.DataContainer$DataContainerDirectOutput.writeObject(DataContainer.java:206)
        at org.jboss.serial.persister.ArrayPersister.saveObjectArray(ArrayPersister.java:110)
        at org.jboss.serial.persister.ArrayPersister.writeData(ArrayPersister.java:101)
        at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.describeObject(ObjectDescriptorFactory.java:276)
        at org.jboss.serial.objectmetamodel.DataContainer$DataContainerDirectOutput.writeObject(DataContainer.java:206)
        at org.jboss.serial.persister.RegularObjectPersister.writeSlotWithFields(RegularObjectPersister.java:182)
        at org.jboss.serial.persister.ObjectOutputStreamProxy.writeFields(ObjectOutputStreamProxy.java:79)
        at org.jboss.serial.persister.ObjectOutputStreamProxy.defaultWriteObject(ObjectOutputStreamProxy.java:68)
        at java.util.Vector.writeObject(Vector.java:1012)
        ... 261 more
        at java.util.Vector.writeObject(Vector.java:1012)
        ... 261 more
Caused by: java.lang.ClassNotFoundException: org.jboss.wsf.spi.serviceref.ServiceRefMetaData from BaseClassLoader@36eb1ba3{vfs:///Applications/jboss-6.1.0.Final/server/default/conf/jboss-service.xml}
        at org.jboss.classloader.spi.base.BaseClassLoader.loadClass(BaseClassLoader.java:480)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
        ... 278 more 

You could think you're missing a library. In this case, ServiceRefMetaData is part of the jbossws-spi.jar. I really spent a lot of time figuring out why this class is missing. But my conclusion is: JBoss is putting you into the wrong direction. You are spending time solving an exception, which is actually be thrown by a lot of other exceptions.

The solution

First of all, decrease the idleTimeoutSeconds of statefull session beans. This will speed up the passivation process, as also the generation of stacktraces:

  • go to $JBOSS_HOME/server/default/deploy/ejb3-interceptors-aop.xml
  • search for:
       <domain name="Stateful Bean" extends="Base Stateful Bean" inheritBindings="true">
          <!-- NON Clustered cache configuration -->
          <annotation expr="class(*) AND !class(@org.jboss.ejb3.annotation.Cache) AND !class(@org.jboss.ejb3.annotation.Clustered)">
             @org.jboss.ejb3.annotation.Cache ("SimpleStatefulCache")
          </annotation>
          <annotation expr="class(*) AND !class(@org.jboss.ejb3.annotation.PersistenceManager) AND !class(@org.jboss.ejb3.annotation.Clustered)">
             @org.jboss.ejb3.annotation.PersistenceManager ("StatefulSessionFilePersistenceManager")
          </annotation>
          <annotation expr="class(*) AND !class(@org.jboss.ejb3.annotation.CacheConfig) AND !class(@org.jboss.ejb3.annotation.Clustered)">
             @org.jboss.ejb3.annotation.CacheConfig (maxSize=100000, idleTimeoutSeconds=300, removalTimeoutSeconds=0)
          </annotation>
          ...
  • change idleTimeoutSeconds from 300 to 30

Next, you need the source code of the JBoss Serialization project. You can get all source code here: http://anonsvn.jboss.org/repos/jbossserialization/tags/. If you don't know the version of JBoss Serialization, look into the MANIFEST.MF file of jboss-serialization.jar. JBoss 6.1.0.Final is using JBSER_1_0_3_GA for example.
Once you checked out the source code, add the project to Eclipse (there's a .project file, so importing is easy). Put a breakpoint in the class: org.jboss.serial.persister.RegularObjectPersister on line 127.

Finally, attach your debugger to your JBoss installation. When the stacktrace is generated, the debugger of Eclipse will be activated. Attach the source code by choosing: workspace > jboss-serialization.

Now simply follow the stacktrace to figure out on which property passivation is failing:

Post new comment

The content of this field is kept private and will not be shown publicly.