III. Développement de l'application▲
III-A. 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.
III-B. Création de l'EJB▲
Nous allons créer notre premier EJB à l'aide du plugin Jope.
- Allez 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.
III-C. 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étier 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>
III-D. 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 par modifier l'EJB, en lui ajoutant une méthode qui va retourner un String. Remplacez les deux 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 deux 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 deux 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.