Anwendungen mit dem integrierbaren EJB-Container entwickeln

Verwenden Sie diese Task, um Anwendungen mit dem integrierbaren EJB-Container (Enterprise JavaBeans) zu entwickeln. Im integrierbaren Container ausgeführte Anwendungen werden schneller gestartet und haben einen geringeren Speicherbedarf als bei der Ausführung im vollständigen Anwendungsserver. Der Container ist eine optimale Umgebung für das schnelle Entwickeln und Testen von Anwendungen, die letztendlich im Anwendungsserver ausgeführt werden.

Vorbereitende Schritte

Zum Erstellen einer integrierbaren EJB-Containeranwendung müssen Sie Ihre Entwicklungsumgebung für die Verwendung von Version 8.0 von Java™ Development Kit (JDK) Version 1.8 oder höher konfigurieren. Außerdem muss Ihre Entwicklungsumgebung die JAR-Datei des integrierbaren WebSphere-Containers im Klassenpfad enthalten. Die Datei com.ibm.ws.ejb.embeddableContainer_9.0.jar befindet sich im Verzeichnis \runtimes unterhalb des Installationsverzeichnisses von WebSphere Application Server.
Einschränkung: Der EJB-Thin-Client com.ibm.ws.ejb.thinclient_9.0.jar und die in die EJB integrierbare JAR-Datei com.ibm.ws.ejb.embeddableContainer_9.0.jar können nicht in demselben Klassenpfad koexistieren.
Einschränkung: Die Datei "com.ibm.ws.ejb.embeddableContainer_9.0.jar" zeigt Nachrichten nur auf Englisch an. Wenn Sie weitere Sprachen benötigen, verwenden Sie die Datei "com.ibm.ws.ejb.embeddableContainer_nls_9.0.jar" anstelle der Datei "com.ibm.ws.ejb.embeddableContainer_9.0.jar". Die Datei "com.ibm.ws.ejb.embeddableContainer_nls_9.0.jar" befindet sich im Verzeichnis \runtimes im Installationsverzeichnis von WebSphere Application Server.

Wenn Ihre Beans die Annotation "javax.annotation.Resource" mit dem Attribut "lookup" verwenden, müssen Sie auch Java Endorsed Standards Override Mechanism verwenden, um die API "javax.annotation.Resource" zu überschreiben, die im JDK auf Ihrem System verfügbar ist. Kopieren Sie die Datei Stammverzeichnis_des_Anwendungsservers\runtimes\endorsed\endorsed_apis_9.0.jar in das Zielverzeichnis Ihrer Wahl. Verwenden Sie die Eigenschaft java.endorsed.dirs im Java-Befehl, um Ihr Verzeichnis anzugeben, das die kopierte JAR-Datei enthält.

Vorgehensweise

  1. Erstellen Sie ein EJB-Modul der Version 3.X. Wenn Sie dieses Modul erstellen, müssen Sie sicherstellen, dass es ausschließlich Features enthält, die vom integrierbaren WebSphere-Container unterstützt werden. Eine vollständige Liste unterstützter Funktionen finden Sie im Artikel Funktionen des integrierbaren EJB-Containers. Stellen Sie sicher, dass sich die EJB-Module im Klassenpfad des integrierbaren Containers enthalten sind. Sie können das EJB-Modul als Verzeichnisse von Klassen oder als EJB-JAR-Dateien packen.
  2. Erstellen Sie die Hauptklasse, die den integrierbaren Container und Methoden in den Enterprise-Beans startet. Verwenden Sie die Klasse "javax.ejb.EJBContainer", um eine Instanz des integrierbaren Containers zu erstellen (mit optionaler Übergabe von Konfigurationsparametern für den Container), rufen Sie den Benennungskontext des Containers ab, und schließen Sie den integrierbaren Container.

    Der folgende Beispielcode veranschaulicht die Verwendung des integrierbaren Containers:

    //EmbeddableContainerSample.java
    import java.util.HashMap;
    import java.util.Map;
    import javax.ejb.embeddable.EJBContainer;
    import my.pkg.MyBeanIface; // Lokale Geschäftsschnittstelle der
                               // Enterprise-Bean
    
    public class EmbeddableContainerSample {
    
       public static void main(String[] args) throws Throwable {
    
          // Eigenschaftsübersicht erstellen, die an den integrierbaren Container übergeben wird
          Map<String,Object> properties = new HashMap<String,Object>();
    
          // Angeben, dass der integrierbare WebSphere-Container verwendet werden soll
          properties.put(EJBContainer.PROVIDER, 
              "com.ibm.websphere.ejbcontainer.EmbeddableContainerProvider");
    
          // Containerinstanz erstellen und Eigenschaftsübersicht an den Container übergeben
          EJBContainer ec = EJBContainer.createEJBContainer(properties);
    
          // Containerkontext zum Suchen einer Bean verwenden
          MyBeanIface bean = ec.getContext().lookup(
              "java:global/MyEJBModule/MyBean!my.pkg.MyBeanIface");
    
          // Methode in der Beaninstanz aufrufen
          bean.doStuff();
    
          ...
    
    
          // Integrierbaren Container schließen
          ec.close();
    
       }
    }
    

    In diesem Beispielcode haben Sie eine Instanz eines integrierbaren Containers erstellt, indem Sie die Eigenschaft "EJBContainer.PROVIDER" auf die Klasse "com.ibm.websphere.ejbcontainer.EmbeddableContainerProvider" gesetzt und diese Eigenschaft an die Methode "EJBContainer.createEJBContainer" übergeben haben. Sie haben den Benennungskontext des Containers verwendet, um eine lokale Enterprise-Bean zu suchen, z. B. MyBean. Für die Suche wird die portierbare Syntax für globale Benennung verwendet.

    Dieser Beispielcode stützt sich darauf, dass der integrierbare Container den Klassenpfad automatisch durchsucht, um das EJB-Modul "MyEJBModule" zu finden. Alternativ können Sie die Module, die Sie starten möchten, mit der Eigenschaft "EJBContainer.MODULES" angeben. Verwenden Sie diese Eigenschaft, um eine Zeichenfolge oder ein Zeichenfolgenarray von Modulnamen anzugeben, die im JVM-Klassenpfad enthalten sein müssen.

    Sie können auch eine Datei oder einen Dateibereich von Modulen angeben, die nicht im Klassenpfad enthalten sind. Dieser Ansatz kann eine Änderung des Ladeprogramms für Kontextklassen im aktuellen Thread erfordern, falls diese Module zusätzliche Bibliotheken erfordert, die nicht im JVM-Klassenpfad enthalten sind.

    Das folgende Codebeispiel veranschaulicht, wie der integrierbare Container mithilfe eines Dateibereichs gestartet wird.

    ...
    // Eigenschaftenobjekt erstellen, das an den integrierbaren Container übergeben wird
    Map<String,Object> props = new HashMap<String,Object>();
    
    // EJB-Module angeben, die beim Erstellen des Containers gestartet werden sollen
    File[] ejbModules = new File[2];
    ejbModules[0] = new File("/home/myusername/ejbs/ShoppingCartEJB.jar");
    ejbModules[1] = new File("/home/myusername/ejbs/OnlineCatalogEJB.jar");
    props.put(EJBContainer.MODULES, ejbModules);
    
    // In diesem Beispiel stützen sich beide Module auf Code in einer gemeinsam genutzten Bibliothek.
    // Damit der integrierbare Container die gemeinsam genutzte Bibliothek lädt, muss das
    // Kontextklassenladeprogramm in der Lage sein, diese gemeinsam genutzte Bibliothek zu laden.
    
    // Konfigurieren Sie das Kontextklassenladeprogramm so, dass es die gemeinsam genutzte Bibliothek laden kann.
    File sharedLibUtilityFile = new File("/home/myusername/ejbs/SharedLib.jar");
    ClassLoader oldCL = Thread.currentThread().getContextClassLoader();
    ClassLoader newCL = new URLClassLoader(new URL[]{
       sharedLibUtilityFile.toURI().toURL()}, oldCL);
    Thread.currentThread().setContextClassLoader(newCL);
    
    // Integrierbaren Container erstellen und die Eigenschaftsübersicht an den Container übergeben
    EJBContainer ec = EJBContainer.createEJBContainer(props);
    
    // EJB aufrufen, die vom integrierbaren Container geladen wurde
    ...

    Nachdem Sie die Beaninstanz gesucht haben, starten Sie die Methoden in der Instanz. Nachdem Sie die containerrelevanten Tasks ausgeführt haben, schließen Sie den Container, der die Bean-Methoden startet, die mit "PreDestroy" markiert ist, und den integrierbaren Container schließt. Schließen Sie die integrierbare Containerinstanz, bevor Sie eine neue erstellen.

  3. Passen Sie den integrierbaren Container an. Sie können Eigenschaften verwenden, um die Laufzeitumgebung des integrierbaren EJB-Containers anzupassen. Eine vollständige Liste der unterstützten Eigenschaften finden Sie im Artikel Angepasste Eigenschaften des integrierbaren EJB-Containers.
  4. Wenn Ihre Anwendung Ressourcen wie Datenquellen verwenden soll, können Sie diese Ressourcen anschließend erstellen und in der Eigenschaftsübersicht, die an den integrierbaren Container übergeben wird, oder in einer Eigenschaftendatei konfigurieren.

    Der integrierbare EJB-Container wird häufig für das Testen von Anwendungen eingesetzt, die letztendlich im Anwendungsserver ausgeführt werden. Zahlreiche dieser Anwendungen stützen sich auf JDBC-Datenquellen, die im Server über die Administrationskonsole oder mit dem Scripting-Tool wsadmin konfiguriert werden. Da diese Tools nicht im integrierbaren Container vorhanden sind, können Sie den integrierbaren WebSphere-Container so konfigurieren, dass diese Ressourcen bereitgestellt werden, indem Eigenschaften an den Container übergeben werden.

    Die Konfigurationseigenschaften der Datenquelle können auch in einer Eigenschaftendatei gespeichert werden. Der integrierbare Container lädt Eigenschaften, die in einer Datei mit dem Namen "embeddable.properties" im aktuellen Arbeitsverzeichnis gespeichert sind, automatisch. Sie können diese Dateiposition überschreiben, indem Sie die neue Dateiposition als Wert der Systemeigenschaft "com.ibm.websphere.embeddable.configFileName" angeben.

    Die Konfigurationseigenschaften der Datenquelle beginnen alle mit dem Wort DataSource, dem ein Begriff folgt, der die zu konfigurierende Datenquelle identifiziert. Die Eigenschaft DataSource.myDataSource.someProperty gilt beispielsweise für eine andere Datenquelle als die Eigenschaft mit dem Namen DataSource.anotherDS.someOtherProperty. Die Datenquelleneigenschaften sind in den Informationen zu den angepassten Eigenschaften des integrierbaren EJB-Containers aufgelistet.

    Im Folgenden sehen Sie ein Beispiel für die Verwendung von Datenquellen in einer Anwendung:

    ...
    InitialContext context = new InitialContext();
    DataSource ds = (DataSource) context.lookup("env/jdbc/AcctsPayableDS");
    Connection conn = ds.getConnection();
    // Verbindung für den Zugriff auf die Datenbank AcctsPayableDS verwenden
    ...

    Im Server hat ein Systemadministrator eine Datenquelle erstellt und im JNDI-Namespace an env/jdbc/AcctsPayableDS gebunden. Alternativ könnte der Code die Datenquelle in einem Namespace "java:comp" suchen, der env/jdbc/AcctsPayableDS zugeordnet ist, oder ein EJB-Feld angeben, das mit der Datenquelle injiziert wird. In allen Fällen muss eine Datenquelle an den Namespace gebunden sein. Verwenden Sie den folgenden Code, um diese Aktion über das Programm auszuführen, wenn die Instanz des integrierbaren Containers erstellt wird:

    ...
    // Eigenschaftsübersicht erstellen, in der die Konfigurationseigenschaften
    // des integrierbaren Containers gespeichert werden
    Map<String,Object> props = new HashMap<String,Object>();
    
    // JNDI-Namen definieren, der an diese Datenquelle gebunden werden soll
    props.put("DataSource.ds1.name", "env/jdbc/AcctsPayableDS");
    
    // Klassennamen für die Datenquelle definieren. Diese Eigenschaft ist erforderlich.
    // In diesem Beispiel wird ein Derby-JDBC-Treiber verwendet.
    props.put("DataSource.ds1.dataSourceClass",
       "org.apache.derby.jdbc.EmbeddedConnectionPoolDataSource");
    
    // Datenbanknamen definieren
    props.put("DataSource.ds1.databaseName", "AcctsPayableTestDB");
    
    // Instanz des integrierbaren Containers mit den angepassten Eigenschaften erstellen
    EJBContainer ec = EJBContainer.createEJBContainer(props);
    
    // EJB im integrierbaren Container aufrufen...
    ...

    Der vorherige Code erstellt eine einfache Datenquelle für eine Apache-Derby-Datenbank mit dem Namen "AcctsPayableTestDB" und bindet sie an env/jdbc/AcctsPayableDS. Sie können dieselbe Task deklarativ ausführen, indem Sie den folgenden Text in eine Datei mit dem Namen embeddable.properties im aktuellen Arbeitsverzeichnis der JVM einfügen. Sie können diesen Text auch in eine beliebige Textdatei einfügen und diese Textdatei mit der Systemeigenschaft "com.ibm.websphere.embeddable.configFileName" angeben.

    DataSource.ds1.name=env/jdbc/AcctsPayableDS
    DataSource.ds1.dataSourceClass=org.apache.derby.jdbc.EmbeddedConnectionPoolDataSource
    DataSource.ds1.databaseName=AcctsPayableTestDB

    Verwenden Sie bei der Entwicklung der EJB Ressourcenreferenzen, anstatt die Datenquellen direkt zu suchen.

  5. Ihre Anwendung kann die rollenbasierte Java-EE-Sicherheit, deklarativ und programmgesteuert, verwenden, um Ihre rollenbasierte EJB-Sicherheit zu prüfen. Sie können die folgenden Aktionen ausführen, um die rollenbasierte EJB-Sicherheit zu prüfen:
    • Definieren Sie einen Benutzer für Berechtigungszwecke.
    • Ordnen Sie Benutzer Rollen zu, die in Ihrer EJB deklariert sind.
    • Testen Sie die Verwendung der EJBContext-Methoden "isCallerInRole()" und "getCallerPrincipal()" in Ihrer EJB.

    Im Folgenden sehen Sie ein Beispiel für die Verwendung der deklarativen und programmgesteuerten Sicherheit in Ihrer Anwendung:

    import java.util.HashMap;
    import java.util.Map;
    import javax.ejb.EJBContainer;
    import my.pkg.MyBeanIface; // Lokale Geschäftsschnittstelle der
                               // Enterprise-Bean
    public class EmbeddableContainerSample {
    
       public static void main(String[] args) throws Throwable {
          // Eigenschaftsübersicht erstellen, die an den integrierbaren Container übergeben wird
          Map<String,Object> properties = new HashMap<String,Object>();
          // Angeben, dass der integrierbare WebSphere-Container verwendet werden soll
          properties.put(EJBContainer.PROVIDER, 
              "com.ibm.websphere.ejbcontainer.EmbeddableContainerProvider");
          
          // Angeben, dass die Sicherheitsprüfung aktiviert werden soll
          properties.put("com.ibm.websphere.securityEnabled", "true");
          
          // Benutzer bob, fred und mary der Rolle employee zuordnen
          props.put("role.employee", "bob, fred, mary");
          // Benutzer fred der Rolle manager zuordnen
          props.put("role.manager", "fred");
          // Benutzer fred wird als runAs-Rollenmanager verwendet
          props.put("role.runAs.manager", "fred");
          // Benutzer fred wird für die Rollenberechtigung beim Aufruf
          // von Methoden in der EJB verwendet
          props.put("user.invocation", "fred");
          // Containerinstanz erstellen und Eigenschaftsübersicht an den Container übergeben
          EJBContainer ec = EJBContainer.createEJBContainer(properties);
          // Containerkontext zum Suchen einer Bean verwenden
          MyBeanIface bean = ec.getContext().lookup(
              "java:global/MyEJBModule/MyBean!my.pkg.MyBeanIface");
          // Methode in der Beaninstanz aufrufen
          bean.doStuff();
          ...
          // Integrierbaren Container schließen
          ec.close();
       }
    }

    Der vorherige Code aktiviert die Sicherheit und erstellt dann zwei Rollen, employee und manager, sowie drei Benutzer, bob, mary und fred. Anschließend gibt der Code an, dass Benutzer fred für die Ausführung in der Rolle manager verwendet wird. Bevor der integrierbare Container erstellt wird, legt er den Aufrufbenutzer fred fest. Das bedeutet, dass EJB-Methoden vom Benutzer fred gestartet werden. Dies bedeutet wiederum, dass fred auf diese Methoden zugreifen kann, wenn diese Methoden die Rolle employee oder manager erfordern.

  6. Ihre Anwendung kann das LTC-Verhalten (Local Transaction Containment, lokaler Transaktionseinschluss) pro Bean angegeben werden. Der lokale Transaktionseinschluss wird im gleichnamigen Artikel beschrieben.

    Im Folgenden sehen Sie ein Beispiel für die Spezifikation des LTC-Resolvers und nicht aufgelöster Aktionen:

    import java.util.HashMap;
    import java.util.Map;
    import javax.ejb.EJBContainer;
    import my.pkg.MyBeanIface; // Lokale Geschäftsschnittstelle der
                               // Enterprise-Bean
    
     public class EmbeddableContainerSample {
    
       public static void main(String[] args) throws Throwable {
    
          // Eigenschaftsübersicht erstellen, die an den integrierbaren Container übergeben wird
          Map<String,Object> properties = new HashMap<String,Object>();
          // Angeben, dass der integrierbare WebSphere-Container verwendet werden soll
          properties.put(EJBContainer.PROVIDER, 
              "com.ibm.websphere.ejbcontainer.EmbeddableContainerProvider");
          
          // Angeben, dass der LTC-Resolver container-at-boundary verwendet werden soll
          properties.put("Bean.myApp1#moduleA#bean101.LocalTransaction.Resolver",
                                                          "ContainerAtBoundary");
          
          // Angeben, dass der LTC nicht aufgelöste Aktionen festschreiben soll
          properties.put("Bean.myApp1#moduleA#bean101.LocalTransaction.UnresolvedAction",
                                                          "Commit");
          
          // Containerinstanz erstellen und Eigenschaftsübersicht an den Container übergeben
          EJBContainer ec = EJBContainer.createEJBContainer(properties);
          // Containerkontext zum Suchen einer Bean verwenden
          MyBeanIface bean = ec.getContext().lookup(
              "java:global/MyEJBModule/MyBean!my.pkg.MyBeanIface");
          // Methode in der Beaninstanz aufrufen
          bean.doStuff();
          ...
          // Integrierbaren Container schließen
          ec.close();
       }
    }

    Der vorherige Code definiert die Resolveraktion für die angegebene Bean auf den vom Standard abweichenden Wert "container-at-boundary" und bewirkt, dass für die nicht aufgelöste Aktion die vom Standard abweichende Aktion verwendet wird, die die Transaktion festschreibt.

    Wenn beim Starten des integrierbaren Containers kein Anwendungsname angegeben wird, muss <Anwendungsname> weggelassen werden. Sie müssen jedoch den Begrenzer # verwenden. Beispiel:
    properties.put("Bean.#moduleA#bean101.LocalTransaction.UnresolvedAction", "Commit"); 

Symbol, das den Typ des Artikels anzeigt. Taskartikel



Symbol für Zeitmarke Letzte Aktualisierung: 25.05.2016
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=tejb_dvemcontainer
Dateiname:tejb_dvemcontainer.html