3.2.11. EJB 2.x Changes

3.2.11.1. Update Applications That Use EJB 2.x

JBoss EAP 6 was built on open standards and is compliant with the Java Enterprise Edition 6 specification. While the application server provides support for EJB 2.x, it may no longer support features which go beyond the specification. Keep in mind that the Java EE 7 specification has marked EJB 2.x as optional, so it is strongly recommended that you rewrite your application code to the EJB 3.x specification.
If you still want to migrate your EJB 2.x code, in most cases you will need to make some modifications to run in JBoss EAP 6. This topic describes some of the changes you may need to run EJB 2.x on JBoss EAP 6.
Configuration Changes Required to Run EJB 2.x on JBoss EAP 6

Start the Server With the Full Profile
EJB 2.x Container Managed Persistence (CMP) beans require the Java Enterprise Edition 6 Full Profile. This profile contains configuration elements that are needed to run CMP EJBs.
This configuration profile contains the org.jboss.as.cmp extension module:
<extensions>
    ...
    <extension module="org.jboss.as.cmp"/>
    ...
</extensions>
It also contains the cmp subsystem:
<profiles>
    ...
    <subsystem xmlns="urn:jboss:domain:cmp:1.1"/>
    ...
</profiles>
.
To start a JBoss EAP 6 standalone server with the full profile, pass the -c standalone-full.xml or -c standalone-full-ha.xml argument on the command line when you start the server.
Container Configuration Is No Longer Supported
In previous versions of JBoss EAP, it was possible to configure different container for CMP entity and other beans and use it by setting references inside the jboss.xml application deployment descriptor file. For example, there were different configurations for SLSB to session beans in general.
In JBoss EAP 6.x, it is possible to use EJB 2 Entity beans with a standard container. However, the different container configurations are no longer supported. The recommended approach is to migrate the EJB2 Stateful Session Beans (SFSB), Stateless Session Beans (SLSB), Message Driven Beans (MDB) to EJB 3, and for the Container-Managed Persistence (CMP) and Bean-Managed Persistence (BMP) Entity Beans to use the Java Persistence API (JPA) according to the EJB 3 specification.
The default container configuration in JBoss EAP 6 contains several changes for EJB 2 CMP beans:
  • Pessimistic locking is active by default. This can result in deadlocks.
  • The deadLock detection code that was in the CMP layer in JBoss EAP 5.x is no longer in JBoss EAP 6.
In JBoss EAP 5.x, it was also possible to customize caching, pooling, commit-options, and the interceptor stack. In JBoss EAP 6, this is no longer possible. There is only one implementation, which is similar to the Instance Per Transaction policy with commit-option C. If you migrate an application that uses the cmp2.x jdbc2 pm entity bean container configuration, which uses CMP2.x compatible JDBC based persistence manager, there will be a performance impact. This container was optimized for performance. It is recommended that you migrate these entities to EJB 3 before migrating the application.
Server Side Interceptor Configuration
JBoss EAP 6 supports the standard Java EE Interceptor using the @Interceptors and @AroundInvoke annotations. However, this does not allow manipulation outside the Security or Transaction.
In previous versions of JBoss EAP, it was possible to modify the interceptor stack to have custom Interceptors for each EJB invocation. This was often used to implement customized security or retry mechanisms before security checks or transaction checks or creation. JBoss EAP 6.1 introduced container interceptors to provide similar functionality. For more information about container interceptors, see the chapter entitled Container Interceptors in the Development Guide for JBoss EAP.
Another approach to provide more control before, during, or after the commit phase of a transaction while keeping with the Java EE specification is to use the Transaction Synchronization Registry to add a listener.
The resource can be retrieved using one of the following methods:
  • Use the InitialContext
    TransactionSynchronizationRegistry tsr = (TransactionSynchronizationRegistry) 
    		new InitialContext().lookup("java:jboss/TransactionSynchronizationRegistry");
    tsr.registerInterposedSynchronization(new MyTxCallback());
    
  • Use Injection
    @Resource(mappedName = "java:comp/TransactionSynchronizationRegistry")
    TransactionSynchronizationRegistry tsr;
    ...
    tsr.registerInterposedSynchronization(new MyTxCallback());
    
The callback routine must implement the javax.transaction.Synchronization Interface. Use the beforeCompletion{} method to perform any checks before the transaction is committed or rolled back. If a RuntimeException is thrown from this method, the transaction is rolled back and the client is informed with a EJBTransactionRolledbackException. In case of an XA-Transaction, all resources will be rolled back according to the XA contract. It is also possible for enable business logic to depend on the transaction state using the afterCompletion(int txStatus) method. If a RuntimeException is thrown from this method, the transaction remains in the former state, either committed or rolled-back, and the client is not informed. Only the transaction manager shows a warning within the server log files.
Server Side Configuration for Client Side Interceptors
In previous versions of JBoss EAP, it was possible to configure the client interceptors within the server configuration and provide only the classes with the client API.
In JBoss EAP 6, this is no longer possible because the client Proxy is no longer created on the server side and transmitted to the client after the lookup. The proxy is now generated on the client side. This optimization avoids a server invocation for the lookup and class uploads,
Entity Bean Pool Configuration
Entity bean pool configuration is not recommended in JBoss EAP 6. Because it is limited to configuration of the <strict-max-pool> element, deadlocks and other issues can occur if the pool is too small to load all entities in the result set. Entity beans do not have large lifecycle methods during initialization, so creating the instance and surrounding container is no slower than when using a pooled entity bean instance.
Replace the jboss.xml Deployment Descriptor File
The jboss-ejb3.xml deployment descriptor replaces the jboss.xml deployment descriptor file. This file is used to override and add to the features provided by the Java Enterprise Edition (EE) defined ejb-jar.xml deployment descriptor. The new file is incompatible with jboss.xml, and the jboss.xml is now ignored in deployments.
For example, in previous releases of JBoss EAP, if you defined a <resource-ref> in the ejb-jar.xml file, you needed a corresponding resource definition for the JNDI name in the jboss.xml file. XDoclet automatically generated both of these deployment descriptor files. In JBoss EAP 6, the JNDI mapping information is now defined in the jboss-ejb3.xml file. Assume the datasource is defined in the Java source code as follows.
DataSource ds1 = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/Resource1");
DataSource ds2 = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/Resource2");
The ejb-jar.xml defines the following resource references.
<resource-ref >
    <res-ref-name>jdbc/Resource1</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>
<resource-ref >
    <res-ref-name>java:comp/env/jdbc/Resource2</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>
The jboss-ejb3.jxml file maps the JNDI names to the references using the following XML syntax.
<resource-ref>
    <res-ref-name>jdbc/Resource1</res-ref-name>
    <jndi-name>java:jboss/datasources/ExampleDS</jndi-name>
</resource-ref>
<resource-ref>
    <res-ref-name>java:comp/env/jdbc/Resource2</res-ref-name>
    <jndi-name>java:jboss/datasources/ExampleDS</jndi-name>
</resource-ref>
Some of the configuration options that were available in the JBoss EAP 5.x jboss.xml file were not implemented in JBoss EAP 6. The following list describes some of the commonly used attributes in the jboss.xml file and whether there is an alternate way to achieve them in JBoss EAP 6.
  • The method-attribute element was used to configure individual entity and session beans methods.
    • The read-only and idempotent configuration options were not ported to JBoss EAP 6.
    • The transaction-timeout option is now configured in the jboss-ejb3.xml file.
  • The missing-method-permission-exclude-mode attribute changed the behavior of methods without implementing explicit security metadata on a secured bean. In JBoss EAP 6, the absence of a @RolesAllowed annotation is currently treated in a similar manner to the @PermitAll
DataSource Type Mapping Configuration
In previous versions of JBoss EAP, it was possible to configure the datasource type-mapping within the *-ds.xml datasource deployment configuration file.
In JBoss EAP 6, this must now be done in the jbosscmp-jdbc.xml deployment descriptor file.
<defaults>  
    <datasource-mapping>mySQL</datasource-mapping>  
    <create-table>true</create-table>  
    ....  
</defaults>
In previous versions of JBoss EAP, customized mapping was done in the standardjbosscmp-jdbc.xml file. This file is no longer available and mapping is now done in the jbosscmp-jdbc.xml deployment descriptor file.
Additional Container-Managed Persistence (CMP) and Container-Managed Relationship (CMR) Changes

Container Managed Relationship (CMR) Iterator and Collection Changes
In previous releases of JBoss EAP, it was possible for some containers, for example the cmp2.x jdbc2 pm container, to iterate CMR collections and remove or add relations. Because container configuration is not supported, this is no longer possible in JBoss EAP 6. For information about how to achieve this same functionality in the application code, see EJB2.1 Finder for CMP entities with relations (CMR) returns duplicates in EAP6 in the Support Knowledgebase Solutions section of the Customer Portal .
Container Managed Relationship (CMR) Duplicate Entries for Finders
In previous versions of JBoss EAP, it was possible to select different CMP containers which used different persistence strategies. The cmp2.x jdbc2 pm container in JBoss EAP 5.x used optimized SQL-92 to generate optimized LEFT OUTER JOIN syntax for finders. Because JBoss EAP 6.x only supports the standard container for CMP and CMR, the implementation does not contain these optimizations. The finder should include the keyword DISTINCT in the SELECT statement to avoid cartesian product in the result set. For more information , see EJB2.1 Finder for CMP entities with relations (CMR) returns duplicates in EAP6 in the Support Knowledgebase Solutions section of the Customer Portal.
Cascade Delete Default Change for CMP Entity Beans
The cascade delete default value has changed to false. This can result in delete failures in JBoss EAP 6. If entity relations are marked as cascade-delete, you must explicitly set the batch-cascade-delete to true in the jbosscmp-jdbc.xml file. For more information , see cascade delete fail for EJB2 CMP Entities after migration to EAP6 in the Support Knowledgebase Solutions section of the Customer Portal.
CMP Customized Mappers for Custom Fields
If you used customer mapper classes such as JDBCParameterSetter, JDBCResultSetReader and Mapper in your JBoss EAP 5.x application, you may see java.lang.ClassNotFoundException when you deploy your application to JBoss EAP 6. This is because the package names for the interfaces were changed from org.jboss.ejb.plugins.cmp.jdbc.Mapper to org.jboss.as.cmp.jdbc.Mapper. For more information , see How to use Field mapping for custom classes in an EJB2 CMP application in EAP6 in the Support Knowledgebase Solutions section of the Customer Portal.
Generation of Primary Keys Using entity-commands
If your JBoss EAP 5 application uses entity-commands to generate primary keys, for example Sequence or Auto-increment, you may see a ClassNotFoundException for the JDBCOracleSequenceCreateCommand class when you migrate your application to JBoss EAP 6. This is because the class package was changed from org.jboss.ejb.plugins.cmp.jdbc to org.jboss.as.cmp.jdbc.keygen. If you use this class in your JBoss EAP 6 application, you must also add a dependency on the EAP_HOME/modules/system/layers/base/org/jboss/as/cmp module.
Application Changes

Modify the Code to Use the New JNDI Namespace Rules.
As with EJB 3.0, you must use the full JNDI prefix with EJB 2.x. For more information on the new JNDI namespace rules and code examples, see Section 3.1.8.1, “Update Application JNDI Namespace Names”.
Examples showing how to update JNDI namespaces from previous releases can be found here: Section 3.1.8.5, “Examples of JNDI Namespaces in Previous Releases and How They are Specified in JBoss EAP 6”.
Modify the jboss-web.xml File Descriptor
Modify the <jndi-name> for each <ejb-ref> to use the new JNDI fully qualified lookup format.
Use XDoclet to Map JNDI Name of Internal Local Interfaces
With EJB 2, it was very common to use the Locator pattern to look up Beans. If you used this pattern in your application, rather than modify application code, you can use XDoclet to generate a map for the new JNDI names.
A typical XDoclet annotation looks like this:
@ejb.bean name="UserAttribute" display-name="UserAttribute" local-jndi-name="ejb21/UserAttributeEntity" view-type="local" type="CMP" cmp-version="2.x" primkey-field="id"
The JNDI name ejb21/UserAttributeEntity in the above example is no longer valid in JBoss EAP 6. You can map this name to a valid JNDI name using the naming subsystem in the server configuration and a patch for XDoclet.
You can create customized mappers, as noted in the paragraph above entitled CMP Customized Mappers for Custom Fields or you can modify the code as described in the following procedure.

Procedure 3.24. Change the XDoclet Generated Code and Use the Naming Subsystem

  1. Extract the XDoclet lookup.xdt template located in the ejb-module.jar and modify the lookup() in the lookupHome as follows:
    private static Object lookupHome(java.util.Hashtable environment, String jndiName, Class narrowTo) throws javax.naming.NamingException {  
        // Obtain initial context  
        javax.naming.InitialContext initialContext = new javax.naming.InitialContext(environment);  
        try { 
            // Replace the existing lookup      
            // Object objRef = initialContext.lookup(jndiName);  
            // This is the new mapped lookup
            Object objRef;  
            try {  
                // try JBoss EAP mapping  
                objRef = initialContext.lookup("global/"+jndiName);  
            } catch(java.lang.Exception e) {  
                objRef = initialContext.lookup(jndiName);  
            }  
            // only narrow if necessary  
            if (java.rmi.Remote.class.isAssignableFrom(narrowTo))  
                return javax.rmi.PortableRemoteObject.narrow(objRef, narrowTo); 
            else  
                return objRef;  
        } finally {  
            initialContext.close();  
        }  
    }
  2. Run Ant, setting the template attribute to use the modified lookup.xdt for the ejbdoclet task.
  3. Modify the naming subsystem in the server configuration file to map the old JNDI name to the new valid JNDI name.
    <subsystem xmlns="urn:jboss:domain:naming:1.2">  
        <bindings>  
            <lookup name="java:global/ejb21/UserAttributeEntity" lookup="java:global/ejb2CMP/ejb/UserAttribute!de.wfink.ejb21.cmp.cmr.UserAttributeLocalHome"/>  
        </bindings>  
        <remote-naming/>  
    </subsystem>
Summary of Obsolete Files

The following files are no longer supported in JBoss EAP 6.

jboss.xml
The jboss.xml deployment descriptor file is no longer supported and ignored if included in the deployed archive.
standardjbosscmp-jdbc.xml
The standardjbosscmp-jdbc.xml configuration file is no longer supported. This configuration information is now included in the org.jboss.as.cmp module and it is no longer customizable.
standardjboss.xml
The standardjboss.xml configuration file is no longer supported. This configuration information is now included in the standalone.xml file when running a standalone server or the domain.xml file when running in a managed domain..