Inleiding tot EJB JNDI Lookup op WildFly Application Server

1. Overzicht

Enterprise Java Beans (EJB) vormen het kernonderdeel van de Java EE-specificatie, gericht op het vereenvoudigen van de ontwikkeling van gedistribueerde applicaties op bedrijfsniveau. De levenscyclus van EJB's wordt afgehandeld door een applicatieserver, zoals JBoss WildFly of Oracle GlassFish.

EJB's bieden een robuust programmeermodel dat de implementatie van softwaremodules op bedrijfsniveau vergemakkelijkt, aangezien het aan de applicatieserver is om problemen met niet-zakelijke logica, zoals transactieafhandeling, beheer van de levenscyclus van componenten of injectie van afhankelijkheden, af te handelen.

Verder hebben we al twee artikelen gepubliceerd over de basisconcepten van EJB, dus bekijk ze gerust hier en hier.

In deze zelfstudie laten we zien hoe u een eenvoudige EJB-module op WildFly implementeert en een EJB aanroept vanaf een externe client via een JNDI.

2. Implementatie van de EJB-module

Bedrijfslogica wordt geïmplementeerd door een of meerdere lokale / externe bedrijfsinterfaces (ook bekend als lokale / externe weergaven) of rechtstreeks via klassen die geen interface implementeren (niet-weergave-interfaces).

Het is vermeldenswaard dat lokale bedrijfsinterfaces worden gebruikt wanneer de bean wordt benaderd vanaf clients die zich in dezelfde omgeving bevinden, dwz hetzelfde EAR- of WAR-bestand, terwijl externe bedrijfsinterfaces vereist zijn wanneer de bean wordt benaderd vanuit een andere omgeving. , dwz een andere JVM- of applicatieserver.

Laten we een eenvoudige EJB-module maken, die uit slechts één boon zal bestaan. De bedrijfslogica van de boon is eenvoudig en beperkt tot het converteren van een bepaald gegeven Draad naar de hoofdletterversie.

2.1. Een externe bedrijfsinterface definiëren

Laten we eerst een enkele zakelijke interface op afstand definiëren, versierd met de @Remote annotatie. Dit is verplicht volgens de EJB 3.x-specificatie, aangezien de bean zal worden benaderd vanaf een externe client:

@Remote openbare interface TextProcessorRemote {String processText (String-tekst); }

2.2. Een staatloze boon definiëren

Laten we vervolgens de bedrijfslogica realiseren door de bovengenoemde externe interface te implementeren:

@Stateless openbare klasse TextProcessorBean implementeert TextProcessorRemote {openbare String processText (String-tekst) {return text.toUpperCase (); }}

De TextProcessorBean class is een eenvoudige Java-klasse, versierd met de @Stateless annotatie.

Staatloze bonen onderhouden per definitie geen conversatiestatus met hun klanten, zelfs niet als ze de instantiestatus voor verschillende verzoeken kunnen behouden. Hun tegenhanger, stateful beans, behoudt hun gesprekstoestand en omdat ze duurder zijn om te maken voor de applicatieserver.

Omdat in dit geval de bovenstaande klasse geen instantiestatus heeft, kan deze staatloos worden gemaakt. In het geval dat het een status heeft, zou het helemaal geen zin hebben om het voor verschillende klantverzoeken te gebruiken.

Het gedrag van de boon is deterministisch, d.w.z. het heeft geen bijwerkingen, zoals een goed ontworpen boon zou moeten zijn: er is alleen input voor nodig Draad en geeft de versie in hoofdletters terug.

2.3. Afhankelijkheden van Maven

Vervolgens moeten we het javaee-api Maven-artefact naar de module, die alle Java EE 7-specificatie-API's biedt, inclusief degene die vereist zijn voor EJB's:

 javax javaee-api 7.0 voorzien 

Op dit moment zijn we erin geslaagd om een ​​eenvoudige, maar functionele EJB-module te maken. Om het beschikbaar te maken voor alle potentiële klanten, moeten we het artefact toevoegen aan onze lokale Maven-repository als een JAR-bestand.

2.4. De EJB-module in de lokale repository installeren

Er zijn verschillende methoden om dit te bereiken. De meest eenvoudige bestaat uit het uitvoeren van de Maven-levenscyclus schoon - installeer bouwfasen:

mvn schone installatie

Deze opdracht installeert de EJB-module als ejbmodule-1.0.jar (of een willekeurig artefact-ID gespecificeerd in het pom.xml bestand), naar onze lokale repository. Lees dit artikel voor meer informatie over het installeren van een lokale JAR met Maven.

Ervan uitgaande dat de EJB-module correct is geïnstalleerd in onze lokale repository, is de volgende stap het ontwikkelen van een externe clienttoepassing die gebruik maakt van onze TextProcessorBean API.

3. Externe EJB-client

We houden de bedrijfslogica van de externe EJB-client uiterst eenvoudig: ten eerste voert hij een JNDI-zoekopdracht uit om een TextProcessorBean proxy. Daarna roept het de volmachten op processText () methode.

3.1. Afhankelijkheden van Maven

We moeten de volgende Maven-artefacten opnemen om de EJB-client te laten werken zoals verwacht:

 javax javaee-api 7.0 leverde org.wildfly wildfly-ejb-client-bom 10.1.0.Final com.beldung.ejbmodule ejbmodule 1.0 

Hoewel het vrij duidelijk is waarom we de javaee-api artefact, de opname van wildfly-ejb-client-bom is niet. Het artefact is vereist voor het uitvoeren van externe EJB-aanroepen op WildFly.

Last but not least moeten we de vorige EJB-module beschikbaar maken voor de klant, daarom hebben we de ejbmodule afhankelijkheid ook.

3.2. EJB-klantklasse

Gezien het feit dat de EJB-client een proxy van TextProcessorBean, we zullen heel pragmatisch zijn en de cliëntklasse een naam geven TextApplication:

openbare klasse TextApplication {openbare statische leegte hoofd (String [] args) gooit NamingException {TextProcessorRemote textProcessor = EJBFactory .createTextProcessorBeanFromJNDI ("ejb:"); System.out.print (textProcessor.processText ("voorbeeldtekst")); } privé statische klasse EJBFactory {privé statische TextProcessorRemote createTextProcessorBeanFromJNDI (String naamruimte) gooit NamingException {terug lookupTextProcessorBean (naamruimte); } privé statische TextProcessorRemote lookupTextProcessorBean (String naamruimte) gooit 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 () gooit 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); retourneer nieuwe InitialContext (jndiProperties); }}}

Simpel gezegd, alles wat de TextApplicationclass is het ophalen van de bean-proxy en roept zijn processText () methode met een voorbeeldstring.

De daadwerkelijke zoekactie wordt uitgevoerd door de geneste klasse EJBFactory, die eerst een JNDI maakt InitialContext instantie, geeft vervolgens de vereiste JNDI-parameters door aan de constructor en gebruikt deze ten slotte om de bean-proxy op te zoeken.

Merk op dat de zoekopdracht wordt uitgevoerd met behulp van WildFly's eigen "ejb:" -naamruimte. Dit optimaliseert het opzoekproces, aangezien de client de verbinding met de server uitstelt totdat de proxy expliciet wordt aangeroepen.

Het is ook vermeldenswaard dat het mogelijk is om de bean-proxy op te zoeken zonder de naamruimte "ejb" te gebruiken. Echter, we zouden alle extra voordelen van luie netwerkverbindingen missen, waardoor de klant een stuk minder presteert.

3.3. De EJB-context instellen

De client moet weten met welke host en poort een verbinding tot stand moet worden gebracht om de bean-lookup uit te voeren. In zoverre, de client vereist het instellen van de gepatenteerde WildFly EJB-context, die wordt gedefinieerd met de jboss-ejb-client.properties het dossier geplaatst in het klassenpad, meestal onder de src / main / resources map:

endpoint.name = client-endpoint remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED = false remote.connections = standaard 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 = mijngebruikersnaam remote.connection.default.password = mijnwachtwoord

Het bestand spreekt voor zich, omdat het alle parameters bevat die nodig zijn om een ​​verbinding met WildFly tot stand te brengen, inclusief het standaardaantal externe verbindingen, de standaardhost en -poort en de gebruikersreferenties. In dit geval is de verbinding niet gecodeerd, maar dit kan gebeuren wanneer SSL is ingeschakeld.

Het laatste waar u rekening mee moet houden, is dat als de verbinding authenticatie vereist, is het nodig om een ​​gebruiker aan WildFly toe te voegen via de add-user.sh/add-user.bat nut.

4. Conclusie

Het uitvoeren van EJB-lookups op WildFly is eenvoudig, zolang we ons strikt aan het beschreven proces houden.

Zoals gewoonlijk zijn alle voorbeelden in dit artikel hier en hier beschikbaar op GitHub.