3.2.11. Cambios de EJB 2.x
3.2.11.1. Actualización de aplicaciones que utilizan EJB 2.x
JBoss EAP 6 se construyó sobre estándares abiertos y cumple con los requerimientos de la especificación de la edición empresarial de Java 6. Mientras que el servidor de aplicaciones proporciona soporte para EJB 2.x, puede que ya no soporte funcionalidades que van más allá de la especificación. Tenga en mente que la especificación Java EE 7 ha marcado EJB 2.x como opcional así que se le recomienda con mucho énfasis que reescriba el código de su aplicación en la especificación EJB 3.x.
Si todavía quiere migrar su código EJB 2.x en la mayoría de los casos necesitará realizar algunas modificaciones para ejecutar en JBoss EAP 6. Este tema describe algunos de los cambios que puede necesitar para ejecutar EJB 2.x en JBoss EAP 6.
Cambios en la configuración requeridos para ejecutar EJB 2.x en JBoss EAP 6
- Iniciar el servidor con el perfil completo
- Los beans CMP (del inglés Container Managed Persistence) EJB 2.x requieren el perfil completo de la edición empresarial de Java 6. Este perfil contiene elementos de configuración que se necesitan para ejecutar CMP EJBs.Este perfil de configuración contiene el módulo de extensión
org.jboss.as.cmp
:<extensions> ... <extension module="org.jboss.as.cmp"/> ... </extensions>
También contiene el subsistemacmp
:<profiles> ... <subsystem xmlns="urn:jboss:domain:cmp:1.1"/> ... </profiles>
.Para iniciar un servidor autónomo JBoss EAP 6 con el perfil completo pase el argumento-c standalone-full.xml
or-c standalone-full-ha.xml
en la línea de comandos cuando inicie el servidor. - La configuración de contenedor ya no se soporta
- En versiones anteriores de JBoss EAP era posible configurar un contenedor diferente para entidades CMP y otros beans y utilizarlo estableciendo referencias dentro del archivo descriptor de implementación de la aplicación
jboss.xml
. Por ejemplo, había diferentes configuraciones para SLSB para poner los beans en sesiones en general.En JBoss EAP 6.x, es posible utilizar beans de entidad EJB 2 con un contenedor estándar. Sin embargo, ya no se soportan las diferentes configuraciones del contenedor. El enfoque recomendado es migrar los beans de sesión con estado EJB2 (SFSB del inglés Stateful Session Beans), los beans de sesión sin estado (SLSB ddel inglés Stateless Session Beans), beans dirigidos por mensajes (MDB del inglés Message Driven Beans) a EJB 3 y para la persistencia administrada por el contenedor (CMP del inglés Container-Managed Persistence) y los beans de entidad de persistencia administrada por beans (BMP del inglés Bean-Managed Persistence) utilizar la API de persistencia Java (JPA del inglés Java Persistence API) de acuerdo con la especificación EJB 3.La configuración predeterminada del contenedor en JBoss EAP 6 contiene varios cambios para los beans EJB 2 CMP:- El bloqueo pesimista está activado por defecto. Esto puede generar puntos muertos.
- El código de detección de deadLock que se encontraba en la capa CMP en JBoss EAP 5.x ya no está en JBoss EAP 6.
En JBoss EAP 5.x, también era posible el personalizar el caché, el agrupamiento,commit-options
y la pila de interceptores. En JBoss EAP 6, esto ya no es posible. Hay solo una implementación, la cual es similar a la políticaInstance Per Transaction
concommit-option
C
. Si migra una aplicación que usa la configuración del contenedor del bean de entidadescmp2.x jdbc2 pm
, el cual usa un administrador de persistencia basado en JDBC compatible con CMP2.x , entonces tendrá impacto en el rendimiento. Este contenedor se optimizó para rendimiento. Se recomienda que migre estas entidades a EJB 3 antes de migrar la aplicación. - Configuración del interceptor del lado del servidor
- JBoss EAP 6 soporta el
Interceptor
Java EE estándar utilizando las anotaciones@Interceptors
y@AroundInvoke
. Sin embargo, esto no permite la manipulación por fuera de la transacción o la seguridad.En versiones anteriores de JBoss EAP era posible modificar la pila de interceptores para tener interceptores personalizados para cada invocación EJB. Esto se utilizaba con frecuencia para implementar seguridad personalizada o mecanismos de reintento antes de chequeos de seguridad o chequeos de transacciones o creación. JBoss EAP 6.1 introdujo interceptores de contenedor para brindar una funcionalidad similar. Para mayor información sobre interceptores de contenedor consulte el capítulo titulado Interceptores de contenedor en la Guía de desarrollo para JBoss EAP.Otro enfoque para brindar más control antes, durante o después de la fase de guardado de una transacción siguiendo la especificación Java EE es utilizar el registro de sincronización de transacciones para agregar un escucha.El recurso se puede recuperar usando uno de los siguientes métodos:La rutina callback debe implementar la interfaz- Use el
InitialContext
TransactionSynchronizationRegistry tsr = (TransactionSynchronizationRegistry) new InitialContext().lookup("java:jboss/TransactionSynchronizationRegistry"); tsr.registerInterposedSynchronization(new MyTxCallback());
- Use inyección
@Resource(mappedName = "java:comp/TransactionSynchronizationRegistry") TransactionSynchronizationRegistry tsr; ... tsr.registerInterposedSynchronization(new MyTxCallback());
javax.transaction.Synchronization
. Use el métodobeforeCompletion{}
para realizar cualquier chequeo antes de que la transacción se guarde o se deshaga. Si este método presenta unaRuntimeException
entonces la transacción se deshace y se le informa al cliente con unaEJBTransactionRolledbackException
. En el caso de una XA-Transaction, todos los recursos se desharán de acuerdo con el contrato XA. También es posible para la lógica empresarial habilitada el depender del estado de la transacción utilizando el métodoafterCompletion(int txStatus)
. Si este método presenta unaRuntimeException
entonces la transacción permanece en el estado anterior ya sea con lo cambios guardados o deshechos y no se le informa al cliente. Solo el administrador de transacciones muestra una advertencia dentro del los archivos de registro del servidor. - Configuración del lado del servidor para interceptores del lado del cliente
- En versiones anteriores de JBoss EAP era posible configurar los interceptores clientes dentro de la configuración del servidor y proporcionar solo las clases con el API cliente.En JBoss EAP 6, esto ya no es posible ya que el Proxy cliente ya no se crea en el lado del servidor ni se transmite al cliente después de la búsqueda. Ahora el proxy se genera del lado del cliente. Esta optimización evita una invocación del servidor para la búsqueda y carga de clases,
- Configuración del pool de beans de entidades
- En JBoss EAP 6 no se recomienda la configuración del pool de beans de entidades. Ya que se limita a la configuración del elemento
<strict-max-pool>
pueden tener lugar puntos muertos y otros problemas si el pool es demasiado pequeño para cargar todas las entidades en el grupo de resultados. Los beans de entidad no tienen métodos largos del ciclo de vida durante la inicialización así que el crear la y el contenedor que lo rodea no es más lento que cuando se utiliza una instancia de bean de entidad en pool. - Reemplace el archivo descriptor de implementación jboss.xml
- El descriptor de implementación
jboss-ejb3.xml
reemplaza el archivo descriptor de implementaciónjboss.xml
. Este archivo se utiliza para sobreescribir y agregar a las funcionalidades proporcionadas por el descriptor de implementaciónejb-jar.xml
de la edición empresarial Java (EE). El nuevo archivo es incompatible conjboss.xml
y eljboss.xml
ahora se ignora en las implementaciones.Por ejemplo, en lanzamientos anteriores de JBoss EAP, si definía una<resource-ref>
en el archivoejb-jar.xml
necesitaba una definición de recursos correspondiente para el nombre JNDI en el archivojboss.xml
. XDoclet automáticamente generaba ambos archivos descriptores de implementación. En JBoss EAP 6, la información de mapeo JNDI ahora se define en el archivojboss-ejb3.xml
. Asuma que la fuente de datos se define en el código fuente Java así:DataSource ds1 = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/Resource1"); DataSource ds2 = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/Resource2");
Elejb-jar.xml
define las siguientes referencias de recursos.<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>
El archivojboss-ejb3.jxml
mapea los nombres JNDI a las referencias usando la siguiente sintaxis XML.<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>
Algunas de las opciones de configuración que estaban disponibles en el archivojboss.xml
JBoss EAP 5.x no se implementaron en JBoss EAP 6. La siguiente lista describe algunos de los atributos utilizados comúnmente en el archivojboss.xml
y si hay una manera opcional de alcanzarlos en JBoss EAP 6.- El elemento
method-attribute
se utilizaba para configurar métodos de beans de sesión y entidades individuales.- Las opciones de configuración
read-only
yidempotent
no se llevaron a JBoss EAP 6. - La opción
transaction-timeout
ahora se configura en el archivojboss-ejb3.xml
.
- El atributo
missing-method-permission-exclude-mode
cambió el comportamiento de los métodos sin implementar metadatos de seguridad explícitos en un bean asegurado. En JBoss EAP 6, la ausencia de una anotación@RolesAllowed
se trata de manera similar a@PermitAll
- Configuración de mapeo del tipo de fuente de datos
- En versiones anteriores de JBoss EAP, era posible configurar el mapeo del tipo de fuente de datos dentro del archivo de configuración de la implementación de la fuente de datos
*-ds.xml
.En JBoss EAP 6, esto se debe hacer ahora en el archivo descriptor de implementaciónjbosscmp-jdbc.xml
.<defaults> <datasource-mapping>mySQL</datasource-mapping> <create-table>true</create-table> .... </defaults>
En versiones anteriores de JBoss EAP, el mapeo personalizado se realizaba en el archivostandardjbosscmp-jdbc.xml
. Este archivo ya no está disponible y el mapeo ahora se realiza en el archivo descriptor de implementaciónjbosscmp-jdbc.xml
.
Cambios adicionales a la persistencia administrada por el contenedor y las relaciones administradas por el contenedor
- Cambios en el iterador de relaciones administradas por el contenedor y colecciones
- En lanzamientos anteriores de JBoss EAP, era posible para algunos contenedores, por ejemplo el contenedor
cmp2.x jdbc2 pm
el iterar colecciones CMR (del inglés Container Managed Relationship) y borrar o agregar relaciones. Debido a que la configuración del contenedor no se soporta, esto ya no es posible en JBoss EAP 6. Para obtener mayor información sobre cómo lograr esta misma funcionalidad en el código de la aplicación, consulte EJB2.1 Localizador de entidades CMP con relaciones (CMR) retorna duplicados en EAP6 en la sección de Soluciones de la base de conocimiento de soporte del Portal de clientes. - Entradas duplicadas de relaciones administradas por el contenedor para localizadores
- En versiones anteriores de JBoss EAP, era posible seleccionar diferentes contenedores CMP que utilizaban diferentes estrategias de persistencia. El contenedor
cmp2.x jdbc2 pm
en JBoss EAP 5.x utilizabaSQL-92
optimizado para generar sintaxis LEFT OUTER JOIN optimizada para localizadores. Debido a que JBoss EAP 6.x solo soporta el contenedor estándar para CMP y CMR, la implementación no contiene estas optimizaciones. El localizador debe incluir la palabra claveDISTINCT
en la declaraciónSELECT
para evitar un producto cartesiano en el grupo de resultados. Para obtener mayor información consulte EJB2.1 Localizador para entidades CMP con relaciones (CMR) retorna duplicados en EAP6 en la sección de Soluciones de la base de conocimiento de soporte del Portal de clientes. - Cambio en el borrado predeterminado en cascada para beans de entidad CMP
- El valor predeterminado del borrado en cascada cambió a
false
. Esto puede generar fallos de borrado en JBoss EAP 6. Si relaciones de entidades se marcan comocascade-delete
debe establecer explícitamente elbatch-cascade-delete
comotrue
en el archivojbosscmp-jdbc.xml
. Para obtener mayor información consulte fallo en el borrado en cascada para entidades EJB2 CMP después de la migración a EAP6 en la sección de Soluciones de la base de conocimiento de soporte del Portal de clientes. - Mapeos personalizados CMP para campos personalizados
- Si utilizó las clases de mapeo de clientes tal como
JDBCParameterSetter
,JDBCResultSetReader
yMapper
en su aplicación JBoss EAP 5.x, es posible que vea lajava.lang.ClassNotFoundException
cuando implementa su aplicación en JBoss EAP 6. Esto se debe a que los nombres de paquetes para las interfaces se cambiaron deorg.jboss.ejb.plugins.cmp.jdbc.Mapper
aorg.jboss.as.cmp.jdbc.Mapper
. Para obtener mayor información consulte Cómo utilizar el mapeo de campos para las clases personalizadas en una aplicación EJB2 CMP en EAP6 en la sección de Soluciones de la base de conocimiento de soporte del Portal de clientes. - Generación de llaves primarias utilizando comandos de entidad
- Si su aplicación JBoss EAP 5 usa
entity-commands
para generar llaves primarias, por ejemploSequence
oAuto-increment
es posible que vea unaClassNotFoundException
para la claseJDBCOracleSequenceCreateCommand
cuando migra su aplicación a JBoss EAP 6. Esto se debe a que el paquete clase cambió deorg.jboss.ejb.plugins.cmp.jdbc
aorg.jboss.as.cmp.jdbc.keygen
. Si utiliza esta clase en su aplicación JBoss EAP 6 también debe agregar una dependencia en el móduloEAP_HOME/modules/system/layers/base/org/jboss/as/cmp
.
Cambios en la aplicación
- Modifique el código para utilizar las nuevas reglas de espacio de nombres JNDI.
- Así como con EJB 3.0, tiene que utilizar el prefijo completo JNDI con EJB 2.x. Para mayor información sobre las nuevas reglas del espacio de nombre JNDI y ejemplos del código consulte Sección 3.1.8.1, “Actualización de los nombres de espacios de nombres JNDI de la aplicación”.Puede encontrar los ejemplos sobre cómo actualizar los espacios de nombres JNDI de lanzamientos anteriores aquí: Sección 3.1.8.5, “Ejemplos de espacios de nombres JNDI en lanzamientos anteriores y la manera en que se especifican en JBoss EAP 6”.
- Modifique el descriptor de archivos
jboss-web.xml
- Modifique el
<jndi-name>
para cada<ejb-ref>
para utilizar el nuevo formato de búsqueda completamente calificado JNDI. - Use XDoclet para mapear el nombre JNDI Name de interfaces locales internas
- Con EJB 2 era muy común el utilizar el patrón
Locator
para buscar Beans. Si usted utilizaba este patrón en su aplicación, en lugar de modificar el código de la aplicación code, puede utilizar XDoclet para generar un mapa para los nuevos nombres JNDI.Una anotación XDoclet típica se ve así:@ejb.bean name="UserAttribute" display-name="UserAttribute" local-jndi-name="ejb21/UserAttributeEntity" view-type="local" type="CMP" cmp-version="2.x" primkey-field="id"
El nombre JNDIejb21/UserAttributeEntity
en el ejemplo anterior ya no es válido en JBoss EAP 6. Puede mapear este nombre a un nombre JNDI válido utilizando el subsistemanaming
en la configuración del servidor y un parche para XDoclet.Puede crear mapeos personalizados tal como se anota en el párrafo anterior titulado Mapeos personalizados CMP para campos personalizados o puede modificar el código tal como se describe en el siguiente procedimiento.Procedimiento 3.24. Cambie el código generado XDoclet y use el subsistema de nombrado
- Extraiga la plantilla XDoclet
lookup.xdt
que se encuentra enejb-module.jar
y modifiquelookup()
enlookupHome
así: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(); } }
- Ejecute Ant, configurando el atributo plantilla para utilizar el
lookup.xdt
modificado para la tareaejbdoclet
. - Modifique el subsistema
naming
en el archivo de configuración del servidor para mapear el nombre JNDI viejo al nuevo nombre JNDI válido.<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>
Resumen de archivos obsoletos
Los siguientes archivos ya no se soportan en JBoss EAP 6.
- jboss.xml
- El archivo descriptor de implementación
jboss.xml
ya no se soporta y se ignora si se incluye en el archivador implementado. - standardjbosscmp-jdbc.xml
- El archivo de configuración
standardjbosscmp-jdbc.xml
ya no se soporta. Esta información de configuración ahora se incluye en el móduloorg.jboss.as.cmp
y ya no se puede personalizar. - standardjboss.xml
- El archivo de configuración
standardjboss.xml
ya no se soporta. Esta información de configuración ahora se incluye en el archivostandalone.xml
al ejecutar un servidor autónomo o el archivodomain.xml
en un dominio administrado.