Übersicht über die Paketierung von Modulen der EJB 3.x
Dieser Artikel beschreibt die Anwendungspaketierung bei Verwendung von Beans der EJB Version 3.x (Enterprise JavaBeans).
Die Paketierung von Anwendungen, die Beans der EJB Version 3.x verwenden, ähnelt den Assemblierungsvoraussetzungen für Java EE 1.4-Anwendungen (Java™ Platform, Enterprise Edition): Die Komponenten werden in Modulen und die Module in Anwendungs-EAR-Dateien (Enterprise Archive) gepackt. Die Komponenten und Module verfügen beide über beschreibende Metadaten, die in einem XML-Implementierungsdeskriptor (XML = Extensible Markup Language) bereitgestellt werden. Die Spezifikationen EJB 3.x unterstützen eine zusätzliche Methode zur Beschreibung von Metadaten und zur Paketierung von Persistenzeinheiten.
- JAR-Dateien (Java Application Archive) für EJB-Module. Java EE-Anwendungsclientmodule und -Dienstprogrammklassenmodule.
- WAR-Dateien für Webmodule oder EJB-Inhalt. Die WAR-Datei muss Version 2.5 oder höher haben, um EJB-Inhalt enthalten zu können.
- Andere technologiespezifische Module, z. B. RAR-Dateien (Resource Application Archive) und andere Arten von Modulen.
EJB-Module ohne Implementierungsdeskriptoren
Sie können EJB-Module ohne einen Implementierungsdeskriptor packen, falls Sie Beans der EJB Version 3.x verwenden. Dazu müssen Sie zunächst eine JAR- oder WAR-Datei mit Metadaten in einer Annotation erstellen, die in der EJB-Komponente enthalten ist. Für Metadaten, die über Annotationen definiert wurden, benötigen Beans der EJB Version 3.x keinen Eintrag in der Datei ejb-jar.xml.
Bei EJB 3.0 wurden während der Installation eines Moduls der EJB Version 3.0 standardmäßig die Annotationen überprüft. In WebSphere Application Server, Version 9.0 wird standardmäßig so vorgegangen, dass während der Anwendungsinstallation oder beim Serverstart Module mit einer Version vor Java EE 5 nicht überprüft werden.
Damit die Abwärtskompatibilität mit dem Feature Pack for EJB 3.0 und dem Feature Pack for Web Services erhalten bleibt, können Sie auswählen, ob traditionelle Webmodule nach zusätzlichen Metadaten durchsucht werden sollen oder nicht. Für jedes Feature-Pack-Prüfverhalten ist ein Schalter auf Serverebene definiert. Wenn der Standardwert nicht geeignet ist, muss der Schalter in jedem Server und Administrationsserver, dessen Standardwert geändert werden soll, festgelegt werden. Bei den Schaltern handelt es sich um die angepassten Servereigenschaften "com.ibm.websphere.webservices.UseWSFEP61ScanPolicy={true|false}" und "com.ibm.websphere.ejb.UseEJB61FEPScanPolicy={true|false}". Klicken Sie in der Administrationskonsole auf
.EJB-Module mit Implementierungsdeskriptoren
Sie können EJB-Module weiterhin mit Implementierungsdeskriptoren verwenden. Module mit Implementierungsdeskriptoren können jeden Versionsstand der EJB-Spezifikation, einschließlich EJB 3.x, unterstützen. Im Allgemeinen sollten diese Deskriptoren jedoch die Implementierungsanforderungen der Komponenten im Modul wiedergeben.
Ein EJB-Modul kann einen Implementierungsdeskriptor der EJB Version 3.x, 2.x oder 1.x haben.
Bei Implementierungsdeskriptoren der EJB Version 2.x oder 1.x wird davon ausgegangen, dass der Implementierungsdeskriptor alle Metadaten für das Modul enthält, und es wird nicht zusätzlich nach Metadaten in den Annotationen gesucht.
Die EJB-Container-Annotationen werden für EJB-Module geprüft, die entweder keinen Implementierungsdeskriptor oder den Implementierungsdeskriptor der Version 3.0, ejb-jar.xml, mit dem XML-Attribut "metadata-complete", das auf "false" oder "omitted" gesetzt ist, enthalten. Den vollständigen Regelsatz, mit dessen Hilfe der Server bestimmt, ob ein Annotationsscan durchgeführt wird, finden Sie im Abschnitt zum Verhalten für den Annotationsscan.
Verhalten für den Annotationsscan
Der Server kann die Klassendateien im Modul nach Annotationsinhalt durchsuchen. Der Server sucht Annotationsinhalt, der eine Komponente, eine Referenz auf eine Ressource oder ein bestimmes Verhalten definieren kann. Annotationen können beispielsweise verwendet werden, um eine EJB-Komponente zu definieren, um eine Referenz auf eine von einer EJB-Komponente zu verwendende Datenquelle zu deklarieren, oder um die Transaktions- und Sicherheitsattribute zu deklarieren, die einer EJB-Methode zugeordnet sind. Dieser Prüfprozess wird als Annotationsscan bezeichnet. Wenn die Klassendateien im Modul Annotationen enthalten, die vom Server berücksichtigt werden müssen, muss der Server für die Durchführung von Annotationsscans konfiguriert sein. Enthalten die Klassendateien im Modul keine Annotationen, können Sie den Server aus Leistungsaspekten so konfigurieren, dass keine Annotationsscans stattfinden.
- Existenz der Implementierungsdeskriptordatei "ejb-jar.xml"
- Version des Implementierungsdeskriptors "ejb-jar.xml", sofern vorhanden
- Wert der Einstellung "metadata-complete" im Implementierungsdeskriptor "ejb-jar.xml", sofern vorhanden
- Version des Implementierungsdeskriptors "web.xml", wenn der EJB-Inhalt in ein WAR-Modul gepackt ist und der Implementierungsdeskriptor "ejb-jar.xml" nicht vorhanden ist
- Wert der Einstellung "metadata-complete" im Implementierungsdeskriptor "web.xml", wenn der EJB-Inhalt in ein WAR-Modul gepackt ist und der Implementierungsdeskriptor "ejb-jar.xml" nicht vorhanden ist
Den folgenden Tabellen können Sie entnehmen, ob ein Annotationsscan für EJB-Inhalt, der in ein EJB-JAR-Modul oder in ein WAR-Modul gepackt ist, durchgeführt wird oder nicht.
ejb-jar.xml | Wert von metadata-complete in ejb-jar.xml | Werden Annotationen gescannt? |
---|---|---|
Vorhanden, mit Version 2.x oder niedriger | Nicht zutreffend | Nein |
Vorhanden, mit Version 3.x oder höher | true | Nein |
Vorhanden, mit Version 3.x oder höher | false (oder omitted) | Ja |
Nicht vorhanden | Nicht zutreffend | Ja |
Datei ejb-jar.xml | Wert von metadata-complete in ejb-jar.xml | Datei web.xml | Wert von metadata-complete in web.xml | Werden Annotationen gescannt? |
---|---|---|---|---|
Vorhanden, mit Version 3.x oder höher | true | Nicht zutreffend | Nicht zutreffend | Nein |
Vorhanden, mit Version 3.x oder höher | false (oder omitted) | Nicht zutreffend | Nicht zutreffend | Ja |
Vorhanden, mit Version 2.x oder niedriger | Nicht zutreffend | Nicht zutreffend | Nicht zutreffend | Nein |
Nicht vorhanden | Nicht zutreffend | Vorhanden, mit Version 2.5 oder höher | true | Nein |
Nicht vorhanden | Nicht zutreffend | Vorhanden, mit Version 2.5 oder höher | false (oder omitted) | Ja |
Nicht vorhanden | Nicht zutreffend | Vorhanden, mit Version 2.4 oder niedriger | Nicht zutreffend | Nein |
Nicht vorhanden | Nicht zutreffend | Nicht vorhanden | Nicht zutreffend | Ja |
Sie müssen den Unterschied zwischen dem Attribut "metadata-complete" des Elements "ejb-jar" des Implementierungsdeskriptors ejb-jar.xml und der Installationseinstellung "metadata-complete", die während der Installation der Anwendung bzw. des Moduls angegeben werden kann, unbedingt kennen.
Das Attribut "metadata-complete" des Elements "ejb-jar" der Datei ejb-jar.xml ist ein XML-Attribut. Mithilfe dieses Attributs bestimmt der Server, ob Klassen nach Annotationsdaten durchsucht werden müssen (siehe die Regeln in den Tabellen "Annotationsscan für EJB-Inhalt").
Im Gegensatz dazu wird die Einstellung "metadata-complete", die während der Installation angegeben werden kann, vom Server für die Generierung der Datei ejb-jar.xml verwendet. Wenn keine Datei ejb-jar.xml im Modul vorhanden ist und die Installationseinstellung "metadata-complete" den Wert "true" hat, sucht der Server nach Annotationsinhalt, verwendet diesen für die Generierung einer Datei ejb-jar.xml und setzt anschließend das XML-Attribut "metadata-complete" in dieser Datei auf "true".
Persistenzeinheiten
Persistenzeinheiten, einschließlich der Datei persistence.xml und der ihr zugeordneten Klassen können in das Modul gepackt werden, für das sie benötigt werden. Sie können auch in eine separate JAR-Dienstprogrammdatei gepackt werden, die mit ihrem abhängigen Modul in die EAR-Datei gepackt wird.
Anwendungspaketierung
Sie können Beans der EJB Version 2.x und früher und Beans der EJB Version 3.x in derselben Anwendung verwenden. Beans der EJB Version 3.x werden in Modulen der EJB Version 2.x und EJB 1.x jedoch nicht erkannt.
- Als Anwendungsname wird der Name der EAR-Datei ohne deren Erweiterung angenommen.
- Dateien, die auf .war enden, werden als Webmodule betrachtet. Das Kontextstammverzeichnis des Webmoduls ist der Name der Datei relativ zum Stammverzeichnis des Anwendungspakets, aber ohne WAR-Dateierweiterung.
- Dateien, die auf .jar enden und nicht im Verzeichnis /lib enthalten sind und die überdies entweder die Datei ejb-jar.xml enthalten oder mindestens eine Klasse, die eine @Stateful-, @Stateless-, @Singleton- oder @MessageDriven-Annotation definiert, werden als EJB-Modul betrachtet.
- Andere JAR-Dateien, die nicht im Verzeichnis "/lib" enthalten sind, werden nicht als EJB-Modul betrachtet.
JPA-Paketierung
Es wird empfohlen, die Persistenzeinheiten in separate JAR-Dateien zu packen, damit sie besser zugänglich und wiederverwendbar sind. Diese können, entweder mit oder ohne tatsächliche Datenbankpersistenz, außerhalb des Containers getestet werden. Persistenzeinheiten können als JAR-Dienstprogrammdateien in eigenständige Anwendungen oder in EAR-Dateien eingefügt werden. Aufgrund der Vielzahl von Anwendungsfällen und möglichen Leistungsproblemen beim Prüfen großer Klassenmengen wird empfohlen, dass die Persistenzeinheit die Klassen der Persistenzeinheiten definiert.
Für das Persistenz-Szenario verwendete Sitzungsfassaden
Ein häufig verwendetes Muster ist der Einsatz von Sitzungsfassaden für die Persistenz. Die Verwendung von Session-Bean-Fassaden zur Steuerung von JPA wird unterstützt. Die Schnittstelle "EntityManager" ist für Threads nicht sicher, daher sollten Servlets niemals "@PersistenceContext" einbringen. Servlets müssen entweder das Fassadenmuster verwenden oder müssen eine EntityManagerFactory-Instanz verwenden, um in jeder Anforderung einen EntityManager zu erstellen.
Es wird empfohlen, JPA-Persistenzeinheiten in einer separaten, von den Session-Bean-Fassaden getrennten JAR-Datei zu definieren. Dies ist ein bewährtes Verfahren, das eine größere Flexibilität bei der gemeinsamen Nutzung ermöglicht und das überdies Probleme bei der gemeinsamen Verwendung von JPA- und Nicht-JPA-annotierten Klassen vermeidet.
Normalerweise wird eine JAR-Datei erstellt, die die Entitätsklassen und die JPA-Definition persistence.xml enthält. Diese wird der EAR-Datei als JAR-Dienstprogrammdatei hinzugefügt. Das Modul der EJB Version 3.x fügt der JAR-Datei eine Abhängigkeit hinzu, indem diese im Modul der EJB Version 3.x MANIFEST.MF deklariert wird. Wenn eine EAR-Datei beispielsweise die Dateien TradeApp.ear, TradeWeb.war, EJB3Trade.jar und TradeInfo.jar enthält, hat die Datei EJB3Trade.jar eine Datei MANIFEST.MF wie die folgende:
Manifest-Version: 1.0
Class-Path: TradeInfo.jar
Die Sitzungsfassade in der Datei EJB3Trade.jar verweist auf JPA-Entitätsklassen und Persistenzeinheiten in der Datei TradeInfo.jar. Die in der Datei TradeWeb.war definierte Webanwendung kann genauso vorgehen, um die JPA-Entitätsobjekte als Datenübertragungsobjekte, die zwischen den Ebenen des web und des EJB-Containers fließen, einzusetzen.
Szenario einer ebenen- und versionsübergreifenden Session-Bean-Referenz
Es gibt mehrere Möglichkeiten, Referenzen auf Session-Beans der EJB Version 3.x zu definieren und zu verwenden. Für Referenzen zwischen Sitzungen der EJB 3.x kann das @EJB-Injektionsziel verwendet werden. Für eine ebenenübergreifende Referenz, z. B. die Referenz einer Webanwendung auf eine Session-Bean der EJB Version 3.x, oder für eine versionsübergreifende Referenz, z. B. die Referenz einer EJB-2.1-Session-Bean auf eine Session-Bean der EJB Version 3.x kann eine XML-Implementierungsdeskriptorreferenz verwendet werden, um "ejb-refs" und "ejb-local-refs" zu definieren. Es gibt hierbei zwei Varianten, die abhängig davon sind, ob eine Geschäftsschnittstelle der EJB Version 3.x referenziert wird oder eine Komponentenschnittstelle vor EJB 3.x, das auch ein EJBLocalHome definiert. Webanwendungen und Clientanwendungen können auch die Annotation "@EJB" verwenden, wenn die referenzierte Komponente über AutoLink aufgelöst werden kann.
Das vorherige Szenario verwendet ein Clientmuster im EJB-2.1-Stil mit einer Session-Bean-Implementierung der EJB Version 3.x. Damit ein aktuellerer Clientstil verwendet wird, kann die Clientseite so bereinigt werden, dass sie die Geschäftsschnittstelle der Session-Bean direkt anstatt über eine Home-Schnittstelle ermittelt. In diesem Fall ist es nicht erforderlich, die Annotation "@LocalHome(<localhome>.class)" zu definieren. Sie können hierzu eine Definitionsvariante von "ejb-ref" und "ejb-local-ref" verwenden. Verwenden Sie einen Nullwert als Wert des Elements "local-home", und binden Sie "ejb-local-ref" an die Bindung "ejblocal:" der Session-Bean anstatt an die Bindung "home". Beispiel:
<ejb-local-ref id="EJBLocalRef_1154112538064">
<description>com.ibm.persistence.ejb3.order.facadecom.ibm.persistence.ejb3.order.facade</description>
<ejb-ref-name>ejb/OrderEJB</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local-home></local-home>
<local>com.ibm.persistence.ejb3.order.facade.OrderProcessor</local>
</ejb-local-ref>
Der Client-Code muss ebenfalls angepasst werden, um für das gesuchte Objekt das geeignete Casting auszuführen, in diesem Fall die Geschäftsschnittstelle anstelle der Home-Schnittstelle:
try {
InitialContext ctx = new InitialContext();
orderProcessor = (OrderProcessor)ctx.lookup("java:comp/env/ejb/OrderEJB");
}
catch(Exception e) {
e.printStackTrace(System.out);
throw new ServletException(e);
}