An EJB container is the component that manages a particular class of EJB. In JBoss there is one instance of the org.jboss.ejb.Container created for each unique configuration of an EJB that is deployed. The actual object that is instantiated is a subclass of Container, and the creation of the container instance is managed by the EJBDeployer MBean. The EJBDeployer MBeanThe org.jboss.ejb.EJBDeployer MBean is responsible for the creation of EJB containers. Given an EJB JAR that is ready for deployment, the EJBDeployer will create and initialize the necessary EJB containers, one for each type of EJB. These are the configurable attributes of the EJBDeployer:
The deployer contains two central methods: deploy and undeploy. The deploy method takes a URL, which either points to an EJB JAR or to a directory whose structure is the same as a valid EJB JAR (which is convenient for development purposes). After a deployment has been made, you can undeploy it by calling undeploy on the same URL. A call to deploy with an already-deployed URL will cause an undeploy followed by deployment of the URL. JBoss has support for full re-deployment of both implementation and interface classes, and it reloads any changed classes. This allows you to develop and update EJBs without ever stopping a running server. During the deployment of the EJB JAR, the EJBDeployer and its associated classes perform three main functions: verify the EJBs, create a container for each unique EJB, and initialize the container with the deployment configuration information. The following sections talk about each of these functions. Verifying EJB DeploymentsWhen the VerifyDeployments attribute of EJBDeployer is true, the deployer performs a verification of EJBs in the deployment. The verification checks that an EJB meets EJB specification compliance. This entails validating that the EJB deployment unit contains the required home, remote, local home, and local interfaces. It also checks that the objects appearing in these interfaces are of the proper types and that the required methods are present in the implementation class. This is a useful behavior that is enabled by default because there are a number of steps that an EJB developer and deployer must perform correctly to construct a proper EJB JAR, and it is easy to make a mistake. The verification stage attempts to catch any errors and fail the deployment with an error that indicates what needs to be corrected. Probably the most problematic aspect of writing EJBs is the fact that there is a disconnection between the bean implementation and its remote and home interfaces, as well as its deployment descriptor configuration. It is easy to have these separate elements get out of sync. One tool that helps eliminate this problem is XDoclet. It allows you to use custom JavaDoc-like tags in the EJB bean implementation class to generate the related bean interfaces, deployment descriptors, and related objects. See the XDoclet home page, http://sourceforge.net/projects/xdoclet, for additional details. Deploying EJBs into ContainersThe most important roles that the EJBDeployer performs are creating an EJB container and deploying the EJB into the container. The deployment phase consists of iterating over EJBs in an EJB JAR and extracting the bean classes and their metadata as described by the ejb-jar.xml and jboss.xml deployment descriptors. For each EJB in the EJB JAR, the following steps are performed:
Initializing with Configuration InformationJBoss externalizes most, if not all, of the setup of the EJB containers, using an XML file that conforms to the jboss_4_0.dtd. The section of the DTD that relates to container configuration information is shown in Figure 5.4. Figure 5.4. The jboss_4_0 DTD elements related to container configuration.
The container-configuration element and its subelements specify container configuration settings for a type of container, as given by the container-name element. Each configuration specifies information such as the default invoker type, the container interceptor makeup, instance caches/pools and their sizes, the persistence manager, security, and so on. Because this is a large amount of information that requires a detailed understanding of the JBoss container architecture, JBoss ships with a standard configuration file for the four types of EJBs. This configuration file is called standardjboss.xml, and it is located in the conf directory of any configuration file set that uses EJBs. The following is a sample of container-configuration from standardjboss.xml:
The container configuration information can be specified at two levels. The first is in the standardjboss.xml file that is contained in the configuration file set directory. The second is at the EJB JAR level. By placing a jboss.xml file in the EJB JAR META-INF directory, you can specify either overrides for container configurations in the standardjboss.xml file or entirely new named container configurations. This provides great flexibility in the configuration of containers. As you have seen, all container configuration attributes have been externalized and are therefore easily modifiable. Knowledgeable developers can even implement specialized container components, such as instance pools or caches, and easily integrate them with the standard container configurations to optimize behavior for a particular application or environment. How an EJB deployment chooses its container configuration is based on the explicit or implicit jboss/enterprise-beans/<type>/configuration-name element. The configuration-name element is a link to a container-configurations/container-configuration element in Figure 5.4. It specifies which container configuration to use for the referring EJB. The link is from a configuration-name element to a container-name element. You can specify container configurations per class of EJB by including a container-configuration element in the EJB definition. Typically, you do not define completely new container configurations, although doing so is supported. The typical usage of a jboss.xml-level container-configuration is to override one or more aspects of a container-configuration coming from the standardjboss.xml descriptor. You do this by specifying a container-configuration that references the name of an existing standardjboss.xml container-configuration/container-name as the value for the container-configuration/extends attribute. The following example shows an example of defining a new Secured Stateless SessionBean configuration that is an extension of the Standard Stateless SessionBean configuration: <?xml version="1.0"?> <jboss> <enterprise-beans> <session> <ejb-name>EchoBean</ejb-name> <configuration-name>Secured Stateless SessionBean</configuration-name> <!-- ... --> </session> </enterprise-beans> <container-configurations> <container-configuration extends="Standard Stateless SessionBean"> <container-name>Secured Stateless SessionBean</container-name> <!-- Override the container security domain --> <security-domain>java:/jaas/my-security-domain</security-domain> </container-configuration> </container-configurations> </jboss> If an EJB does not provide a container configuration specification in the deployment-unit EJB JAR, the container factory chooses a container configuration from the standardjboss.xml descriptor, based on the type of the EJB. So, in reality, there is an implicit configuration-name element for every type of EJB, and the mappings from the EJB type to default container configuration name are as follows:
It is not necessary to indicate which container configuration an EJB is using if you want to use the default, based on the bean type. It probably provides for a more self-contained descriptor to include the configuration-name element, but this is purely a matter of style. Now that you know how to specify which container configuration an EJB is using and can define a deployment unit-level override, let's look at the container-configuration child elements. A number of the elements specify interface class implementations whose configurations are affected by other elements, so before starting in on the configuration elements, you need to understand the org.jboss.metadata.XmlLoadable interface. XmlLoadable is a simple interface that consists of a single method. The interface definition is as follows: import org.w3c.dom.Element; public interface XmlLoadable { public void importXml(Element element) throws Exception; } Classes implement this interface to allow their configuration to be specified via an XML document fragment. The root element of the document fragment is what would be passed to the importXml method. You will see a few examples of this as the container configuration elements are described in the following sections. The container-name ElementThe container-name element specifies a unique name for a given configuration. EJBs link to a particular container configuration by setting their configuration-name element to the value of the container-name for the container configuration. The call-logging ElementThe call-logging element expects a Boolean (true or false) as its value, to indicate whether the LogInterceptor should log method calls to a container. This is somewhat obsolete with the change to log4j, which provides a finegrained logging API. The invoker-proxy-binding-name ElementThe invoker-proxy-binding-name element specifies the name of the default invoker to use. In the absence of a bean-level invoker-bindings specification, the invoker-proxy-binding whose name matches the invoker-proxy-binding-name element value is used to create home and remote proxies. The sync-on-commit-only ElementThe sync-on-commit-only element configures a performance optimization that causes entity bean state to be synchronized with the database only at commit time. Normally, the state of all the beans in a transaction would need to be synchronized when a finder method is called or when a remove method is called, for example. The insert-after-ejb-post-create ElementThe insert-after-ejb-post-create element is another entity bean optimization. It causes the database insert command for a new entity bean to be delayed until the ejbPostCreate method is called. This allows normal CMP fields as well as CMR fields to be set in a single insert, instead of the default insert followed by an update; this removes the requirement for relationship fields to allow null values. The call-ejb-store-on-clean ElementAccording to the EJB specification, the container is required to call ejbStore method on an entity bean instance when a transaction commits, even if the instance was not modified in the transaction. Setting the call-ejb-store-on-clean element to false causes JBoss to call ejbStore only for dirty objects. The container-interceptors ElementThe container-interceptors element specifies one or more interceptor elements that are to be configured as the method interceptor chain for the container. The value of the interceptor element is a fully qualified classname of an org.jboss.ejb.Interceptor interface implementation. The container interceptors form a linked-list structure through which EJB method invocations pass. The first interceptor in the chain is invoked when the MBeanServer passes a method invocation to the container. The last interceptor invokes the business method on the bean. We will discuss the Interceptor interface later in this chapter, in the section "The Container Plug-in Framework." Generally, you need to be careful when changing an existing standard EJB interceptor configuration because the EJB contract regarding security, transactions, persistence, and thread safety derives from the interceptors. The instance-pool ElementThe instance-pool element specifies the fully qualified classname of an org.jboss.ejb.InstancePool interface implementation to use as the container InstancePool. We will discuss the InstancePool interface in detail later in this chapter, in the section "The Container Plug-in Framework." The container-pool-conf ElementThe container-pool-conf element is passed to the InstancePool implementation class given by the instance-pool element if it implements the XmlLoadable interface. All current JBoss InstancePool implementations derive from the org.jboss.ejb.plugins.AbstractInstancePool class, which provides support for the following elements, shown in Figure 5.5: Figure 5.5. The container-pool-conf element DTD.
The instance-cache ElementThe instance-cache element specifies the fully qualified classname of the org.jboss.ejb.InstanceCache interface implementation. This element is meaningful only for entity and stateful session beans because these are the only EJB types that have associated identities. We will discuss the InstanceCache interface in detail later in this chapter, in the section "The Container Plug-in Framework." The container-cache-conf ElementThe container-cache-conf element is passed to the InstanceCache implementation if it supports the XmlLoadable interface. All current JBoss InstanceCache implementations derive from the org.jboss.ejb.plugins.AbstractInstanceCache class, which provides support for the XmlLoadable interface and uses the cache-policy child element as the fully qualified classname of an org.jboss.util.CachePolicy implementation that is used as the instance cache store. The cache-policy-conf child element is passed to the CachePolicy implementation if it supports the XmlLoadable interface. If it does not, the cache-policy-conf will silently be ignored. Two JBoss implementations of CachePolicy that are used by the standardjboss.xml configuration support the current array of cache-policy-conf child elements: org.jboss.ejb.plugins.LRUEnterpriseContextCachePolicy and org.jboss.ejb.plugins.LRUStatefulContextCachePolicy. Entity bean containers use LRUEnterpriseContextCachePolicy, and stateful session bean containers use LRUStatefulContextCachePolicy. Both cache policies support the following cache-policy-conf child elements, which are shown in Figure 5.6: Figure 5.6. The container-cache-conf element DTD.
LRUStatefulContextCachePolicy also supports these child elements:
An alternative cache policy implementation is the org.jboss.ejb.plugins.NoPassivationCachePolicy class, which simply never passivates instances. It uses an in-memory HashMap implementation that never discards instances unless they are explicitly removed. This class does not support any of the cache-policy-conf configuration elements. The persistence-manager ElementThe persistence-manager element value specifies the fully qualified classname of the persistence manager implementation. The type of the implementation depends on the type of EJB. For stateful session beans, it must be an implementation of the org.jboss.ejb.StatefulSessionPersistenceManager interface. For BMP entity beans, it must be an implementation of the org.jboss.ejb.EntityPersistenceManager interface, and for CMP entity beans, it must be an implementation of the org.jboss.ejb.EntityPersistenceStore interface. The web-class-loader ElementThe web-class-loader element specifies a subclass of org.jboss.web.WebClassLoader that is used in conjunction with the WebService MBean to allow dynamic loading of resources and classes from deployed EARs, EJB JARs, and WARs. A WebClassLoader is associated with a Container and must have an org.jboss.mx.loading.UnifiedClassLoader as its parent. It overrides the getURLs() method to return a different set of URLs for remote loading than what is used for local loading. WebClassLoader has two methods, which are meant to be overridden by subclasses: getKey() and getBytes(). The latter is a no-op in this implementation and should be overridden by subclasses with bytecode-generation ability, such as the class loader used by the iiop module. A WebClassLoader subclass must have a constructor with the same signature as the WebClassLoader(ObjectNamecontainerName, UnifiedClassLoader parent) constructor. The locking-policy ElementThe locking-policy element gives the fully qualified classname of the EJB lock implementation to use. This class must implement the org.jboss.ejb.BeanLock interface. The current JBoss versions include the following:
Locking and deadlock detection are discussed in more detail later in this chapter, in the section "Entity Bean Locking and Deadlock Detection." The commit-option and optiond-refresh-rate ElementsThe commit-option value specifies the EJB entity bean persistent storage commit option. It must be one of the following:
The security-domain ElementThe security-domain element specifies the JNDI name of the object that implements the org.jboss.security.AuthenticationManager and org.jboss.security.RealmMapping interfaces. It is more typical to specify the security-domain under the jboss root element so that all EJBs in a given deployment are secured in the same manner. However, it is possible to configure the security domain for each bean configuration. The details of the security manager interfaces and configuring the security layer are discussed in Chapter 8, "Security on JBoss." The cluster-config ElementThe cluster-config element allows you to specify cluster-specific settings for all EJBs that use the container configuration. You can specify the cluster configuration at the container configuration level or at the individual EJB deployment level. The cluster-config DTD fragment is shown in Figure 5.7. Figure 5.7. cluster-config and related elements.
The child elements are as follows:
The depends Element The depends element gives a JMX ObjectName of a service on which the container or EJB depends. Specification of explicit dependencies on other services prevents the need to worry about the natural deployment ordering of the services. The Container Plug-in FrameworkThe JBoss EJB container uses a framework pattern that allows you to change implementations of various aspects of the container's behavior. The container itself does not perform any significant work other than connecting the various behavioral components together. Implementations of the behavioral components are referred to as plug-ins because you can plug in a new implementation by changing a container configuration. Examples of plugin behavior you might want to change include persistence management, object pooling, object caching, container invoking, and intercepting. There are four subclasses of the org.jboss.ejb.Container class, each of which implements a particular bean type:
The EJB containers delegate much of their behavior to components known as container plug-ins. The interfaces that make up the container plug-in points include the following: org.jboss.ejb.ContainerPlugin org.jboss.ejb.ContainerInvoker org.jboss.ejb.Interceptor org.jboss.ejb.InstancePool org.jboss.ejb.InstanceCache org.jboss.ejb.EntityPersistanceManager org.jboss.ejb.EntityPersistanceStore org.jboss.ejb.StatefulSessionPersistenceManager The container's main responsibility is to manage its plug-ins. This means ensuring that the plug-ins have all the information they need to implement their functionality. The org.jboss.ejb.ContainerPlugin InterfaceThe ContainerPlugin interface is the parent interface of all container plug-in interfaces. It provides a callback that allows a container to give each of its plug-ins a pointer to the container the plug-in is working on behalf of. The ContainerPlugin interface is shown in Listing 5.4. Listing 5.4. The org.jboss.ejb.ContainerPlugin Interfacepublic interface ContainerPlugin extends Service, AllowedOperationsFlags { /** * This callback is set by the container so that the plugin * may access its container * * @param con the container which owns the plugin */ public void setContainer(Container con); } The org.jboss.ejb.Interceptor InterfaceThe Interceptor interface enables you to build a chain of method interceptors through which each EJB method invocation must pass. The Interceptor interface is shown in Listing 5.5. Listing 5.5. The org.jboss.ejb.Interceptor Interfaceimport org.jboss.invocation.Invocation; public interface Interceptor extends ContainerPlugin { public void setNext(Interceptor interceptor); public Interceptor getNext(); public Object invokeHome(Invocation mi) throws Exception; public Object invoke(Invocation mi) throws Exception; } All interceptors defined in the container configuration are created and added to the container interceptor chain by EJBDeployer. The last interceptor is not added by the deployer but rather by the container itself because this is the interceptor that interacts with the EJB bean implementation. The order of the interceptor in the chain is important. The idea behind ordering is that interceptors that are not tied to a particular EnterpriseContext instance are positioned before interceptors that interact with caches and pools. Implementers of the Interceptor interface form a linked-list type of structure through which the Invocation object is passed. The first interceptor in the chain is invoked when an invoker passes an Invocation to the container via the JMX bus. The last interceptor invokes the business method on the bean. There are usually on the order of five interceptors in a chain, depending on the bean type and container configuration. Interceptor semantic complexity ranges from simple to complex. An example of a simple interceptor is LoggingInterceptor, and an example of a complex interceptor is EntitySynchronizationInterceptor. One of the main advantages of an interceptor pattern is flexibility in the arrangement of interceptors. Another advantage is the clear functional distinction between different interceptors. For example, logic for transaction and security is cleanly separated between TXInterceptor and SecurityInterceptor, respectively. If any of the interceptors fail, the call is terminated at that point. This is a fail-quickly type of semantic. For example, if a secured EJB is accessed without proper permissions, the call fails as the SecurityInterceptor before any transactions are started or instance caches are updated. The org.jboss.ejb.InstancePool InterfaceAn InstancePool is used to manage the EJB instances that are not associated with any identity. The pools actually manage subclasses of the org.jboss.ejb.EnterpriseContext objects that aggregate unassociated bean instances and related data. Listing 5.6 shows the InstancePool interface. Listing 5.6. The org.jboss.ejb.InstancePool Interfacepublic interface InstancePool extends ContainerPlugin { /** * Get an instance without identity. Can be used * by finders and create-methods, or stateless beans * * @return Context /w instance * @exception RemoteException */ public EnterpriseContext get() throws Exception; /** Return an anonymous instance after invocation. * * @param ctx */ public void free(EnterpriseContext ctx); /** * Discard an anonymous instance after invocation. * This is called if the instance should not be reused, * perhaps due to some exception being thrown from it. * * @param ctx */ public void discard(EnterpriseContext ctx); /** * Return the size of the pool. * * @return the size of the pool. */ public int getCurrentSize(); /** * Get the maximum size of the pool. * * @return the size of the pool. */ public int getMaxSize(); } Depending on the configuration, a container may choose to have a certain size of the pool contain recycled instances, or it may choose to instantiate and initialize an instance on demand. The InstanceCache implementation uses the pool to acquire free instances for activation, and interceptors use the pool to acquire instances to be used for Home interface methods (create and finder calls). The org.jboss.ebj.InstanceCache InterfaceThe container InstanceCache implementation handles all EJB instances that are in an active state, meaning bean instances that have an identity attached to them. Only entity and stateful session beans are cached, as these are the only bean types that have state between method invocations. The cache key of an entity bean is the bean primary key. The cache key for a stateful session bean is the session ID. Listing 5.7 shows the InstanceCache interface. Listing 5.7. The org.jboss.ejb.InstanceCache Interfacepublic interface InstanceCache extends ContainerPlugin { /** * Gets a bean instance from this cache given the identity. * This method may involve activation if the instance is not * in the cache. * Implementation should have O(1) complexity. * This method is never called for stateless session beans. * * @param id the primary key of the bean * @return the EnterpriseContext related to the given id * @exception RemoteException in case of illegal calls * (concurrent / reentrant), NoSuchObjectException if * the bean cannot be found. * @see #release */ public EnterpriseContext get(Object id) throws RemoteException, NoSuchObjectException; /** * Inserts an active bean instance after creation or activation. * Implementation should guarantee proper locking and O(1) complexity. * * @param ctx the EnterpriseContext to insert in the cache * @see #remove */ public void insert(EnterpriseContext ctx); /** * Releases the given bean instance from this cache. * This method may passivate the bean to get it out of the cache. * Implementation should return almost immediately leaving the * passivation to be executed by another thread. * * @param ctx the EnterpriseContext to release * @see #get */ public void release(EnterpriseContext ctx); /** * Removes a bean instance from this cache given the identity. * Implementation should have O(1) complexity and guarantee * proper locking. * * @param id the primary key of the bean * @see #insert */ public void remove(Object id); /** * Checks whether an instance corresponding to a particular * id is active * * @param id the primary key of the bean * @see #insert */ public boolean isActive(Object id); } In addition to managing the list of active instances, the InstanceCache is also responsible for activating and passivating instances. If an instance with a given identity is requested, and it is not currently active, the InstanceCache must use the InstancePool to acquire a free instance, and then the persistence manager must activate the instance. Similarly, if the InstanceCache decides to passivate an active instance, it must call the persistence manager to passivate it and release the instance to the InstancePool. The org.jboss.ejb.EntityPersistenceManager InterfaceThe EntityPersistenceManager interface is responsible for the persistence of entity beans. This includes the following:
Listing 5.8 shows the EntityPersistenceManager interface. Listing 5.8. The org.jboss.ejb.EntityPersistenceManager Interfacepublic interface EntityPersistenceManager extends ContainerPlugin { /** * Returns a new instance of the bean class or a subclass of the * bean class. * * @return the new instance */ Object createBeanClassInstance() throws Exception; /** * This method is called whenever an entity is to be created. The * persistence manager is responsible for calling the ejbCreate method * on the instance and to handle the results properly wrt the persistent * store. * * @param m the create method in the home interface that was * called * @param args any create parameters * @param instance the instance being used for this create call */ void createEntity(Method m, Object[] args, EntityEnterpriseContext instance) throws Exception; /** * This method is called whenever an entity is to be created. The * persistence manager is responsible for calling the ejbPostCreate method * on the instance and to handle the results properly wrt the persistent * store. * * @param m the create method in the home interface that was * called * @param args any create parameters * @param instance the instance being used for this create call */ void postCreateEntity(Method m, Object[] args, EntityEnterpriseContext instance) throws Exception; /** * This method is called when single entities are to be found. The * persistence manager must find out whether the wanted instance is * available in the persistence store, and if so it shall use the * ContainerInvoker plugin to create an EJBObject to the instance, which * is to be returned as result. * * @param finderMethod the find method in the home interface that was * called * @param args any finder parameters * @param instance the instance to use for the finder call * @return an EJBObject representing the found entity */ Object findEntity(Method finderMethod, Object[] args, EntityEnterpriseContext instance) throws Exception; /** * This method is called when collections of entities are to be * found. The persistence manager must find out whether the wanted * instances are available in the persistence store, and if so it * shall use the ContainerInvoker plugin to create EJBObjects to * the instances, which are to be returned as result. * * @param finderMethod the find method in the home interface that was * called * @param args any finder parameters * @param instance the instance to use for the finder call * @return an EJBObject collection representing the found * entities */ Collection findEntities(Method finderMethod, Object[] args, EntityEnterpriseContext instance) throws Exception; /** * This method is called when an entity shall be activated. The * persistence manager must call the ejbActivate method on the * instance. * * @param instance the instance to use for the activation * * @throws RemoteException thrown if some system exception occurs */ void activateEntity(EntityEnterpriseContext instance) throws RemoteException; /** * This method is called whenever an entity shall be loaded from the * underlying storage. The persistence manager must load the state * from the underlying storage and then call ejbLoad on the * supplied instance. * * @param instance the instance to synchronize * * @throws RemoteException thrown if some system exception occurs */ void loadEntity(EntityEnterpriseContext instance) throws RemoteException; /** * This method is used to determine if an entity should be stored. * * @param instance the instance to check * @return true, if the entity has been modified * @throws Exception thrown if some system exception occurs */ boolean isModified(EntityEnterpriseContext instance) throws Exception; /** * This method is called whenever an entity shall be stored to the * underlying storage. The persistence manager must call ejbStore * on the supplied instance and then store the state to the * underlying storage. * * @param instance the instance to synchronize * * @throws RemoteException thrown if some system exception occurs */ void storeEntity(EntityEnterpriseContext instance) throws RemoteException; /** * This method is called when an entity shall be passivated. The * persistence manager must call the ejbPassivate method on the * instance. * * @param instance the instance to passivate * * @throws RemoteException thrown if some system exception occurs */ void passivateEntity(EntityEnterpriseContext instance) throws RemoteException; /** * This method is called when an entity shall be removed from the * underlying storage. The persistence manager must call ejbRemove * on the instance and then remove its state from the underlying * storage. * * @param instance the instance to remove * * @throws RemoteException thrown if some system exception occurs * @throws RemoveException thrown if the instance could not be removed */ void removeEntity(EntityEnterpriseContext instance) throws RemoteException, RemoveException; } The org.jboss.ejb.EntityPersistenceStore InterfaceAs per the EJB 2.1 specification, JBoss supports two entity bean persistence semantics: container-managed persistence (CMP) and bean-managed persistence (BMP). The CMP implementation uses an implementation of the org.jboss.ejb.EntityPersistenceStore interface. By default, this is the org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreManager, which is the entry point for the CMP2 persistence engine. The EntityPersistenceStore interface is shown in Listing 5.9. Listing 5.9. The org.jboss.ejb.EntityPersistenceStore Interface{ /** * Returns a new instance of the bean class or a subclass of the * bean class. * * @return the new instance * * @throws Exception */ Object createBeanClassInstance() throws Exception; /** * Initializes the instance context. * * <p>This method is called before createEntity, and should * reset the value of all cmpFields to 0 or null. * * @param ctx * * @throws RemoteException */ void initEntity(EntityEnterpriseContext ctx); /** * This method is called whenever an entity is to be created. The * persistence manager is responsible for handling the results * properly wrt the persistent store. * * @param m the create method in the home interface that was * called * @param args any create parameters * @param instance the instance being used for this create call * @return The primary key computed by CMP PM or null for BMP * * @throws Exception */ Object createEntity(Method m, Object[] args, EntityEnterpriseContext instance) throws Exception; /** * This method is called when single entities are to be found. The * persistence manager must find out whether the wanted instance * is available in the persistence store, if so it returns the * primary key of the object. * * @param finderMethod the find method in the home interface that was * called * @param args any finder parameters * @param instance the instance to use for the finder call * @return a primary key representing the found entity * * @throws RemoteException thrown if some system exception occurs * @throws FinderException thrown if some heuristic problem occurs */ Object findEntity(Method finderMethod, Object[] args, EntityEnterpriseContext instance) throws Exception; /** * This method is called when collections of entities are to be * found. The persistence manager must find out whether the wanted * instances are available in the persistence store, and if so it * must return a collection of primaryKeys. * * @param finderMethod the find method in the home interface that was * called * @param args any finder parameters * @param instance the instance to use for the finder call * @return a primary key collection representing the found * entities * * @throws RemoteException thrown if some system exception occurs * @throws FinderException thrown if some heuristic problem occurs */ Collection findEntities(Method finderMethod, Object[] args, EntityEnterpriseContext instance) throws Exception; /** * This method is called when an entity shall be activated. * * <p>With the PersistenceManager factorization most EJB * calls should not exist However this call permits us to * introduce optimizations in the persistence store. Particularly * the context has a "PersistenceContext" that a PersistenceStore * can use (JAWS does for smart updates) and this is as good a * callback as any other to set it up. * @param instance the instance to use for the activation * * @throws RemoteException thrown if some system exception occurs */ void activateEntity(EntityEnterpriseContext instance) throws RemoteException; /** * This method is called whenever an entity shall be loaded from the * underlying storage. The persistence manager must load the state * from the underlying storage and then call ejbLoad on the * supplied instance. * * @param instance the instance to synchronize * * @throws RemoteException thrown if some system exception occurs */ void loadEntity(EntityEnterpriseContext instance) throws RemoteException; /** * This method is used to determine if an entity should be stored. * * @param instance the instance to check * @return true, if the entity has been modified * @throws Exception thrown if some system exception occurs */ boolean isModified(EntityEnterpriseContext instance) throws Exception; /** * This method is called whenever an entity shall be stored to the * underlying storage. The persistence manager must call ejbStore * on the supplied instance and then store the state to the * underlying storage. * * @param instance the instance to synchronize * * @throws RemoteException thrown if some system exception occurs */ void storeEntity(EntityEnterpriseContext instance) throws RemoteException; /** * This method is called when an entity shall be passivated. The * persistence manager must call the ejbPassivate method on the * instance. * * <p>See the activate discussion for the reason for * exposing EJB callback * calls to the store. * * @param instance the instance to passivate * * @throws RemoteException thrown if some system exception occurs */ void passivateEntity(EntityEnterpriseContext instance) throws RemoteException; /** * This method is called when an entity shall be removed from the * underlying storage. The persistence manager must call ejbRemove * on the instance and then remove its state from the underlying * storage. * * @param instance the instance to remove * * @throws RemoteException thrown if some system exception occurs * @throws RemoveException thrown if the instance could not be removed */ void removeEntity(EntityEnterpriseContext instance) throws RemoteException, RemoveException; } The default BMP implementation of the EntityPersistenceManager interface is org.jboss.ejb.plugins.BMPPersistenceManager. The BMP persistence manager is fairly simple because all persistence logic is in the entity bean itself. The only duty of the persistence manager is to perform container callbacks. The org.jboss.ejb.StatefulSessionPersistenceManager InterfaceThe StatefulSessionPersistenceManager interface is responsible for the persistence of stateful session beans. This includes the following:
The StatefulSessionPersistenceManager interface is shown in Listing 5.10. Listing 5.10. The org.jboss.ejb.StatefulSessionPersistenceManager Interfacepublic interface StatefulSessionPersistenceManager extends ContainerPlugin { public void createSession(Method m, Object[] args, StatefulSessionEnterpriseContext ctx) throws Exception; public void activateSession(StatefulSessionEnterpriseContext ctx) throws RemoteException; public void passivateSession(StatefulSessionEnterpriseContext ctx) throws RemoteException; public void removeSession(StatefulSessionEnterpriseContext ctx) throws RemoteException, RemoveException; public void removePassivated(Object key); } The default implementation of the StatefulSessionPersistenceManager interface is org.jboss.ejb.plugins.StatefulSessionFilePersistenceManager. As its name implies, StatefulSessionFilePersistenceManager utilizes the file system to persist stateful session beans. More specifically, the persistence manager serializes beans in a flat file whose name is composed of the bean name and session ID, with a .ser extension. The persistence manager restores a bean's state during activation and respectively stores its state during passivation from the bean's .ser file. |