JBoss.org Community Documentation

18.4. Stateful Session Beans in EJB 3.0

To cluster stateful session beans in EJB 3.0, you need to tag the bean implementation class with the @Cluster annotation, just as we did with the EJB 3.0 stateless session bean earlier. The @org.jboss.ejb3.annotation.cache.tree.CacheConfig annotation can also be applied to the bean to specify caching behavior. Below is the definition of the @CacheConfig annotation:

 
public @interface CacheConfig
{
String name() default "jboss.cache:service=EJB3SFSBClusteredCache";
int maxSize() default 10000;
long idleTimeoutSeconds() default 300;   
boolean replicationIsPassivation() default true;   
long removalTimeoutSeconds() default 0;
} 
  • name specifies the object name of the JBoss Cache Mbean that should be used for caching the bean (see below for more on this Mbean).

  • maxSize specifies the maximum number of beans that can cached before the cache should start passivating beans, using an LRU algorithm.

  • idleTimeoutSeconds specifies the max period of time a bean can go unused before the cache should passivate it (irregardless of whether maxSize beans are cached.)

  • removalTimeoutSeconds specifies the max period of time a bean can go unused before the cache should remove it altogether.

  • replicationIsPassivation specifies whether the cache should consider a replication as being equivalent to a passivation, and invoke any @PrePassivate and @PostActivate callbacks on the bean. By default true, since replication involves serializing the bean, and preparing for and recovering from serialization is a common reason for implementing the callback methods.

Here is an example of a clustered EJB 3.0 stateful session bean implementation.

@Stateful
@Clustered
@CacheConfig(maxSize=5000,removalTimeoutSeconds=18000)
public class MyBean implements MySessionInt {
   
   private int state = 0;

   public void increment() {
      System.out.println("counter: " + (state++));
   }
}
            

As with stateless beans, the @Clustered annotation can also be omitted and the clustering configuration applied in jboss.xml; see the example above.

As with EJB 2.0 clustered SFSBs, JBoss provides a mechanism whereby a bean implementation can expose a method the container can invoke to check whether the bean's state is not dirty after a request and doesn't need to be replicated. With EJB3, the mechanism is a little more formal; instead of just exposing a method with a known signature, an EJB3 SFSB must implement the org.jboss.ejb3.cache.Optimized interface:

public interface Optimized {
boolean isModified();
}

JBoss Cache provides the session state replication service for EJB 3.0 stateful session beans. The related MBean service is defined in the ejb3-clustered-sfsbcache-service.xml file in the deploy directory. The contents of the file are as follows.

 
<server>
	<mbean code="org.jboss..cache.TreeCache"
	name="jboss.cache:service=EJB3SFSBClusteredCache">
	  
		<attribute name="ClusterName">
			${jboss.partition.name:DefaultPartition}-SFSBCache
			</attribute>
			<attribute name="IsolationLevel">REPEATABLE_READ</attribute>
			<attribute name="CacheMode">REPL_ASYNC</attribute> 
		  
			<!-- We want to activate/inactivate regions as beans are deployed --> 
			 <attribute name="UseRegionBasedMarshalling">true</attribute> 
			<!-- Must match the value of "useRegionBasedMarshalling" --> 
			<attribute name="InactiveOnStartup">true</attribute>
			  
			<attribute name="ClusterConfig">
			... ...
			</attribute> 
			  
			<!-- The max amount of time (in milliseconds) we wait until the 
			initial state (ie. the contents of the cache) are retrieved from 
			existing members.  --> 
			<attribute name="InitialStateRetrievalTimeout">17500</attribute>
			  
			<!--  Number of milliseconds to wait until all responses for a
				synchronous call have been received.
				-->
			<attribute name="SyncReplTimeout">17500</attribute>
			  
			<!--  Max number of milliseconds to wait for a lock acquisition -->
			<attribute name="LockAcquisitionTimeout">15000</attribute>
			  
			 <!--  Name of the eviction policy class. -->
			<attribute name="EvictionPolicyClass">
				org.jboss.cache.eviction.LRUPolicy
			</attribute>
			  
			<!--  Specific eviction policy configurations. This is LRU -->
			<attribute name="EvictionPolicyConfig">
			 <config>
				<attribute name="wakeUpIntervalSeconds">5</attribute>
				 <name>statefulClustered</name> 
				<!-- So default region would never timeout -->
				<region name="/_default_">
				<attribute name="maxNodes">0</attribute>
				 <attribute name="timeToIdleSeconds">0</attribute>
				</region>
			</config>
		</attribute> 
					  
	<!-- Store passivated sessions to the file system --> 
	 <attribute name="CacheLoaderConfiguration"> 
	<config> 
	  
	 <passivation>true</passivation> 
	<shared>false</shared> 
							  
	  <cacheloader> 
		 <class>org.jboss.cache.loader.FileCacheLoader</class> 
		<!-- Passivate to the server data dir --> 
		 <properties> 
			location=${jboss.server.data.dir}${/}sfsb 
		</properties> 
		<async>false</async> 
		<fetchPersistentState>true</fetchPersistentState> 
		<ignoreModifications>false</ignoreModifications> 
		</cacheloader> 
		  
			 </config> 
	   </attribute>
	</mbean>
</server>

The configuration attributes in this MBean are essentially the same as the attributes in the standard JBoss Cache TreeCache MBean discussed in Chapter 22, JBossCache and JGroups Services . Again, we omitted the JGroups configurations in the ClusterConfig attribute (see more in Section 22.1, “JGroups Configuration”). Two noteworthy items: