The EJB Container


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 MBean

The 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:

  • VerifyDeployments A Boolean flag that indicates whether the EJB verifier should be run. This validates that the EJBs in a deployment unit conform to the EJB 2.1 specification. Setting this to true is useful for ensuring that your deployments are valid.

  • VerifierVerbose A Boolean that controls the verbosity of any verification failures/warnings that result from the verification process.

  • StrictVerifier A Boolean that enables/disables strict verification. When strict verification is enabled, an EJB will deploy only if the verifier reports no errors.

  • CallByValue A Boolean flag which indicates that call-by-value semantics should be used by default.

  • ValidateDTDs ABoolean flag that indicates whether the ejb-jar.xml and jboss.xml descriptors should be validated against their declared DTDs. Setting this to true is useful for ensuring that your deployment descriptors are valid.

  • MetricsEnabled A Boolean flag that controls whether container interceptors marked with a metricsEnabled=true attribute should be included in the configuration. This allows you to define a container interceptor configuration that includes metric-type interceptors that can be toggled on and off.

  • WebServiceName The JMX ObjectName string of the web service MBean that provides support for the dynamic class loading of EJB classes.

  • transactionManagerServiceName The JMX ObjectName string of the JTA transaction manager service. This must have an attribute named transactionManager that returns that javax.transaction.TransactionManager instance.

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 Deployments

When 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 Containers

The 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:

1.

Create a subclass of org.jboss.ejb.Container, depending on the type of the EJB: stateless, stateful, BMP entity, CMP entity, or message driven. The container is assigned a unique ClassLoader from which it can load local resources. The uniqueness of the ClassLoader is also used to isolate the standard java:comp JNDI namespace from other J2EE components.

2.

Set all container-configurable attributes from a merge of the jboss.xml and standardjboss.xml descriptors.

3.

Create and add the container interceptors, as configured for the container.

4.

Associate the container with an application object. This application object represents a J2EE enterprise application and may contain multiple EJBs and web contexts.

5.

If all EJBs are successfully deployed, the application is started, which in turn starts all containers and makes the EJBs available to clients. If any EJB fails to deploy, a deployment exception is thrown, and the deployment module is failed.

Initializing with Configuration Information

JBoss 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:

[View full width]

<container-configuration> <container-name>Standard CMP 2.x EntityBean</container-name> <call-logging>false</call-logging> <invoker-proxy-binding-name>entity-rmi-invoker</invoker-proxy-binding-name> <sync-on-commit-only>false</sync-on-commit-only> <insert-after-ejb-post-create>false</insert-after-ejb-post-create> <call-ejb-store-on-clean>true</call-ejb-store-on-clean> <container-interceptors> <interceptor>org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor</interceptor> <interceptor>org.jboss.ejb.plugins.LogInterceptor</interceptor> <interceptor>org.jboss.ejb.plugins.SecurityInterceptor</interceptor> <interceptor>org.jboss.ejb.plugins.TxInterceptorCMT</interceptor> <interceptor>org.jboss.ejb.plugins.CallValidationInterceptor</interceptor> <interceptor metricsEnabled="true">org.jboss.ejb.plugins.MetricsInterceptor< /interceptor> <interceptor>org.jboss.ejb.plugins.EntityCreationInterceptor</interceptor> <interceptor>org.jboss.ejb.plugins.EntityLockInterceptor</interceptor> <interceptor>org.jboss.ejb.plugins.EntityInstanceInterceptor</interceptor> <interceptor>org.jboss.ejb.plugins.EntityReentranceInterceptor</interceptor> <interceptor>org.jboss.resource.connectionmanager.CachedConnectionInterceptor< /interceptor> <interceptor>org.jboss.ejb.plugins.EntitySynchronizationInterceptor</interceptor> <interceptor>org.jboss.ejb.plugins.cmp.jdbc.JDBCRelationInterceptor</interceptor> </container-interceptors> <instance-pool>org.jboss.ejb.plugins.EntityInstancePool</instance-pool> <instance-cache>org.jboss.ejb.plugins.InvalidableEntityInstanceCache</instance-cache> <persistence-manager>org.jboss.ejb.plugins.cmp.jdbc.JDBCStoreManager</persistence-manager> <locking-policy>org.jboss.ejb.plugins.lock.QueuedPessimisticEJBLock</locking-policy> <container-cache-conf> <cache-policy>org.jboss.ejb.plugins.LRUEnterpriseContextCachePolicy</cache-policy> <cache-policy-conf> <min-capacity>50</min-capacity> <max-capacity>1000000</max-capacity> <overager-period>300</overager-period> <max-bean-age>600</max-bean-age> <resizer-period>400</resizer-period> <max-cache-miss-period>60</max-cache-miss-period> <min-cache-miss-period>1</min-cache-miss-period> <cache-load-factor>0.75</cache-load-factor> </cache-policy-conf> </container-cache-conf> <container-pool-conf> <MaximumSize>100</MaximumSize> </container-pool-conf> <commit-option>B</commit-option> </container-configuration>

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:

  • Container-managed persistence entity version 2.0 = Standard CMP 2.x EntityBean

  • Container-managed persistence entity version 1.1 = Standard CMP EntityBean

  • Bean-managed persistence entity = Standard BMP EntityBean

  • Stateless session = Standard Stateless SessionBean

  • Stateful session = Standard Stateful SessionBean

  • Message driven = Standard Message Driven Bean

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 Element

The 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 Element

The 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 Element

The 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 Element

The 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 Element

The 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 Element

According 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 Element

The 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 Element

The 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 Element

The 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.


  • MinimumSize The MinimumSize element gives the minimum number of instances to keep in the pool, although JBoss does not currently seed an InstancePool to the MinimumSize value.

  • MaximumSize The MaximumSize element specifies the maximum number of pool instances that are allowed. The default use of MaximumSize may not be what you expect. The pool MaximumSize is the maximum number of EJB instances that are kept available, but additional instances can be created if the number of concurrent requests exceeds the MaximumSize value.

  • strictMaximumSize If you want to limit the maximum concurrency of an EJB to the pool MaximumSize, you need to set the strictMaximumSize element to TRue. When strictMaximumSize is true, only MaximumSize EJB instances can be active. When there are MaximumSize active instances, any subsequent requests will be blocked until an instance is freed back to the pool. The default value for strictMaximumSize is false.

  • strictTimeout How long a request blocks waiting for an instance pool object is controlled by the strict-Timeout element. strictTimeout defines the time, in milliseconds, to wait for an instance to be returned to the pool when there are MaximumSize active instances. A value less than or equal to 0 means not to wait at all. When a request times out while waiting for an instance, a java.rmi.ServerException is generated, and the call is aborted. This element is parsed as a Long, so the maximum possible wait time is 9,223,372,036,854,775,807, or about 292,471,208 years, and this is the default value.

The instance-cache Element

The 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 Element

The 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.


  • min-capacity Specifies the minimum capacity of this cache.

  • max-capacity Specifies the maximum capacity of the cache, which cannot be less than min-capacity.

  • overager-period Specifies the period, in seconds, between runs of the overager task. The purpose of the overager task is to see whether the cache contains beans with an age greater than the max-bean-age element value. Any beans that meet this criterion are passivated.

  • max-bean-age Specifies the maximum period of inactivity, in seconds, a bean can have before it will be passivated by the overager process.

  • resizer-period Specifies the period, in seconds, between runs of the resizer task. The purpose of the resizer task is to contract or expand the cache capacity, based on the remaining three element values. When the resizer task executes, it checks the current period between cache misses, and if the period is less than the min-cache-miss-period value, the cache is expanded up to the max-capacity value, using cache-load-factor. If instead the period between cache misses is greater than the max-cache-miss-period value, the cache is contracted, using cache-load-factor.

  • max-cache-miss-period Specifies the time period, in seconds, in which a cache miss should signal that the cache capacity be contracted. It is equivalent to the minimum miss rate that will be tolerated before the cache is contracted.

  • min-cache-miss-period Specifies the time period, in seconds, in which a cache miss should signal that the cache capacity be expanded. It is equivalent to the maximum miss rate that will be tolerated before the cache is expanded.

  • cache-load-factor Specifies the factor by which the cache capacity is contracted and expanded. The factor should be less than 1. When the cache is contracted, the capacity is reduced so that the current ratio of beans to cache capacity is equal to the cache-load-factor value. When the cache is expanded, the new capacity is determined as current-capacity * 1/cache-load-factor. The actual expansion factor may be as high as 2, based on an internal algorithm based on the number of cache misses. The higher the cache miss rate, the closer the true expansion factor will be to 2.

LRUStatefulContextCachePolicy also supports these child elements:

  • remover-period Specifies the period, in seconds, between runs of the remover task. The remover task removes passivated beans that have not been accessed in more than max-bean-life seconds. This task prevents stateful session beans that were not removed by users from filling up the passivation store.

  • max-bean-life Specifies the maximum period of inactivity, in seconds, that a bean can exist before being removed from the passivation store.

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 Element

The 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 Element

The 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 Element

The 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:

  • org.jboss.ejb.plugins.lock.QueuedPessimisticEJBLock This implementation holds threads awaiting the transactional lock to be freed in a fair FIFO queue. Nontransactional threads are also put into this waiting queue as well. This class pops the next waiting transaction from the queue and notifies only those waiting threads that are associated with that transaction. QueuedPessimisticEJBLock is the current default used by the standard configurations.

  • org.jboss.ejb.plugins.lock.QueuedPessimisticEJBLockNoADE This behaves the same as the QueuedPessimisticEJBLock except that deadlock detection is disabled.

  • org.jboss.ejb.plugins.lock.SimpleReadWriteEJBLock This lock allows multiple read locks concurrently. Once a writer has requested the lock, future read-lock requests whose transactions do not already have the read lock will block until all writers are done; then all the waiting readers will concurrently go (depending on the reentrant setting/methodLock). A reader who promotes gets first crack at the write lock, ahead of other waiting writers. If there is already a reader that is promoting, an inconsistent read exception is thrown. Of course, writers have to wait for all read-locks to release before taking the write lock.

  • org.jboss.ejb.plugins.lock.NoLock This anti-locking policy is used with the instance-per-transaction container configurations.

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 Elements

The commit-option value specifies the EJB entity bean persistent storage commit option. It must be one of the following:

  • A The container caches the bean's state between transactions. This option assumes that the container is the only user accessing the persistent store. This assumption allows the container to synchronize the in-memory state from the persistent storage only when absolutely necessary. This occurs before the first business method executes on a found bean or after the bean is passivated and reactivated to serve another business method. This behavior is independent of whether the business method executes inside a transaction context.

  • B The container caches the bean state between transactions. However, unlike with option A, the container does not assume exclusive access to the persistent store. Therefore, the container synchronizes the in-memory state at the beginning of each transaction. Thus, business methods executing in a transaction context don't see much benefit from the container caching the bean, whereas business methods executing outside a transaction context (with transaction attributes Never, NotSupported, or Supports) access the cached (and potentially invalid) state of the bean.

  • C The container does not cache bean instances. The in-memory state must be synchronized on every transaction start. For business methods executing outside a transaction, the synchronization is still performed, but ejb-Load executes in the same transaction context as that of the caller.

  • D This is a JBoss-specific commit option that is not described in the EJB specification. It is a lazy read scheme where bean state is cached between transactions as with option A, but the state is periodically resynchronized with that of the persistent store. The default time between reloads is 30 seconds, but you can configure it by using the optiond-refresh-rate element.

The security-domain Element

The 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 Element

The 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:

  • partition-name The partition-name element indicates where to find the org.jboss.ha.framework.interfaces.HAPartition interface to be used by the container to exchange clustering information. This is not the full JNDI name under which HAPartition is bound. Rather, it should correspond to the PartitionName attribute of the ClusterPartitionMBean service that is managing the desired cluster. The actual JNDI name of the HAPartition binding will be formed by appending /HASessionState/ to the partition-name value. The default value is DefaultPartition.

  • home-load-balance-policy The home-load-balance-policy element indicates the Java classname to be used to load balance calls made on the home proxy. The class must implement the org.jboss.ha.framework.interface.LoadBalancePolicy interface. The default policy is org.jboss.ha.framework.interfaces.RoundRobin.

  • bean-load-balance-policy The bean-load-balance-policy element indicates the Java classname to be used to load balance calls in the bean proxy. The class must implement the org.jboss.ha.framework.interface.LoadBalancePolicy interface. For entity beans and stateful session beans, the default is org.jboss.ha.framework. interfaces.FirstAvailable. For stateless session beans, it is org.jboss.ha.framework.interfaces.RoundRobin.

  • session-state-manager-jndi-name The session-state-manager-jndi-name element indicates the name of the org.jboss.ha.framework.interfaces.HASessionState to be used by the container as a back end for state session management in the cluster. Unlike the partition-name element, this is a JNDI name under which the HASessionState implementation is bound. The default location used is /HASessionState/Default.

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 Framework

The 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:

  • org.jboss.ejb.EntityContainer Handles javax.ejb.EntityBean types.

  • org.jboss.ejb.StatelessSessionContainer Handles stateless javax.ejb.SessionBean types.

  • org.jboss.ejb.StatefulSessionContainer Handles stateful javax.ejb.SessionBean types.

  • org.jboss.ejb.MessageDrivenContainer Handles javax.ejb.MessageDrivenBean types.

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 Interface

The 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 Interface
 public 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 Interface

The 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 Interface
 import 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 Interface

An 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 Interface
 public 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 Interface

The 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 Interface
 public 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 Interface

The EntityPersistenceManager interface is responsible for the persistence of entity beans. This includes the following:

  • Creating an EJB instance in storage

  • Loading the state of a given primary key into an EJB instance

  • Storing the state of a given EJB instance

  • Removing an EJB instance from storage

  • Activating the state of an EJB instance

  • Passivating the state of an EJB instance

Listing 5.8 shows the EntityPersistenceManager interface.

Listing 5.8. The org.jboss.ejb.EntityPersistenceManager Interface
 public 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 Interface

As 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 Interface

The StatefulSessionPersistenceManager interface is responsible for the persistence of stateful session beans. This includes the following:

  • Creating stateful sessions in storage

  • Activating stateful sessions from storage

  • Passivating stateful sessions to storage

  • Removing stateful sessions from storage

The StatefulSessionPersistenceManager interface is shown in Listing 5.10.

Listing 5.10. The org.jboss.ejb.StatefulSessionPersistenceManager Interface
 public 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.



JBoss 4. 0(c) The Official Guide
JBoss 4.0 - The Official Guide
ISBN: B003D7JU58
EAN: N/A
Year: 2006
Pages: 137

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net