Ejb3DisableSfsbPassivation

Introduction

 

The aim of this wiki is to explain how to disable EJB3 stateful bean (SFSB) passivation. First of all, please remember that pasivation is there for a reason which is to conserve SFSB resources by "swapping out" stateful beans which effectively saves their conversational state to a hard disk or similar. However, there are situations where disabling passivation might make sense:

 

  • If you're having issues converting non-transient instance variables of your SFSB into objects that can be be passivated. For more information on what objects can be passivated or not, check the 4.2.1 section of the EJB3 specification.

  • Swapping out/in operations imply some kind of marshalling/unmarshalling which can have a performance impact. By disabling passivation, you're avoiding this performance penalty but instead your memory consumption requirements increase.

  • If unable to guarantee enough resources at the persistence layer to be able to cope with the passivation of the SFSBs.

 

There're two ways in which SFSB passivation be disabled:

 

Option 1: Use NoPassivationCache Cache Implementation

 

By using this option, SFSBs are stored in a cache that will not attempt to passivate its contents. There's a side effect to using this cache which is that SFSBs in this cache won't be removed after a certain timeout either. So, you should only use this method if you can guarantee that you'll be calling the @Remove method of the SFSB once you're done with it, otherwise it'll never be removed from memory, potentially leading to memory consumption issues. There're 3 ways in which you can implement this option:

 

Method 1. Change the cache implementation for all the SFSBs in your server by opening deploy/ejb3-interceptors-aop.xml file, locating the "Stateful Bean" domain and swapping this line:

<annotation expr="!class(@org.jboss.annotation.ejb.cache.Cache) AND !class(@org.jboss.annotation.ejb.Clustered)">
   @org.jboss.annotation.ejb.cache.Cache (org.jboss.ejb3.cache.simple.SimpleStatefulCache.class)
</annotation>)

 

For:

 

<annotation expr="!class(@org.jboss.annotation.ejb.cache.Cache) AND !class(@org.jboss.annotation.ejb.Clustered)">
   @org.jboss.annotation.ejb.cache.Cache (org.jboss.ejb3.cache.NoPassivationCache.class)
</annotation>

 

Method 2. Change the cache implementation for a specific SFSB by adding an annotation like this to your SFSB:

 

import org.jboss.annotation.ejb.cache.Cache;
...
@Cache(org.jboss.ejb3.cache.NoPassivationCache.class)
public class MySfsb
{
...

 

Method 3. Change the cache implementation for a specific SFSB by creating a META-INF/jboss.xml descriptor and adding something like this:

 

<?xml version="1.0" encoding="UTF-8"?>
<jboss
 xmlns="http://java.sun.com/xml/ns/javaee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
 http://www.jboss.org/j2ee/schema/jboss_5_0.xsd"
 version="3.0">
 <enterprise-beans>

   <session>
     <ejb-name>MySfsb</ejb-name>
     <cache-config>
       <cache-class>org.jboss.ejb3.cache.NoPassivationCache</cache-class>
     </cache-config>
   </session>
  
 </enterprise-beans>
</jboss>

 

Option 2: Make Removal Timeout Smaller Than Idle/Passivation Timeout

 

Another possibility is to stick to the default cache implementation used and instead tweak it so that the removal timeout is smaller, but not 0, than the idle or passivation timeout. By doing this, you're effectively making the bean be removed before it's even got a chance to be passivated, hence achieving the desired effect. One of the main benefits of using this option compared to the previous one is that SFSBs are removed periodically if their @Remove method has not been called which means that memory consumption problems are less likely to occur. Once again, there're 3 ways in which you can implement this option:

 

Method 1. Change the removal and idle timeouts for all SFSBs in your server by opening deploy/ejb3-interceptors-aop.xml file, locating the "Stateful Bean" domain and modifying this line:

<annotation expr="!class(@org.jboss.annotation.ejb.cache.simple.CacheConfig) AND !class(@org.jboss.annotation.ejb.Clustered)">
   @org.jboss.annotation.ejb.cache.simple.CacheConfig (maxSize=100000, idleTimeoutSeconds=300, removalTimeoutSeconds=0)
</annotation>

 

To looks something like this:

 

<annotation expr="!class(@org.jboss.annotation.ejb.cache.simple.CacheConfig) AND !class(@org.jboss.annotation.ejb.Clustered)">
   @org.jboss.annotation.ejb.cache.simple.CacheConfig (maxSize=100000, idleTimeoutSeconds=600, removalTimeoutSeconds=300))
</annotation>

 

Method 2. Change the removal and idle timeouts for a specific SFSB by adding an annotation like this to your SFSB:

 

import org.jboss.annotation.ejb.cache.simple.CacheConfig;
...
@CacheConfig (maxSize=100000, idleTimeoutSeconds=600, removalTimeoutSeconds=300))
public class MySfsb
{
...

 

Method 3. Change the removal and idle timeouts for a specific SFSB by creating a META-INF/jboss.xml descriptor and adding something like this:

 

<?xml version="1.0" encoding="UTF-8"?>
<jboss
 xmlns="http://java.sun.com/xml/ns/javaee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
 http://www.jboss.org/j2ee/schema/jboss_5_0.xsd"
 version="3.0">
 <enterprise-beans>

   <session>
     <ejb-name>MySfsb</ejb-name>
     <cache-config>
       <idle-timeout-seconds>600</idle-timeout-seconds>
       <remove-timeout-seconds>300</remove-timeout-seconds>
     </cache-config>
   </session>
  
 </enterprise-beans>
</jboss>