Guide de configuration des EJB

1. Vue d'ensemble

Dans cet article, nous allons expliquer comment démarrer avec le développement Enterprise JavaBean (EJB).

Les Enterprise JavaBeans sont utilisés pour développer des composants évolutifs, distribués, côté serveur et encapsulent généralement la logique métier de l'application.

Nous utiliserons WildFly 10.1.0 comme notre solution de serveur préférée, cependant, vous êtes libre d'utiliser n'importe quel serveur d'applications Java Enterprise de votre choix.

2. Configuration

Commençons par discuter des dépendances Maven requises pour le développement EJB 3.2 et comment configurer le serveur d'applications WildFly à l'aide du plugin Maven Cargo ou manuellement.

2.1. Dépendance de Maven

Pour utiliser EJB 3.2 , assurez-vous d'ajouter la dernière version à la section des dépendances de votre fichier pom.xml :

 javax javaee-api 7.0 provided 
Vous trouverez la dernière dépendance dans le référentiel Maven. Cette dépendance garantit que toutes les API Java EE 7 sont disponibles pendant la compilation. L' étendue fournie garantit qu'une fois déployée, la dépendance sera fournie par le conteneur où elle a été déployée.

2.2. Configuration WildFly avec Maven Cargo

Parlons de la façon d'utiliser le plugin Maven Cargo pour configurer le serveur.

Voici le code du profil Maven qui provisionne le serveur WildFly:

 wildfly-standalone    org.codehaus.cargo cargo-maven2-plugin ${cargo-maven2-plugin.version   wildfly10x   //download.jboss.org/ wildfly/10.1.0.Final/ wildfly-10.1.0.Final.zip      127.0.0.0  9990   testUser:admin1234!         

Nous utilisons le plugin pour télécharger le zip WildFly 10.1 directement depuis le site Web de WildFly. Qui est ensuite configuré, en s'assurant que le nom d'hôte est 127.0.0.1 et en définissant le port sur 9990.

Ensuite, nous créons un utilisateur de test, en utilisant la propriété cargo.servlet.users , avec l'ID utilisateur testUser et le mot de passe admin1234 !.

Maintenant que la configuration du plugin est terminée, nous devrions pouvoir appeler une cible Maven et faire télécharger, installer, lancer le serveur et déployer l'application.

Pour ce faire, accédez au répertoire ejb-remote et exécutez la commande suivante:

mvn clean package cargo:run

Lorsque vous exécutez cette commande pour la première fois, elle télécharge le fichier zip WildFly 10.1, l'extrait et exécute l'installation, puis la lance. Il ajoutera également l'utilisateur de test décrit ci-dessus. Toute autre exécution ne téléchargera pas à nouveau le fichier zip.

2.3. Configuration manuelle de WildFly

Pour configurer WildFly manuellement, vous devez télécharger vous-même le fichier zip d'installation à partir du site Web wildfly.org. Les étapes suivantes sont une vue d'ensemble du processus de configuration du serveur WildFly:

Après avoir téléchargé et décompressé le contenu du fichier à l'emplacement où vous souhaitez installer le serveur, configurez les variables d'environnement suivantes:

JBOSS_HOME=/Users/$USER/../wildfly.x.x.Final JAVA_HOME=`/usr/libexec/java_home -v 1.8`

Ensuite, dans le répertoire bin , exécutez ./standalone.sh pour les systèmes d'exploitation Linux ou ./standalone.bat pour Windows.

Après cela, vous devrez ajouter un utilisateur. Cet utilisateur sera utilisé pour se connecter au bean EJB distant. Pour savoir comment ajouter un utilisateur, vous devriez jeter un œil à la documentation «ajouter un utilisateur».

Pour obtenir des instructions de configuration détaillées, veuillez consulter la documentation de mise en route de WildFly.

Le projet POM a été configuré pour fonctionner avec le plugin Cargo et la configuration manuelle du serveur en définissant deux profils. Par défaut, le plugin Cargo est sélectionné. Cependant, pour déployer l'application sur un serveur Wildfly déjà installé, configuré et en cours d'exécution, exécutez la commande suivante dans le répertoire ejb-remote :

mvn clean install wildfly:deploy -Pwildfly-runtime

3. À distance vs local

Une interface métier pour un bean peut être locale ou distante.

Un bean annoté @Local n'est accessible que s'il se trouve dans la même application que le bean qui fait l'appel, c'est-à-dire s'ils résident dans le même .ear ou .war .

Un bean annoté @Remote est accessible depuis une autre application, c'est-à-dire une application résidant dans une JVM ou un serveur d'applications différent .

Il y a quelques points importants à garder à l'esprit lors de la conception d'une solution qui inclut des EJB:

  • Les interfaces java.io.Serializable , java.io.Externalizable et définies par le package javax.ejb sont toujours exclues lorsqu'un bean est déclaré avec @Local ou @Remote
  • Si une classe de bean est distante, toutes les interfaces implémentées doivent être distantes
  • Si une classe de bean ne contient aucune annotation ou si l' annotation @Local est spécifiée, alors toutes les interfaces implémentées sont supposées être locales
  • Toute interface explicitement définie pour un bean qui ne contient aucune interface doit être déclarée comme @Local
  • La version EJB 3.2 tend à fournir plus de granularité pour les situations où les interfaces locales et distantes doivent être explicitement définies

4. Création de l' EJB distant

Créons d'abord l'interface du bean et appelons-la HelloWorld:

@Remote public interface HelloWorld { String getHelloWorld(); }

Nous allons maintenant implémenter l'interface ci-dessus et nommer l'implémentation concrète HelloWorldBean:

@Stateless(name = "HelloWorld") public class HelloWorldBean implements HelloWorld { @Resource private SessionContext context; @Override public String getHelloWorld() { return "Welcome to EJB Tutorial!"; } }

Note the @Stateless annotation on the class declaration. It denotes that this bean is a stateless session bean. This kind of bean does not have any associated client state, but it may preserve its instance state and is normally used to do independent operations.

The @Resource annotation injects the session context into the remote bean.

The SessionContext interface provides access to the runtime session context that the container provides for a session bean instance. The container then passes the SessionContext interface to an instance after the instance has been created. The session context remains associated with that instance for its lifetime.

The EJB container normally creates a pool of stateless bean's objects and uses these objects to process client requests. As a result of this pooling mechanism, instance variable values are not guaranteed to be maintained across lookup method calls.

5. Remote Setup

In this section, we will discuss how to setup Maven to build and run the application on the server.

Let's look at the plugins one by one.

5.1. The EJB Plugin

The EJB plugin which is given below is used to package an EJB module. We have specified the EJB version as 3.2.

The following plugin configuration is used to setup the target JAR for the bean:

 maven-ejb-plugin 2.4  3.2  

5.2. Deploy the Remote EJB

To deploy the bean in a WildFly server ensure that the server is up and running.

Then to execute the remote setup we will need to run the following Maven commands against the pom file in the ejb-remote project:

mvn clean install 

Then we should run:

mvn wildfly:deploy

Alternatively, we can deploy it manually as an admin user from the admin console of the application server.

6. Client Setup

After creating the remote bean we should test the deployed bean by creating a client.

First, let's discuss the Maven setup for the client project.

6.1. Client-Side Maven Setup

In order to launch the EJB3 client we need to add the following dependencies:

 org.wildfly wildfly-ejb-client-bom pom import 

We depend on the EJB remote business interfaces of this application to run the client. So we need to specify the EJB client JAR dependency. We add the following in the parent pom:

 com.baeldung.ejb ejb-remote ejb 

The is specified as ejb.

6.2. Accessing the Remote Bean

We need to create a file under src/main/resources and name it jboss-ejb-client.properties that will contain all the properties that are required to access the deployed bean:

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.connect.options.org.xnio.Options .SASL_POLICY_NOPLAINTEXT = false remote.connection.default.connect.options.org.xnio.Options .SASL_DISALLOWED_MECHANISMS = ${host.auth:JBOSS-LOCAL-USER} remote.connection.default.username=testUser remote.connection.default.password=admin1234! 

7. Creating the Client

The class that will access and use the remote HelloWorld bean has been created in EJBClient.java which is in the com.baeldung.ejb.client package.

7.1 Remote Bean URL

The remote bean is located via a URL that conforms to the following format:

ejb:${appName}/${moduleName}/${distinctName}/${beanName}!${viewClassName}
  • The ${appName} is the application name of the deployment. Here we have not used any EAR file but a simple JAR or WAR deployment, so the application name will be empty
  • The ${moduleName} is the name we set for our deployment earlier, so it is ejb-remote
  • The ${distinctName} is a specific name which can be optionally assigned to the deployments that are deployed on the server. If a deployment doesn't use distinct-name then we can use an empty String in the JNDI name, for the distinct-name, as we did in our example
  • The ${beanName} variable is the simple name of the implementation class of the EJB, so in our example it is HelloWorld
  • ${viewClassName} denotes the fully-qualified interface name of the remote interface

7.2 Look-up Logic

Next, let's have a look at our simple look-up logic:

public HelloWorld lookup() throws NamingException { String appName = ""; String moduleName = "remote"; String distinctName = ""; String beanName = "HelloWorld"; String viewClassName = HelloWorld.class.getName(); String toLookup = String.format("ejb:%s/%s/%s/%s!%s", appName, moduleName, distinctName, beanName, viewClassName); return (HelloWorld) context.lookup(toLookup); }

In order to connect to the bean we just created, we will need a URL which we can feed into the context.

7.3 The Initial Context

We'll now create/initialize the session context:

public void createInitialContext() throws NamingException { Properties prop = new Properties(); prop.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming"); prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFacto[ERROR] prop.put(Context.PROVIDER_URL, "http-remoting://127.0.0.1:8080"); prop.put(Context.SECURITY_PRINCIPAL, "testUser"); prop.put(Context.SECURITY_CREDENTIALS, "admin1234!"); prop.put("jboss.naming.client.ejb.context", false); context = new InitialContext(prop); }

To connect to the remote bean we need a JNDI context. The context factory is provided by the Maven artifact org.jboss:jboss-remote-naming and this creates a JNDI context, which will resolve the URL constructed in the lookup method, into proxies to the remote application server process.

7.4 Define Lookup Parameters

We define the factory class with the parameter Context.INITIAL_CONTEXT_FACTORY.

The Context.URL_PKG_PREFIXES is used to define a package to scan for additional naming context.

The parameter org.jboss.ejb.client.scoped.context = false tells the context to read the connection parameters (such as the connection host and port) from the provided map instead of from a classpath configuration file. This is especially helpful if we want to create a JAR bundle that should be able to connect to different hosts.

The parameter Context.PROVIDER_URL defines the connection schema and should start with http-remoting://.

8. Testing

To test the deployment and check the setup, we can run the following test to make sure everything works properly:

@Test public void testEJBClient() { EJBClient ejbClient = new EJBClient(); HelloWorldBean bean = new HelloWorldBean(); assertEquals(bean.getHelloWorld(), ejbClient.getEJBRemoteMessage()); }

With the test passing, we can now be sure everything is working as expected.

9. Conclusion

Nous avons donc créé un serveur EJB et un client qui invoque une méthode sur un EJB distant. Le projet peut être exécuté sur n'importe quel serveur d'applications en ajoutant correctement les dépendances de ce serveur.

L'ensemble du projet peut être trouvé sur GitHub.