Einführung in die EJB-JNDI-Suche auf dem WildFly Application Server

Einführung in die EJB-JNDI-Suche auf dem WildFly-Anwendungsserver

1. Überblick

Enterprise Java Beans (EJB) sind der Kernbestandteil vonJava EE specification, um die Entwicklung verteilter Anwendungen auf Unternehmensebene zu vereinfachen. Der Lebenszyklus von EJBs wird von einem Anwendungsserver verwaltet, z. B.JBoss WildFly oderOracle GlassFish.

EJBs bieten ein robustes Programmiermodell, das die Implementierung von Softwaremodulen auf Unternehmensebene erleichtert, da es Sache des Anwendungsservers ist, nicht mit Geschäftslogik zusammenhängende Probleme wie die Transaktionsverarbeitung, das Management des Komponentenlebenszyklus oder die Einfügung von Abhängigkeiten zu behandeln.

Darüber hinaus haben wir bereits zwei Artikel veröffentlicht, die die Grundkonzepte von EJB behandeln. Schauen Sie sich diese alsohere undhere an.

In diesem Tutorial zeigen wir, wie Sie ein grundlegendes EJB-Modul in WildFly implementieren und einen EJB von einem Remote-Client überJNDI aufrufen.

2. Implementierung des EJB-Moduls

Die Geschäftslogik wird entweder über eine oder mehrere lokale / ferne Geschäftsschnittstellen (auch als lokale / ferne Ansichten bezeichnet) oder direkt über Klassen implementiert, die keine Schnittstelle implementieren (keine Ansichtsschnittstellen).

Es ist erwähnenswert, dass lokale Geschäftsschnittstellen verwendet werden, wenn auf die Bean von Clients zugegriffen werden soll, die sich in derselben Umgebung befinden, d. H. dieselbe EAR- oder WAR-Datei, wohingegen entfernte Geschäftsschnittstellen erforderlich sind, wenn von einer anderen Umgebung aus auf das Bean zugegriffen wird, d. h. eine andere JVM oder einen anderen Anwendungsserver.

Erstellen wir ein grundlegendes EJB-Modul, das nur aus einer Bean besteht. Die Geschäftslogik der Bean ist unkompliziert und beschränkt sich auf die Konvertierung eines bestimmtenString in die Großbuchstabenversion.

2.1. Definieren einer Remote-Geschäftsschnittstelle

Definieren wir zunächst eine einzelne Remote-Geschäftsschnittstelle, die mit der Annotation@Remoteverziert ist. Dies ist gemäßEJB 3.x specification obligatorisch, da auf die Bean von einem Remote-Client aus zugegriffen werden soll:

@Remote
public interface TextProcessorRemote {
    String processText(String text);
}

2.2. Eine zustandslose Bohne definieren

Lassen Sie uns als Nächstes die Geschäftslogik durch Implementierung der oben genannten Remote-Schnittstelle realisieren:

@Stateless
public class TextProcessorBean implements TextProcessorRemote {
    public String processText(String text) {
        return text.toUpperCase();
    }
}

Die KlasseTextProcessorBean ist eine einfache Java-Klasse, die mit der Annotation@Statelessverziert ist.

Statuslose Beans behalten per Definition keinen Konversationsstatus mit ihren Clients bei, selbst wenn sie den Instanzstatus für verschiedene Anforderungen beibehalten können. Ihr Gegenstück, Stateful Beans, behält ihren Konversationsstatus bei, und die Erstellung für den Anwendungsserver ist teurer.

Da in diesem Fall die oben genannte Klasse keinen Instanzstatus hat, kann sie zustandslos gemacht werden. Falls es einen Status hat, ist die Verwendung über verschiedene Client-Anforderungen hinweg überhaupt nicht sinnvoll.

Das Verhalten der Bohne ist deterministisch, d. H. Es hat keine Nebenwirkungen, wie es eine gut gestaltete Bohne sein sollte: Es nimmt nur eine EingabeString und gibt die Großbuchstabenversion zurück.

2.3. Maven-Abhängigkeiten

Als Nächstes müssen wir dem Modul dasjavaee-api Maven-Artefakt hinzufügen, das alle Java EE 7-Spezifikations-APIs bereitstellt, einschließlich der für EJBs erforderlichen:


    javax
    javaee-api
    7.0
    provided

Zu diesem Zeitpunkt ist es uns gelungen, ein einfaches, aber funktionales EJB-Modul zu erstellen. Um es allen potenziellen Kunden zur Verfügung zu stellen, müssen wir das Artefakt als JAR-Datei in unser lokales Maven-Repository einfügen.

2.4. Installieren des EJB-Moduls im lokalen Repository

Es gibt verschiedene Methoden, um dies zu erreichen. Am einfachsten ist es, die Build-Phasen des Maven-Lebenszyklusclean – installauszuführen:

mvn clean install

Dieser Befehl installiert das EJB-Modul alsejbmodule-1.0.jar (oder eine beliebige Artefakt-ID, die in der Dateipom.xmlangegeben ist, in unserem lokalen Repository. Weitere Informationen zum Installieren einer lokalen JAR mit Maven finden Sie unterthis article.

Unter der Annahme, dass das EJB-Modul korrekt in unserem lokalen Repository installiert wurde, besteht der nächste Schritt darin, eine Remote-Client-Anwendung zu entwickeln, die dieTextProcessorBean-API verwendet.

3. Remote-EJB-Client

Wir werden die Geschäftslogik des Remote-EJB-Clients äußerst einfach halten: Zunächst wird eine JNDI-Suche durchgeführt, um einenTextProcessorBean-Proxy zu erhalten. Danach wird dieprocessText()-Methode des Proxys aufgerufen.

3.1. Maven-Abhängigkeiten

Wir müssen die folgenden Maven-Artefakte einschließen, damit der EJB-Client wie erwartet funktioniert:


    javax
    javaee-api
    7.0
    provided


    org.wildfly
    wildfly-ejb-client-bom
    10.1.0.Final


    com.beldung.ejbmodule
    ejbmodule
    1.0

Während es ziemlich offensichtlich ist, warum wir das Artefaktjavaee-apieinbeziehen, ist dies bei der Einbeziehung vonwildfly-ejb-client-bomnicht der Fall. The artifact is required for performing remote EJB invocations on WildFly.

Zu guter Letzt müssen wir dem Client das vorherige EJB-Modul zur Verfügung stellen. Deshalb haben wir auch die Abhängigkeit vonejbmodulehinzugefügt.

3.2. EJB-Client-Klasse

In Anbetracht der Tatsache, dass der EJB-Client einen Proxy vonTextProcessorBean aufruft, sind wir sehr pragmatisch und nennen die ClientklasseTextApplication:

public class TextApplication {

    public static void main(String[] args) throws NamingException {
        TextProcessorRemote textProcessor = EJBFactory
          .createTextProcessorBeanFromJNDI("ejb:");
        System.out.print(textProcessor.processText("sample text"));
    }

    private static class EJBFactory {

        private static TextProcessorRemote createTextProcessorBeanFromJNDI
          (String namespace) throws NamingException {
            return lookupTextProcessorBean(namespace);
        }

        private static TextProcessorRemote lookupTextProcessorBean
          (String namespace) throws NamingException {
            Context ctx = createInitialContext();
            String appName = "";
            String moduleName = "EJBModule";
            String distinctName = "";
            String beanName = TextProcessorBean.class.getSimpleName();
            String viewClassName = TextProcessorRemote.class.getName();
            return (TextProcessorRemote) ctx.lookup(namespace
              + appName + "/" + moduleName
              + "/" + distinctName + "/" + beanName + "!" + viewClassName);
        }

        private static Context createInitialContext() throws NamingException {
            Properties jndiProperties = new Properties();
            jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY,
              "org.jboss.naming.remote.client.InitialContextFactory");
            jndiProperties.put(Context.URL_PKG_PREFIXES,
              "org.jboss.ejb.client.naming");
            jndiProperties.put(Context.PROVIDER_URL,
               "http-remoting://localhost:8080");
            jndiProperties.put("jboss.naming.client.ejb.context", true);
            return new InitialContext(jndiProperties);
        }
    }
}

Einfach ausgedrückt, die KlasseTextApplication __ruft lediglich den Bean-Proxy ab und ruft die MethodeprocessText() mit einer Beispielzeichenfolge auf.

Die eigentliche Suche wird von der verschachtelten KlasseEJBFactory durchgeführt, die zuerst eine JNDIInitialContext-Instanz erstellt, dann die erforderlichen JNDI-Parameter an den Konstruktor übergibt und sie schließlich zum Nachschlagen des Bean-Proxys verwendet.

Beachten Sie, dass die Suche mit dem proprietären WildFly-Namespace "ejb:" durchgeführt wird. Dadurch wird der Suchvorgang optimiert, da der Client die Verbindung zum Server so lange verzögert, bis der Proxy explizit aufgerufen wird.

Es ist auch erwähnenswert, dass es möglich ist, den Bean-Proxy nachzuschlagen, ohne auf den Namespace "ejb" zurückzugreifen. we’d be missing all the additional benefits of lazy network connections, thus making the client a lot less performant.

3.3. Einrichten des EJB-Kontexts

Der Client sollte wissen, mit welchem ​​Host und Port eine Verbindung hergestellt werden soll, um die Bean-Suche durchzuführen. Insofern werdenthe client requires setting up the proprietary WildFly EJB context, which is defined with the jboss-ejb-client.properties file in ihrem Klassenpfad abgelegt, normalerweise unter dem Ordnersrc/main/resources:

endpoint.name=client-endpoint
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=default
remote.connection.default.host=127.0.0.1
remote.connection.default.port=8080
remote.connection.default.connect.options.org.xnio.Options
  .SASL_POLICY_NOANONYMOUS=false
remote.connection.default.username=myusername
remote.connection.default.password=mypassword

Die Datei ist ziemlich selbsterklärend, da sie alle Parameter enthält, die zum Herstellen einer Verbindung zu WildFly erforderlich sind, einschließlich der Standardanzahl von Remoteverbindungen, des Standardhosts und -ports sowie der Benutzeranmeldeinformationen. In diesem Fall wird die Verbindung nicht verschlüsselt, es kann jedoch sein, dass SSL aktiviert ist.

Das Letzte, was berücksichtigt werden muss, ist, dassif the connection requires authentication, it’s necessary to add a user to WildFly via the https://docs.jboss.org/author/display/WFLY8/add-user+utility?sscc=t[_add-user.sh/add-user.bat utility].

4. Fazit

Das Durchführen von EJB-Suchvorgängen in WildFly ist unkompliziert, sofern der beschriebene Prozess strikt eingehalten wird.

Wie üblich sind alle in diesem Artikel enthaltenen Beispiele auf GitHubhere undhere verfügbar.