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 thecmp
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 theInstance Per Transaction
policy withcommit-option
C
. If you migrate an application that uses thecmp2.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:The callback routine must implement the- 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());
javax.transaction.Synchronization
Interface. Use thebeforeCompletion{}
method to perform any checks before the transaction is committed or rolled back. If aRuntimeException
is thrown from this method, the transaction is rolled back and the client is informed with aEJBTransactionRolledbackException
. 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 theafterCompletion(int txStatus)
method. If aRuntimeException
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 thejboss.xml
deployment descriptor file. This file is used to override and add to the features provided by the Java Enterprise Edition (EE) definedejb-jar.xml
deployment descriptor. The new file is incompatible withjboss.xml
, and thejboss.xml
is now ignored in deployments.For example, in previous releases of JBoss EAP, if you defined a<resource-ref>
in theejb-jar.xml
file, you needed a corresponding resource definition for the JNDI name in thejboss.xml
file. XDoclet automatically generated both of these deployment descriptor files. In JBoss EAP 6, the JNDI mapping information is now defined in thejboss-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");
Theejb-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>
Thejboss-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.xjboss.xml
file were not implemented in JBoss EAP 6. The following list describes some of the commonly used attributes in thejboss.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
andidempotent
configuration options were not ported to JBoss EAP 6. - The
transaction-timeout
option is now configured in thejboss-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 thejbosscmp-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 thestandardjbosscmp-jdbc.xml
file. This file is no longer available and mapping is now done in thejbosscmp-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 optimizedSQL-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 keywordDISTINCT
in theSELECT
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 ascascade-delete
, you must explicitly set thebatch-cascade-delete
totrue
in thejbosscmp-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
andMapper
in your JBoss EAP 5.x application, you may seejava.lang.ClassNotFoundException
when you deploy your application to JBoss EAP 6. This is because the package names for the interfaces were changed fromorg.jboss.ejb.plugins.cmp.jdbc.Mapper
toorg.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 exampleSequence
orAuto-increment
, you may see aClassNotFoundException
for theJDBCOracleSequenceCreateCommand
class when you migrate your application to JBoss EAP 6. This is because the class package was changed fromorg.jboss.ejb.plugins.cmp.jdbc
toorg.jboss.as.cmp.jdbc.keygen
. If you use this class in your JBoss EAP 6 application, you must also add a dependency on theEAP_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 nameejb21/UserAttributeEntity
in the above example is no longer valid in JBoss EAP 6. You can map this name to a valid JNDI name using thenaming
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
- Extract the XDoclet
lookup.xdt
template located in theejb-module.jar
and modify thelookup()
in thelookupHome
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(); } }
- Run Ant, setting the template attribute to use the modified
lookup.xdt
for theejbdoclet
task. - 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 theorg.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 thestandalone.xml
file when running a standalone server or thedomain.xml
file when running in a managed domain..