Blue Flower

Chercher

 

Simple Applications JMS

Cet exemple montre les différentes étapes à suivre pour créer une application cliente JMS:

  1. la création d'un objet JMSContext
  2. la création de Producteur et de consommateur de message
  3. Envoi / Réception de messages
  4. Envoi de Messages

Dans notre exemple on va utiliser Glassfish comme serveur d'application et JMS (Provider JMS) comme fournisseur; pour comprendre le fonctionnement de Glassfish il faut se reporter à un autre cours. Dans le Glassfish on crée les ressources nécessaires pour l' application JMS à savoir les Objets adminisntrés (Connection Factories et Destination).

Envoi de Messages

Ici on explique comment on procède pour permettre à un client d'envoyer un message. L'application cliente Producer.java va envoyer des messages.
Les différentes étapes à suivre sont les suivantes:

  1. Injecter des ressources pour les objets administrés de l'exemple.

  2. Accepter et vérifier les arguments saisis en ligne de commande; on peut utiliser cet exemple pour envoyer autant de messages que ce soit en utilisant les files d'attente de messges que les Topic (sujets); on doit spécifier tout ce qu'il faut en ligne de commande quand on exécute le programme.

  3. Créer l'objet JMSContext, puis envoyer le nombre de message texte sous forme de caractères.

  4. Envoyer un message final pour s'assurer que l'application cliente réceptrice de messages ne peut plus recevoir de messages.

  5. Capturer et traiter toutes les exceptions.

Le client producteur de messages Producer.java

package aomara.producer;

import javax.annotation.Resource;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSContext;
import javax.jms.JMSRuntimeException;
import javax.jms.Queue;
import javax.jms.Topic;

/**
 * The Producer class consists only of a main method, which sends several
 * messages to a queue or topic.
 *
 * Run this program in conjunction with SynchConsumer or AsynchConsumer. Specify
 * "queue" or "topic" on the command line when you run the program. By default,
 * the program sends one message. Specify a number after the destination name to
 * send that number of messages.
 */
public class Producer {

    @Resource(lookup = "java:comp/DefaultJMSConnectionFactory")
    private static ConnectionFactory connectionFactory;
    @Resource(lookup = "jms/MyQueue")
    private static Queue queue;
    @Resource(lookup = "jms/MyTopic")
    private static Topic topic;

    /**
     * Main method.
     *
     * @param args the destination used by the example and, optionally, the
     * number of messages to send
     */
    public static void main(String[] args) {
        final int NUM_MSGS;

        if ((args.length < 1) || (args.length > 2)) {
            System.err.println(
                    "Program takes one or two arguments: "
                    + " []");
            System.exit(1);
        }

        String destType = args[0];
        System.out.println("Destination type is " + destType);

        if (!(destType.equals("queue") || destType.equals("topic"))) {
            System.err.println("Argument must be \"queue\" or " + "\"topic\"");
            System.exit(1);
        }

        if (args.length == 2) {
            NUM_MSGS = (new Integer(args[1])).intValue();
        } else {
            NUM_MSGS = 1;
        }

        Destination dest = null;

        try {
            if (destType.equals("queue")) {
                dest = (Destination) queue;
            } else {
                dest = (Destination) topic;
            }
        } catch (JMSRuntimeException e) {
            System.err.println("Error setting destination: " + e.toString());
            System.exit(1);
        }

        /*
         * Within a try-with-resources block, create context.
         * Create producer and message.
         * Send messages, varying text slightly.
         * Send end-of-messages message.
         */
        try (JMSContext context = connectionFactory.createContext();) {
            int count = 0;

            for (int i = 0; i < NUM_MSGS; i++) {
                String message = "This is message " + (i + 1) 
                        + " from producer";
                // Comment out the following line to send many messages
                System.out.println("Sending message: " + message);
                context.createProducer().send(dest, message);
                count += 1;
            }
            System.out.println("Text messages sent: " + count);
            
            /*
             * Send a non-text control message indicating end of
             * messages.
             */
            context.createProducer().send(dest, context.createMessage());
            // Uncomment the following line if you are sending many messages
            // to two synchronous consumers
            // context.createProducer().send(dest, context.createMessage());
        } catch (JMSRuntimeException e) {
            System.err.println("Exception occurred: " + e.toString());
            System.exit(1);
        }
        System.exit(0);
    }
}

L'application cliente productrice de message Producer.java passe par les étapes suivantes:

  1. On injecte les ressources pour la "fabrique de connexion" Connection Factories et la file d'attente de messages (queue) et le Topic (sujet):

    @Resource(lookup = "java:comp/DefaultJMSConnectionFactory")
    private static ConnectionFactory connectionFactory;
    @Resource(lookup = "jms/MyQueue")
    private static Queue queue;
    @Resource(lookup = "jms/MyTopic")
    private static Topic topic;
    
  2. On récupère et on vérifie les arguments, saisis sur la ligne de commande, qui spécifient le type de destination et le nombre d'arguments:

    final int NUM_MSGS;
    String destType = args[0];
    System.out.println("Destination type is " + destType);
    if ( ! ( destType.equals("queue") || destType.equals("topic") ) ) { 
        System.err.println("Argument must be \"queue\" or " + "\"topic\"");
        System.exit(1);
    }
    if (args.length == 2){ 
        NUM_MSGS = (new Integer(args[1])).intValue();
    } else { 
        NUM_MSGS = 1;
    }
    
  3. Assigner à la fois la file d'attente de message (queue) et le Topic (sujet) un objet Destination adéquat.

    Destination dest = null;
    try { 
        if (destType.equals("queue")) { 
            dest = (Destination) queue; 
        } else { 
            dest = (Destination) topic; 
        }
    } catch (Exception e) {
        System.err.println("Error setting destination: " + e.toString()); 
        System.exit(1);
    }
    
  4. Avec un try-with-resources block créer un objet JMSContext:

    try (JMSContext context = connectionFactory.createContext();) {
    
  5. Mettre à zéro le nombre de messages puis créer un objet JMSProducer et envoyer un ou plusieurs messages à la Destination indiquée et incrémenter le compteur.

    int count = 0;
        for (int i = 0; i < NUM_MSGS; i++) { 
            String message = "This is message " + (i + 1) 
                    + " from producer";
            // Comment out the following line to send many messages
            System.out.println("Sending message: " + message); 
            context.createProducer().send(dest, message);
            count += 1;
        }
        System.out.println("Text messages sent: " + count);
    
  6. Envoie un un message vide pour le contrôle de la fin des envois des données:

    context.createProducer().send(dest, context.createMessage());
    

    Envoie d' un message vide pour le contrôle (le messsage n'a pas de type spécifique) est un moyen de signifier au consommateur que l'envoi des messages est fini.

  7. Capturer et traiter les différentes exceptions . la fin de "try-with-resources" block permet la clôture automatique de l'objet JMSContext:

    } catch (Exception e) {
        System.err.println("Exception occurred: " + e.toString());
        System.exit(1);
    }
    System.exit(0);
    

Exécuter l'application Producer Client

On peut exécuter l'application cliente en utilisant la commande appclient; l'application Cliente nécessite une ou deux arguments en ligne de commande à savoir le type de Destination et le nombre de messages (qui est optionnel - si ce nombre n'est pas spécifier on a un seul message envoyé -); on se sert de l'application pour envoyer 3 messages dans la file d'attente de message.

  1. S'assurer que le serveur est lancé et que toutes les ressources relatives au fonctionnement du programme sont en place:

  2. Dans un terminal allez dans le répertoire où se trouve le programme producer (on tape la commande cd producer).

  3. Exécuter le programme en envoyant 3 message dans la file d'attente de messages (queue):

    appclient -client target/producer.jar queue 3
    

    La sortie du programme donne:

    type de Destination est queue 
    Sending message: This is message 1 from producer
    Sending message: This is message 2 from producer
    Sending message: This is message 3 from producer
    Text messages sent: 3
    

précédent