3.2.11. EJB 2.x Änderungen

3.2.11.1. Aktualisierung von Applikationen, die EJB 2.x verwenden

JBoss EAP 6 wurde auf offenen Standards erstellt und ist kompatibel mit der Java Enterprise Edition 6 Spezifikation. Während der Applikationsserver Support für EJB 2.x bietet, bietet er möglicherweise keinen Support mehr für Features, die über die Spezifikation hinaus gehen. Bedenken Sie, dass die Java EE 7 Spezifikation EJB 2.x als optional markierte, demnach wird stark empfohlen, dass Sie Ihren Applikationscode in die EJB 3.x Spezifikation neu schreiben.
Wenn Sie dennoch Ihren EJB 2.x Code migrieren möchten, werden Sie in den meisten Fällen ein paar Änderungen vornehmen müssen, damit es in JBoss EAP 6 läuft. Dieses Thema beschreibt einige der Änderungen, die Sie vornehmen müssen, damit EJB 2.x auf JBoss EAP 6 läuft.
Konfigurationsänderungen erforderlich um EJB 2.x auf JBoss EAP 6 auszuführen

Starten Sie den Server mit dem "Full Profile"
EJB 2.x Container Managed Persistence (CMP) Beans benötigen das Java Enterprise Edition 6 Full Profil. Dieses Profil beinhaltet Konfigurationselemente, die zur Ausführung von CMP EJBs benötigt werden.
Dieses Konfigurationsprofil beinhaltet das org.jboss.as.cmp Erweiterungsmodul:
<extensions>
    ...
    <extension module="org.jboss.as.cmp"/>
    ...
</extensions>
Es beinhaltet auch das cmp Subsystem:
<profiles>
    ...
    <subsystem xmlns="urn:jboss:domain:cmp:1.1"/>
    ...
</profiles>
.
Um einen JBoss EAP 6 Standalone Server mit dem vollständigen Profil zu starten, übertragen Sie das -c standalone-full.xml oder -c standalone-full-ha.xml Argument auf die Befehlszeile, wenn Sie den Server starten.
Containerkonfiguration wird nicht mehr unterstützt
In früheren Versionen der JBoss EAP war es möglich verschiedene Container für die CMP Entity und andere Beans zu konfigurieren und zu benutzen, indem man Referenzen in die jboss.xml Applikations-Deployment Deskriptordatei eingab. Es gab zum Beispiel generell verschiedene Konfigurationen für SLSB zu Session Beans.
Bei der JBoss EAP 6.x ist es möglich EJB 2 Entity Beans mit einem Standard-Container zu benutzen. Die verschiedenen Containerkonfigurationen werden jedoch nicht mehr unterstützt. Empfohlen wird der Ansatz, nach dem die EJB2 Stateful Session Beans (SFSB), Stateless Session Beans (SLSB), Message Driven Beans (MDB) nach EJB 3 zu migrieren und für die Container-Managed Persistence (CMP) und Bean-Managed Persistence (BMP) Entity BeansJava Persistence API (JPA) gemäß der EJB 3 Spezifikation zu benutzen.
Die standardmäßige Containerkonfiguration in JBoss EAP 6 beinhaltet einige Änderungen für EJB 2 CMP Beans:
  • Pessimistisches Sperren ist standardmäßig aktiviert. Das kann zu Deadlocks führen.
  • Der deadLock detection code, den es in der CMP Layer in JBoss EAP 5.x gab, gibt es in JBoss EAP 6 nicht mehr.
In JBoss EAP 5.x war es auch möglich Caching, Pooling, commit-options und den Interzeptor Stack anzupassen. In JBoss EAP 6 ist das nicht mehr möglich. Es gibt nur eine Implementation, die der Instance Per Transaction Policy mit commit-option C ähnlich ist. Wenn Sie eine Applikation migrieren, die die cmp2.x jdbc2 pm Entity Bean Container Konfiguration benutzt, welche einen CMP2.x kompatiblen, JDBC basierten Persistenz-Manager benutzt, wird es sich auf die Performance auswirken. Dieser Container wurde für die Performance optimiert. Es wird empfohlen, dass Sie diese Entities zu EJB 3 migrieren, bevor Sie die Applikation migrieren.
Serverseitige Interzeptor-Konfiguration
JBoss EAP 6 unterstützt den Java EE Interceptor unter Verwendung der @Interceptors und @AroundInvoke Annotationen. Dies ermöglicht jedoch nicht die Bearbeitung außerhalb der Zugriffsrechte oder Transaktion.
In früheren Versionen der JBoss EAP war es möglich den Interzeptor Stack zu bearbeiten um benutzerdefinierte Interzeptoren für jeden EJB Aufruf zu haben. Dies wurde oft verwendet um benutzerdefinierte Zugriffsrechte zu implementieren oder Mechanismen vor Sicherheitsüberprüfungen, Transaktionsüberprüfungen oder Erstellung auszuprobieren. JBoss EAP 6.1 führte Container-Interzeptoren ein, um ähnliche Funktionalitäten zu bieten. Weitere Informationen über Container-Interzeptoren finden Sie in dem Kapitel Container Interceptors im Development Guide für JBoss EAP.
Ein anderer Ansatz für bessere Kontrolle vor, während oder nach der Commitphase einer Transaktion unter Einhaltung der Java EE Spezifikation ist es, das Transaction Synchronization Registry zu benutzen um einen Listener hinzuzufügen.
Die Ressource kann über eine der folgenden Methoden abgefragt werden:
  • Benutzen Sie den InitialContext
    TransactionSynchronizationRegistry tsr = (TransactionSynchronizationRegistry) 
    		new InitialContext().lookup("java:jboss/TransactionSynchronizationRegistry");
    tsr.registerInterposedSynchronization(new MyTxCallback());
    
  • Verwendung von Einspeisung
    @Resource(mappedName = "java:comp/TransactionSynchronizationRegistry")
    TransactionSynchronizationRegistry tsr;
    ...
    tsr.registerInterposedSynchronization(new MyTxCallback());
    
Die Callback Routine muss das javax.transaction.Synchronization Interface implementieren. Benutzen Sie die beforeCompletion{} Methode um Prüfungen durchzuführen, bevor die Transaktion ausgeführt oder zurückgesetzt wurde. Wenn eine RuntimeException von dieser Methode ausgelöst wird, wird die Transaktion zurückgesetzt und der Client wird mit einer EJBTransactionRolledbackException informiert. Im Falle einer XA-Transaction werden alle Ressourcen gemäß dem XA-Vertrag zurückgesetzt. Für Geschäftslogik aktivieren ist es auch möglich über die afterCompletion(int txStatus) Methode vom Transaktionsstatus abhängig zu sein. Wenn eine RuntimeException von dieser Methode ausgelöst wird, bleibt die Transaktion in ihrem früheren Status, entweder zurückgesetzt oder ausgeführt, und der Client wird nicht informiert. Nur der Transaktions-Manager zeigt eine Warnung innerhalb der Serverprotokolldateien an.
Serverseitige Konfiguration für Clientenseitige Interzeptoren
In früheren Versionen der JBoss EAP war es möglich, den Client-Interzeptor innerhalb der Serverkonfiguration zu konfigurieren und nur die Klassen mit dem Client API anzugeben.
Bei der JBoss EAP 6 ist dies nicht mehr möglich, da der Client-Proxy nicht mehr auf der Serverseite erstellt und nach dem Lookup dem Client übertragen wird. Der Proxy wird jetzt auf Clientseite erstellt. Diese Optimierung vermeidet einen Serveraufruf für Lookup und Klassen-Uploads.
Entity Bean Pool Konfiguration
Entity Bean Pool Konfiguration wird in JBoss EAP 6 nicht empfohlen. Da es auf Konfiguration des <strict-max-pool> Elements limitiert ist, können Deadlocks und andere Probleme auftreten, wenn der Pool zu klein ist um alle Entitys im Ergebnissatz zu laden. Entity Beans haben keine großen Lebenszyklusmethoden während der Initialisierung, daher ist die Erstellung der Instanz und umgebenden Container nicht langsamer, als wenn eine in einem Pool zusammengefasste Entity Bean Instanz benutzt wird.
Die jboss.xml Deployment Deskriptor Datei ersetzen
Der jboss-ejb3.xml Deployment-Deskriptor ersetzt die jboss.xml Deployment-Deskriptor-Datei. Diese Datei wird bei der Außerkraftsetzung und Hinzufügung von Features des von der Java Enterprise Edition (EE) definierten ejb-jar.xml Deployment-Deskriptors verwendet. Die neue Datei ist nicht kompatibel mit jboss.xml und die jboss.xml wird jetzt bei Deployments ignoriert.
Wenn Sie zum Beispiel in einer früheren Release der JBoss EAP eine <resource-ref> in der ejb-jar.xml Datei definiert haben, brauchten Sie eine entsprechende Ressourcendefinition für den JNDI Namen in der jboss.xml Datei. XDoclet erstellte automatisch diese beiden Deployment-Deskriptor-Dateien. In JBoss EAP 6 ist die JNDI Mapping Information jetzt in der jboss-ejb3.xml Datei definiert. Es ist vorauszusetzen, dass die Datenquelle im Java Source Code folgendermaßen definiert ist.
DataSource ds1 = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/Resource1");
DataSource ds2 = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/Resource2");
Das ejb-jar.xml definiert folgende Ressourcen-Referenzen.
<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>
Die jboss-ejb3.jxml Datei ordnet die JNDI Namen den Referenzen zu, indem sie folgende XML Syntax benutzt.
<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>
Manche der Konfigurationsoptionen, die in der JBoss EAP 5.x jboss.xml Datei verfügbar waren, wurden nicht in die JBoss EAP 6 implementiert. Die folgende Liste beschreibt einige der in der jboss.xml Datei allgemein verwendeten Attribute und ob es eine Alternative in der JBoss EAP 6 gibt.
  • Das method-attribute Element wurde verwendet um individuelle Entity und Session Beans Methoden zu konfigurieren.
    • Die read-only und idempotent Konfigurationsoptionen wurden nicht in die JBoss EAP 6 portiert.
    • Die transaction-timeout Option wird jetzt in der jboss-ejb3.xml Datei konfiguriert.
  • Das missing-method-permission-exclude-mode Attribut änderte das Verhalten der Methoden ohne die Implementierung von expliziten Sicherheits-Metadaten auf einer gesicherten Bean. In JBoss EAP 6 wird das Fehlen einer @RolesAllowed Annotation derzeit ähnlich gehandhabt, wie @PermitAll
Datenquellen-Typ Mapping Konfiguration
In früheren Versionen der JBoss EAP war es möglich Datenquellen Typ-Mapping innerhalb der *-ds.xml Datenquellen Deployment Konfigurationsdatei zu konfigurieren.
In JBoss EAP 6 muss dies in der jbosscmp-jdbc.xml Deployment-Deskriptor-Datei getan werden.
<defaults>  
    <datasource-mapping>mySQL</datasource-mapping>  
    <create-table>true</create-table>  
    ....  
</defaults>
In früheren Versionen der JBoss EAP wurde benutzerdefiniertes Mapping in der standardjbosscmp-jdbc.xml Datei vorgenommen. Diese Datei ist nicht mehr verfügbar und das Mapping wird jetzt in der jbosscmp-jdbc.xml Deployment-Deskriptor-Datei vorgenommen.
Zusätzliche Änderungen der Container-Managed Persistence (CMP) und Container-Managed Relationship (CMR)

Container Managed Relationship (CMR) Iterator und Collection Änderungen
In früheren Releases der JBoss EAP war es für manche Container, zum Beispiel für den cmp2.x jdbc2 pm Container, möglich CMR Collections zu durchlaufen und Relationen zu entfernen oder hinzuzufügen. Da Containerkonfiguration nicht unterstützt wird, ist das nicht mehr möglich in JBoss EAP 6. Informationen darüber, wie Sie die gleiche Funktionalität im Applikationscode erreichen, finden Sie unter EJB2.1 Finder for CMP entities with relations (CMR) returns duplicates in EAP6 im Support Knowledgebase Solutions Abschnitt des Kundenportals .
Container Managed Relationship (CMR) Doppelte Einträge für Finder
In früheren Versionen der JBoss EAP war es möglich verschiedene CMP Container auszuwählen, die verschiedene Persistenzstrategien benutzen. Der cmp2.x jdbc2 pm Container in JBoss EAP 5.x benutzte optimierte SQL-92 um optimierte LEFT OUTER JOIN Syntax für Finder zu erzeugen. Da JBoss EAP 6.x nur die Standardcontainer für CMP und CMR unterstützt, enthält die Implementierung diese Optimierungen nicht. Der Finder sollte das Schlüsselwort DISTINCT im SELECT Statement enthalten um das kartesische Produkt im Ergebnissatz zu vermeiden. Weitere Informationen finden Sie unter EJB2.1 Finder for CMP entities with relations (CMR) returns duplicates in EAP6 im Support Knowledgebase Solutions Abschnitt im Kundenportal.
Löschweitergabe-Standard Änderung für CMP Entity Beans
Der Standardwert der Löschweitergabe wurde auf false geändert. Das kann zu Löschfehlern in JBoss EAP 6 führen. Wenn Entity Relationen als cascade-delete markiert sind, müssen Sie batch-cascade-delete explizit auf true in der jbosscmp-jdbc.xml Datei setzen. Weitere Informationen finden Sie unter cascade delete fail for EJB2 CMP Entities after migration to EAP6 im Support Knowledgebase Solutions Abschnitt im Kundenportal.
CMP benutzerdefinierte Mapper für benutzerdefinierte Felder
Wenn Sie benutzerdefinierte Mapperklassen, wie JDBCParameterSetter, JDBCResultSetReader und Mapper in Ihrer JBoss EAP 5.x Applikation verwendet haben, wird Ihnen vielleicht java.lang.ClassNotFoundException angezeigt, wenn Sie Ihre Applikation in JBoss EAP 6 deployen. Das liegt daran, dass die Paketnamen für die Interfaces von org.jboss.ejb.plugins.cmp.jdbc.Mapper zu org.jboss.as.cmp.jdbc.Mapper geändert wurden. Weitere Informationen finden Sie unter How to use Field mapping for custom classes in an EJB2 CMP application in EAP6 im Support Knowledgebase Solutions Abschnitt im Kundenportal.
Erstellung von Primärschlüsseln unter Verwendung von Entity-Befehlen
Wenn Ihre JBoss EAP 5 Applikation entity-commands benutzt um Primärschlüssel zu erzeugen, zum Beispiel Sequence oder Auto-increment, wird Ihnen vielleicht eine ClassNotFoundException für die JDBCOracleSequenceCreateCommand KJlasse angezeigt, wenn Sie Ihre Applikation zu JBoss EAP 6 migrieren. Das liegt daran, dass das Klassenpaket von org.jboss.ejb.plugins.cmp.jdbc zu org.jboss.as.cmp.jdbc.keygen geändert wurde. Wenn Sie diese Klasse in Ihrer JBoss EAP 6 Applikation sehen, müssen Sie auch eine Abhängigkeit auf dem EAP_HOME/modules/system/layers/base/org/jboss/as/cmp Modul hinzufügen.
Applikations-Änderungen

Bearbeiten Sie den Code zur Verwendung der neuen JNDI Namespace-Regeln.
Wie beim EJB 3.0 müssen Sie den vollständigen JNDI-Präfix mit EJB 2.x verwenden. Weitere Informationen zu den neuen JNDI-Namespace-Regeln und Code-Beispiele finden Sie unter Abschnitt 3.1.8.1, »Aktualisierung der JNDI Namespace-Namen der Applikation«.
Beispiele, die zeigen, wie JNDI-Namespaces früherer Releases aktualisiert werden, finden Sie hier: Abschnitt 3.1.8.5, »Beispiele von JNDI-Namespaces in früheren Releases und wie diese in der JBoss EAP 6 spezifiziert sind«.
Bearbeiten Sie den jboss-web.xml-Dateideskriptor
Bearbeiten Sie <jndi-name> für jedes <ejb-ref> zur Verwendung des neuen JNDI Lookup-Formats.
Benutzen Sie XDoclet um den JNDI Name von Internen Lokalen Interfaces zuzuordnen
Mit EJB 2 war es üblich über das Locator Muster Beans zu suchen. Wenn Sie dieses Muster in Ihrer Applikation benutzt haben, anstatt den Applikationscode zu ändern, können Sie mit XDoclet eine Map für die neuen JNDI-Namen erstellen.
Eine typische XDoclet Annotation sieht folgendermaßen aus:
@ejb.bean name="UserAttribute" display-name="UserAttribute" local-jndi-name="ejb21/UserAttributeEntity" view-type="local" type="CMP" cmp-version="2.x" primkey-field="id"
Der JNDI Name ejb21/UserAttributeEntity im angeführten Beispiel ist in JBoss EAP 6 nicht mehr gültig. Sie können diesen Namen unter Verwendung des naming Subsystems in der Serverkonfiguration und einem Patch für XDoclet einem gültigen JNDI-Namen zuordnen.
Sie können benutzerdefinierte Mapper erstellen, wie es im vorherigen Paragraph CMP Customized Mappers for Custom Fields beschrieben wurde, oder Sie können den Code entsprechend folgender Vorgehensweise ändern.

Prozedur 3.24. Den XDoclet Generierten Code ändern und das Benennungs-Subsystem verwenden

  1. Extrahieren Sie die XDoclet lookup.xdt Vorlage im ejb-module.jar und modifizieren Sie das lookup() im lookupHome wie folgt:
    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. Führen Sie Ant aus, während Sie das Vorlagenattribut auf Benutzung des modifizierten lookup.xdt für die ejbdoclet Aufgabe einstellen.
  3. Modifizieren Sie das naming Subsystem in der Server-Konfigurationsdatei um den alten JNDI-Namen dem neuen, gültigen JNDI-Namen zuzuordnen.
    <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>
Zusammenfassung von veralteten Dateien

Folgende Dateien werden in der JBoss EAP 6 nicht mehr unterstützt.

jboss.xml
Die jboss.xml Deployment-Deskriptor-Datei wird nicht mehr unterstützt und wird ignoriert, wenn sie im deployten Archiv erscheint.
standardjbosscmp-jdbc.xml
Die standardjbosscmp-jdbc.xml Konfigurationsdatei wird nicht mehr unterstützt. Diese Konfigurationsinformation ist jetzt im org.jboss.as.cmp Modul erfasst und ist nicht mehr anpassbar.
standardjboss.xml
Die standardjboss.xml Konfigurationsdatei wird nicht mehr unterstützt. Diese Konfigurationsinformation ist jetzt in der standalone.xml Datei erfasst, wenn ein Standalone Server ausgeführt wird, oder in der domain.xml Datei, wenn sie in einer Managed Domain ausgeführt wird.