|
Cadre Fonctionnel |
Développement d’un session bean utilisant l’API JMS |
|
Cadre Technique |
NT / JMS, JonAS (Java Open Application Server), Joram |
|
Identifiant |
JMS_EJB_01 |
|
Référent technique |
|
|
Version |
1.0 |
|
Auteur |
Alexandre Brillant |
|
Date |
04/01 |
|
Source |
Documentation Joram, http://developer.java.sun.com/ |
|
Cibles |
|
|
Dépendance |
Cet exemple délimite l’utilisation de l’API JMS dans jonas. Il reste cependant un exemple standard pour la transmission d’un message via un session bean.
La réception de message ne peut cependant pas se faire de manière asynchrone avec Jonas car cela nécéssite l’utilisation de l’API EJB 2.0 et en particulier le support d’un message-driven bean (MDB).
Ces programmes nécéssitent pour leur exécution les serveurs Jonas et Joram. Reportez-vous à la fiche INS_EJB_01 pour connaître la démarche d’installation.
package hexadev;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
/**
* Interface de gestion du cycle de vie du bean.
*/
public interface AbHome extends EJBHome {
/**
* Création d'un bean de type Ab
*/
Ab create() throws CreateException, RemoteException;
}
|
package hexadev;
import java.rmi.RemoteException;
import javax.ejb.EJBObject;
/**
* Interface pour le client distant. Ce bean permet
* l'émission d'un message avec l'API JMS
*/
public interface Ab extends EJBObject {
/**
* Exemple de publication d'un message
*/
public void publishMessage(String value) throws RemoteException;
}
|
package hexadev;
import java.rmi.RemoteException;
import javax.ejb.*;
import javax.naming.*;
import javax.jms.Topic;
import javax.jms.*;
/**
Exemple d'implémentation d'un session bean
réalisant la transmission d'un Message.
Utiliser le programme JMSAdmin pour amorcer
un Topic et une TopicConnectionFactory
*/
public class AbBean implements SessionBean {
protected SessionContext sessionContext = null;
protected org.objectweb.jonas.jms.TopicConnectionFactory factory = null;
protected Topic topic = null;
/**
* Création du Bean
*/
public void ejbCreate() {
try {
InitialContext ctx = new InitialContext();
Object _obj = ctx.lookup( "java:comp/env/jms/TopicFact" );
factory = ( org.objectweb.jonas.jms.TopicConnectionFactory) _obj;
_obj = ctx.lookup( "Topic1" );
topic = (Topic)_obj;
} catch( Exception exc ) {
System.err.println( exc.getMessage() );
exc.printStackTrace();
}
}
/**
* Activation du bean
*/
public void ejbActivate() {
}
/**
* Désactivation du bean
*/
public void ejbPassivate() {
}
/**
* Suppression du bean
*/
public void ejbRemove() {
}
/**
* Récupère le contexte du bean. Utilisable pour
récupérer des
* propriétés statiques du fichier ejb-jar.xml
*/
public void setSessionContext(SessionContext sessionContext) {
this.sessionContext = sessionContext;
}
/**
* Exemple de publication d'un message
*/
public void publishMessage( String value ) {
try {
javax.jms.TopicConnection tc =
(javax.jms.TopicConnection)factory.createTopicConnection();
tc.start();
javax.jms.TopicSession session =
(javax.jms.TopicSession)tc.createTopicSession( false,
Session.AUTO_ACKNOWLEDGE );
TextMessage text = session.createTextMessage( value );
// Création d'un agent de transmission du message
javax.jms.TopicPublisher tp =
(javax.jms.TopicPublisher)session.createPublisher( topic );
tp.publish( text );
session.close();
tc.close();}
catch( Exception exc ) {
exc.printStackTrace();
}
}
}
|
Remarque : Dans cet exemple, jms/TopicFact lors de la création du session bean représente un accès vers une factory de connection JMS. Cette dernière est déclarée dans le descripteur jonas-ejb-jar.xml.
Fichier ejb-jar.xml :
<!DOCTYPE ejb-jar SYSTEM "ejb-jar_1_1.dtd">
<ejb-jar>
<description>Exemple AB</description>
<enterprise-beans>
<session>
<ejb-name>Ab</ejb-name>
<home>hexadev.AbHome</home>
<remote>hexadev.Ab</remote>
<ejb-class>hexadev.AbBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
<env-entry>
<env-entry-name>prop1</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>prop1 value</env-entry-value>
</env-entry>
<resource-ref>
<res-ref-name>jms/TopicFact</res-ref-name>
<res-type>javax.jms.TopicConnectionFactory</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</Sessionp>
</enterprise-beans>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>Ab</ejb-name>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>
|
Fichier jonas-ejb-jar.xml :
<!DOCTYPE jonas-ejb-jar SYSTEM "jonas-ejb-jar.dtd">
<jonas-ejb-jar>
<jonas-session>
<ejb-name>Ab</ejb-name>
<jndi-name>AbHome</jndi-name>
<jonas-resource>
<res-ref-name>jms/TopicFact</res-ref-name>
<jndi-name>TopicFactory1</jndi-name>
</jonas-resource>
</jonas-session>
</jonas-ejb-jar>
|
package hexadev;
import javax.naming.InitialContext;
import javax.naming.Context;
import javax.rmi.PortableRemoteObject;
/**
* Exemple de client pour le bean Ab
*/
public class ClientAb {
public static void main(String args[]) {
// Contexte de communication avec le serveur EJB
Context initialContext = null;
AbHome home = null;
try {
initialContext = new InitialContext();
home = ( AbHome )PortableRemoteObject.narrow(
initialContext.lookup( "AbHome" ),
hexadev.AbHome.class);
} catch (Exception e) {
e.printStackTrace();
}
Ab ab1 = null;
try {
// Création du bean
ab1 = home.create();
// Utilisation
ab1.publishMessage( "Test1"
);
// Suppression
ab1.remove();
} catch (Exception e) {
e.printStackTrace();
}
}
}
|
package hexadev;
import javax.jms.*;
import javax.naming.*;
import fr.dyade.aaa.joram.XATopicConnectionFactory;
import fr.dyade.aaa.joram.Admin;
import org.objectweb.jonas.jms.TopicConnectionFactory;
/**
Connection au serveur MOM et déclaration
de files de messages via le service de désignation
JNDI( Java Naming Directory Interfaces )
*/
public class JMSAdmin {
public static void main( String[] args ) throws Exception {
System.out.println( "Starting JMSAdmin..." );
// Connexion au serveur MOM joram
Admin admin = new Admin();
// Création d'une factory de files de message supportant des
// transactions par un serveur EJB
XATopicConnectionFactory topicFactory = admin.createXATopicAgentClient();
// Création d'une file
boolean again = true;
Topic topic = null;
while( again ) {
try {
topic = topicFactory.createNewTopic();
again = false;
break;
} catch( Exception exc ) {}
}
System.out.println( "Topic created ..." );
admin.close();
// Déclaration de la file de messages dans JNDI
InitialContext context = new InitialContext();
String internalConnectionFactory = "TopicFactoryRef1";
context.rebind( internalConnectionFactory, topicFactory );
// Création d'une factory propre à Jonas utisant la filede messages QueueFactory1
TopicConnectionFactory jonasFactory = new TopicConnectionFactory( internalConnectionFactory );
context.rebind( "TopicFactory1", jonasFactory );
context.rebind( "Topic1", topic );
}
}
|
Remarque : Ce programme n’a qu’un rôle de référencement sur JNDI d’un « Topic » et d’une factory
Créer le répertoire classes.
Rem Check environment variables: if "%JONAS_ROOT%"=="" Goto SetRoot @Echo on Rem set the Environment Variables set XTRA_CLASSPATH=classes call %JONAS_ROOT%\bin\nt\config_env.bat @Echo on Rem Compiles the source files javac -d classes Ab.java AbBean.java AbHome.java ClientAb.java JMSAdmin.java @Echo on Rem Generates the interposition classes and compiles them call %JONAS_ROOT%\bin\nt\GenIC.bat -d classes ejb-jar.xml @Echo off Goto End :SetRoot @echo "JONAS_ROOT must be set" Goto End :End |
Test :
1°) Mettre à jour la variable d’environnement XTRA_CLASSPATH pour contenir le répertoire classes
2°) Exécuter rmiregistry
3°) Exécuter EJBServer
4°) Exécuter le serveur Joram :
start "Server AAA" call java -DTransaction=NullTransaction fr.dyade.aaa.agent.AgentServer 0 ./s0 |
5°) Exécuter le programme d’administation :
start java hexadev.JMSAdmin
6°) Exécuter le client de test :
java hexadev.ClientAb