Publier un message JMS dans Glassfish v3 avec appclient et ANT

Dans cet article, vous trouverez comment envoyer des messages dans une file d’attente JMS de Glassfish 3.0.1 en injectant directement les informations de configuration au moyen d’annotations. Vous trouverez également les informations nécessaires au déploiement des bibliothèques clients Glassfish. Le reste, comme l’implémentation d’un MDB n’est qu’un jeu d’enfants

Installer appclient

Pour installer appclient sur votre poste client, il faut commencer par régénérer le fichier appclient.jar sur le serveur Glassfish puis le pousser. Dans notre exemple, client et serveur sont la même machine ce qui permet de travailler sur l’adresse localhost et sans mot de passe :

$GLASSFISH_HOME/glassfish/bin# ./package-appclient
Replacing <GLASSFISH_HOME>/glassfish/lib/appclient.jar

Pour installer appclient, décompresser simplement le .jar associé :

cd /home/arkzoyd/arkzoyd-project
jar xvf GLASSFISH_HOME/glassfish/lib/appclient.jar

Créer une ConnectionFactory et une Queue JMS dans Glassfish

Configurer le serveur Glassfish; créer une Connection Factory JMS avec les paramètres ci-dessous :

  • Pool Name : jms/myConnectionFactory
  • Resource Type : javax.jms.ConnectionFactory

Créer une ensuite une destination JMS avec les paramètres ci-dessous :

  • JNDI Name: jms/myQueue
  • Physical Destination Name : myQueue
  • Resource Type : javax.jms.Queue

Créer une application cliente

Voici le code d’une application cliente dans le fichier src/client/SimpleMessageClient.java; l’application utilise les annotations pour configurer les informations d’accès à la connection factory et à la queue :

import javax.jms.ConnectionFactory;
import javax.jms.Queue;
import javax.jms.Connection;
import javax.jms.Session;
import javax.jms.MessageProducer;
import javax.jms.TextMessage;
import javax.jms.JMSException;
import javax.annotation.Resource;


public class SimpleMessageClient {
@Resource(mappedName = "jms/myConnectionFactory")
private static ConnectionFactory connectionFactory;
@Resource(mappedName = "jms/myQueue")
private static Queue queue;

public static void main(String[] args) {
Connection connection = null;
Session session = null;
MessageProducer messageProducer = null;
TextMessage message = null;
final int NUM_MSGS = 3;

try {
connection = connectionFactory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
messageProducer = session.createProducer(queue);
message = session.createTextMessage();

for (int i = 0; i < NUM_MSGS; i++) {
message.setText("This is message " + (i + 1));
System.out.println("Sending message: " + message.getText());
messageProducer.send(message);
}

System.out.println("To see if the bean received the messages,");
System.out.println(
" check <install_dir>/domains/domain1/logs/server.log.");
} catch (Exception e) {
System.out.println("Exception occurred: " + e.toString());
} finally {
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
}
}
System.exit(0);
}
}
}

Créer un fichier ANT

Le fichier build.xml ci-dessous donne un exemple de configuration des tâches de compilation (avec les bibliothèques JMS) puis d’exécution sous Linux avec le script appclient :

<?xml version="1.0" encoding="UTF-8"?>
<project>
<!-- Change the properties below to fit to your project context -->
<property name="app.name" value="project4"/>
<!-- Make sure the ENVIRONMENT variables are set correctly -->
<property environment="env"/>
<property name="clientdir" value="/home/arkzoyd/arkzoyd-project/appclient"/>
<property name="src.dir" value="src"/>
<property name="appclient" value="${clientdir}/glassfish/bin/appclient"/>

<target name="compile">
<mkdir dir="build/client/classes"/>
<javac srcdir="src/client" destdir="build/client/classes">
<classpath>
<pathelement location="${clientdir}/glassfish/modules/javax.ejb.jar"/>
<pathelement location="${clientdir}/glassfish/modules/javax.jms.jar"/>
</classpath>
</javac>
</target>

<target name="jar" depends="compile">
<mkdir dir="build/jar"/>
<jar destfile="build/jar/${app.name}-client.jar" basedir="build/client/classes">
<manifest>
<attribute name="Main-Class" value="SimpleMessageClient"/>
</manifest>
</jar>
</target>

<target name="run" depends="jar">
<echo message="running application client container."/>
<exec executable="${appclient}">
<arg line="-client 'build/jar/${app.name}-client.jar'"/>
</exec>
</target>

</project>

Compiler, packager et exécuter le client java

Vous voilà prêt à exécuter le client et insérer des messages dans votre file d’attente JMS :

ant run
Buildfile: /home/arkzoyd/arkzoyd-project/project4/build.xml

compile:
[javac] /home/arkzoyd/arkzoyd-project/project4/build.xml:13: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds

jar:

run:
[echo] running application client container.
[exec] Aug 1, 2010 11:46:59 PM com.sun.enterprise.transaction.JavaEETransactionManagerSimplified initDelegates
[exec] INFO: Using com.sun.enterprise.transaction.jts.JavaEETransactionManagerJTSDelegate as the delegate
[exec] Aug 1, 2010 11:47:04 PM com.sun.enterprise.connectors.jms.util.JmsRaUtil getInstalledMqVersion
[exec] WARNING: jmsra.upgrade_check_failed
[exec] Aug 1, 2010 11:47:04 PM org.hibernate.validator.util.Version <clinit>
[exec] INFO: Hibernate Validator bean-validator-3.0-JBoss-4.0.2
[exec] Aug 1, 2010 11:47:04 PM org.hibernate.validator.engine.resolver.DefaultTraversableResolver detectJPA
[exec] INFO: Instantiated an instance of org.hibernate.validator.engine.resolver.JPATraversableResolver.
[exec] Aug 1, 2010 11:47:04 PM com.sun.messaging.jms.ra.ResourceAdapter start
[exec] INFO: MQJMSRA_RA1101: SJSMQ JMS Resource Adapter starting: REMOTE
[exec] Aug 1, 2010 11:47:04 PM com.sun.messaging.jms.ra.ResourceAdapt er start
[exec] INFO: MQJMSRA_RA1101: SJSMQ JMSRA Started:REMOTE
[exec] Sending message: This is message 1
[exec] Sending message: This is message 2
[exec] Sending message: This is message 3
[exec] To see if the bean received the messages,
[exec] check /domains/domain1/logs/server.log.

BUILD SUCCESSFUL
Total time: 9 seconds

Je suis assez séduit par la facilité d’utilisation. Reste à envoyer un mail depuis mon Message Driven Bean et gérer l’activation des comptes d’accès de cette manière… Une autre histoire que je ne vous raconterai pas !