3. Développement de l'application▲
3.1. Création du projet▲
La configuration étant à présent terminée, nous allons pouvoir rentrer dans le vif
du sujet, c'est à dire le développement de notre premier EJB.
La première chose à faire est de créer un nouveau projet.
Pour ce faire, nous devons aller dans le menu "File --> New --> Project".
- Choisissez "Jonas Project"
- Cliquez sur "next"
- Choisissez le nom du projet: par exemple "FirstEJB
- Cliquez sur "next"
- Cochez la case "Create a web application"
- Cliquez sur "Finish"
Voici normalement à quoi ressemblera l'arborescence de votre projet.
3.2. Création de l'EJB▲
Nous allons créer notre premier EJB à l'aide du plugin Jope.
- Aller dans le menu "File --> New --> Jonas EJB"
- Entrez le nom du package. Par exemple "helloWorld"
- Entrez le nom de l'EJB. Par exemple "HelloWorld"
- Entrez le nom de l'archive. Par exemple "helloWorld"
- Cochez la case "Remote"
Vous remarquerez que les différentes classes nécessaires ainsi que le client ont été créés
3.3. Code généré▲
Je vais vous présenter le code généré par le plugin.
Premièrement voici l'interface distante.
Cette interface va contenir toutes les méthodes métier qu'un client peut invoquer sur notre EJB
// HelloWorld.java
package
helloWorld;
import
java.rmi.RemoteException;
import
javax.ejb.EJBObject;
/**
* HelloWorld remote interface
*/
public
interface
HelloWorld extends
EJBObject {
public
void
method1
(
) throws
RemoteException;
public
void
method2
(
java.lang.String s) throws
RemoteException;
}
L'interface d'accueil.
Cette interface définit les méthodes qu'un client peut invoquer pour :
- créer des objets EJB
- trouver les objets EJB existants (pour les beans entité)
- supprimer les objets EJB
// HelloWorldHome.java
package
helloWorld;
import
java.rmi.RemoteException;
import
java.util.Collection;
import
javax.ejb.CreateException;
import
javax.ejb.EJBHome;
import
javax.ejb.FinderException;
/**
* Home interface for the bean HelloWorld
*/
public
interface
HelloWorldHome extends
EJBHome {
HelloWorld create
(
) throws
CreateException, RemoteException;
}
L'EJB qui va contenir toutes les méthodes métiers de notre application.
// HelloWorldEJB.java
// Stateless Session bean
package
helloWorld;
import
java.rmi.RemoteException;
import
java.sql.Connection;
import
java.sql.SQLException;
import
java.sql.Statement;
import
javax.ejb.CreateException;
import
javax.ejb.EJBException;
import
javax.ejb.RemoveException;
import
javax.ejb.EJBObject;
import
javax.ejb.SessionBean;
import
javax.ejb.SessionContext;
import
javax.naming.Context;
import
javax.naming.InitialContext;
import
javax.naming.NamingException;
import
javax.sql.DataSource;
/**
*
*/
public
class
HelloWorldEJB implements
SessionBean {
SessionContext ejbContext;
// ------------------------------------------------------------------
// SessionBean implementation
// ------------------------------------------------------------------
public
void
setSessionContext
(
SessionContext ctx) {
ejbContext =
ctx;
}
public
void
ejbRemove
(
) {
}
public
void
ejbCreate
(
) throws
CreateException {
}
public
void
ejbPassivate
(
) {
}
public
void
ejbActivate
(
) {
}
// ------------------------------------------------------------------
// HelloWorld implementation
// ------------------------------------------------------------------
/**
* method1
*/
public
void
method1
(
) {
}
/**
* method2
*/
public
void
method2
(
java.lang.String s) {
}
}
Le client de l'EJB.
// HelloWorldClient.java
// mini Client for accessing bean HelloWorld
package
helloWorld;
import
java.rmi.RemoteException;
import
java.util.Collection;
import
java.util.Properties;
import
javax.naming.Context;
import
javax.naming.InitialContext;
import
javax.naming.NamingException;
import
javax.rmi.PortableRemoteObject;
/**
*
*/
public
class
HelloWorldClient {
static
Context ctx =
null
;
static
HelloWorldHome home =
null
;
public
static
void
main
(
String[] arg) {
// Get InitialContext
try
{
ctx =
getInitialContext
(
);
}
catch
(
NamingException e) {
e.printStackTrace
(
);
System.exit
(
2
);
}
// Lookup bean home
String bName =
"HelloWorldHome"
;
try
{
home =
(
HelloWorldHome) PortableRemoteObject.narrow
(
ctx.lookup
(
bName), HelloWorldHome.class
);
HelloWorld bean =
home.create
(
);
bean.method1
(
);
}
catch
(
Exception e) {
e.printStackTrace
(
);
System.exit
(
2
);
}
// ...
}
/**
* Using a Properties object will work on JDK 1.1.x and Java2
* clients
*/
static
private
Context getInitialContext
(
) throws
NamingException {
String url =
"rmi://localhost:1099"
;
try
{
// Get an InitialContext
Properties h =
new
Properties
(
);
h.put
(
Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.rmi.registry.RegistryContextFactory"
);
h.put
(
Context.PROVIDER_URL, url);
return
new
InitialContext
(
h);
}
catch
(
NamingException ne) {
ne.printStackTrace
(
);
throw
ne;
}
}
}
Le descripteur de déploiement qui va reprendre les conditions que doivent remplir les composants telles que :
- La gestion du cycle de vie des beans
- La persistance
- le paramétrage des transactions
- ....
<!DOCTYPE ejb-jar PUBLIC
"-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN"
"http://java.sun.com/dtd/ejb-jar_2_0.dtd"
>
<ejb-jar>
<description>
Describe here the content of this file</description>
<display-name>
helloWorld</display-name>
<enterprise-beans>
<session>
<description>
Describe here the session bean HelloWorld</description>
<display-name>
helloWorld/HelloWorldEJB</display-name>
<ejb-name>
HelloWorldEJB</ejb-name>
<home>
helloWorld.HelloWorldHome</home>
<remote>
helloWorld.HelloWorld</remote>
<ejb-class>
helloWorld.HelloWorldEJB</ejb-class>
<session-type>
Stateless</session-type>
<transaction-type>
Container</transaction-type>
<env-entry>
<env-entry-name>
name1</env-entry-name>
<env-entry-type>
java.lang.String</env-entry-type>
<env-entry-value>
value1</env-entry-value>
</env-entry>
<resource-ref>
<res-ref-name>
jdbc/mydb</res-ref-name>
<res-type>
javax.sql.DataSource</res-type>
<res-auth>
Application</res-auth>
</resource-ref>
</session>
</enterprise-beans>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>
HelloWorldEJB</ejb-name>
<method-name>
*</method-name>
</method>
<trans-attribute>
Supports</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>
Le fichier propre à chaque conteneur d'EJB qui est un fichier xml reprenant des fonctions qui ne sont pas traitées par la spécification EJB.
<!DOCTYPE jonas-ejb-jar PUBLIC
"-//ObjectWeb//DTD JOnAS 3.2//EN"
"http://www.objectweb.org/jonas/dtds/jonas-ejb-jar_3_2.dtd"
>
<jonas-ejb-jar>
<jonas-session>
<ejb-name>
HelloWorldEJB</ejb-name>
<jndi-name>
HelloWorldHome</jndi-name>
<jonas-resource>
<res-ref-name>
jdbc/mydb</res-ref-name>
<jndi-name>
jdbc_1</jndi-name>
</jonas-resource>
</jonas-session>
</jonas-ejb-jar>
3.4. Modification du code▲
Nous allons à présent modifier les différentes classes pour que notre client puisse afficher
"Hello World" dans la console d'Eclipse.
Commençons d'abord par modifier l'EJB, en lui ajoutant une méthode qui va retourner un String.
Remplacez les 2 méthodes actuelles
/**
* method1
*/
public
void
method1
(
) {
}
/**
* method2
*/
public
void
method2
(
java.lang.String s) {
}
par cette méthode
public
String hello
(
)
{
return
"Hello World"
;
}
Nous allons également modifier l'interface distante pour que le client puisse appeler la méthode hello(). Remplacez les 2 lignes actuelles
public
void
method1
(
) throws
RemoteException;
public
void
method2
(
java.lang.String s) throws
RemoteException;
par cette ligne.
public
String hello
(
) throws
RemoteException;
Modification du client pour qu'il appelle la méthode de l'EJB qui va permettre d'afficher "Hello World".
Remplacez la méthode
bean.method1
(
);
par cette ligne.
System.out.println
(
bean.hello
(
));
Une personne m'a judicieusement fait remarquer qu'une NamingException était capturée et affichée 2 fois, ce qui est inutile.
Remplacez simplement cette méthode
static
private
Context getInitialContext
(
)throws
NamingException{
String url =
"rmi://localhost:1099"
;
try
{
// Get an InitialContext
Properties h =
new
Properties
(
);
h.put
(
Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.rmi.registry.RegistryContextFactory"
);
h.put
(
Context.PROVIDER_URL, url);
return
new
InitialContext
(
h);
}
catch
(
NamingException ne)
{
ne.printStackTrace
(
);
throw
ne;
}
}
par celle-ci.
static
private
Context getInitialContext
(
)throws
NamingException{
String url =
"rmi://localhost:1099"
;
// Get an InitialContext
Properties h =
new
Properties
(
);
h.put
(
Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.rmi.registry.RegistryContextFactory"
);
h.put
(
Context.PROVIDER_URL, url);
return
new
InitialContext
(
h);
}
Il ne reste plus enfin qu'à enlever certaines lignes inutiles dans les descripteurs de déploiement.
- Les balises décrivant les propriétés d'environnement dans le fichier helloWorld.xml.
<env-entry>
<env-entry-name>
name1</env-entry-name>
<env-entry-type>
java.lang.String</env-entry-type>
<env-entry-value>
value1</env-entry-value>
</env-entry>
- Les balises déclarant les références à la fabrique de ressources dans le fichier helloWorld.xml. Inutile dans notre cas puisque nous n'utilisons pas par exemple de connexion JDBC
<resource-ref>
<res-ref-name>
jdbc/mydb</res-ref-name>
<res-type>
javax.sql.DataSource</res-type>
<res-auth>
Application</res-auth>
</resource-ref>
-
Les balises déclarant la ressource qui est mentionnée dans le code de notre EJB.
Comme nous n'avons pas déclaré de ressources dans notre code, cette balise ne sert strictement à rien.
<jonas-resource>
<res-ref-name>
jdbc/mydb</res-ref-name>
<jndi-name>
jdbc_1</jndi-name>
</jonas-resource>
Votre EJB est enfin prêt.