Vous êtes sur la page 1sur 23

Université Badji Mokhtar

Annaba
Faculté de l’ingéniorat
Département d’informatique
Master 1, Réseaux et sécurité Informatique

JMS
Java Messaging Service

Mai 2020
Préparé par: MAA. Yahiouche Salima
Introduction…
JMS/CORBA, RMI
Tight coupling
• Avec Sockets,RMI, Corba, on effectue une communication synchrone

• Avec JMS, on peut assurer une communication Asynchrone Loose Coupling

JMS/JDBC

• Avec l’API JDCB, on peut accéder à différentes bases de


données,..Mysql,Oracle,Postgre,…

• Avec l’API JMS, on peut accéder à différents services de messageries,..ActiveMQ,


WebSphereMQ, BEA WebLogic, Jboss,…
JMS, definition
• Une API Java MOM(Message Oriented Middleware)

• Permet d’envoyer des messages entre plusieurs clients

• Une spécification qui décrit comment créer , envoyer, recevoir des


messages
JMS: Les Acteurs
JMS Provider: ActiveMQ, Jboss,
WebSphereMQ,OpenJMS,…
Modes ou Modèles JMS
Modèle producteur/consommateur: la
Destination
Les destinations de type Queue ou Topic évitent au producteur
et au consommateur de connaître leurs adresses respectives, et
elles assurent la transparence de localisation, contrairement aux
sockets où l'on doit connaître le numéro du port et le nom de
machine pour communiquer.
Exemple d’utilisation Queue
• Le mode de communication en point à point est bien adapté à un
work flow d'entreprise où les documents circulent avec un temps de
traitement spécifique
Exemple d’utilisation Topic
• Le mode de communication par événement convient au contraire
pour di user des alertes à plusieurs destinataires, par exemple des in
rmations de bourse à des courtiers, ou bien des anomalies réseau en
télécommunications, des points de synchronisation en vidéo, etc.
Persistance des Messages Queue
• En mode point à point, un message individuel n'est lu que par un seul consommateur
• Le message peut être stocké pour un certain temps par le broker, et la lecture du
message peut être différée par rapport à sa production.
• C'est en ce sens que l'on dira que JMS est un mode de communication asynchrone.
• Après la lecture, le message est détruit de son lieu de stockage après accusé de
reception du consommateur.
Persistance des Messages Topic
Dans un mode publication/abonnement, Comme les consommateurs
plusieurs consommateurs écoutent sur le même peuvent s'abonner et se dé-
canal (Topic) et reçoivent collectivement le sabonner dynamiquement, il
même message individuel n'est pas possible de connaître
le nombre d'accusés de ré
ception à attendre. Le
message est donc détruit imḿ
édiatement, sauf dans le cas
particulier des abonnés
durables

En mode publication/abonnement, un consommateur absent au


moment de l'envoi du message ne le recevra donc pas. C'est pour
cela qu'il est considéré moins fiable que le mode point à point : c'est
la même analogie qu'entre le mode TCP et le mode UDP
Les Messages
• Contrairement aux modèles RPC (CORBA, RMI, SOAP), les
consommateurs et les producteurs ne partagent pas d'interfaces et
s’échangent uniquement des informations sous forme de messages.

• Message = Données (de types binaire,texte,… la plupart du temps)


+ en-tête avec des informations de routage
+ propriétés..par eg. le filtrage des clients
Connexion et Session
Fiabilité Qualité de service

• Ce sont Deux abstractions en JMS qui n'ont pas d'équivalent en mode RPC

• La connexion permet de gérer la sécurité des accès et le déroulement des


transactions vers le gestionnaire jms.
• Une connexion peut ouvrir plusieurs sessions.

• Une session est définie à l'intérieur d'une connexion comme une


délimitation temporelle permettant de grouper des envois ou des réceptions
de messages avec des propriétés spécifiques :

• mode transactionnel ou non, priorités des messages, séquence des messages, gestion
des accusés de réception. C'est ce qu'on appellera la qualité de service.
Architecture JMS
Reception d’un message
• On utilise setText() et getText() pour accéder au message
• On crée une instance connectionFactory (peut être de type ActiveMQ, ou
OpenJMs, ou WebsphereMQ….pensez au but du Patron Factory!!
• Préciser l’adresse du serveur jms, où va se situer la queue ou le Topic
• Créer une connection à l’aide de la méthode createConnection()
• Démarrer la connexion: connection.start();
• Créer une session
• Créer la destination, dans un premier exemple, on va créer une Queue
• Créer le consomateur
• Lui attacher un écouteur MessageListener (rappelez vous Observer
Pattern), il doit implémenter la méthode onMessage(Message)
Reception d’un message: code java
JMS provider: ActiveMQ
• ConnectionFactory connectionFactory =new consumer=session.createConsumer(destination);
ActiveMQConnectionFactory(“tcp://localhost:61
616”); Consumer.setMessageListener(new
MessageListner(){
• Connection connection= connectionFactory
.createConnection(); Public void onMessage(Message message){
• Connection.start(); If (message instanceof TextMessage){
• Session session=connection.createSession (false, TextMessage
Session.AUTO_AKNOWLEDGE); textMessage=(TextMessage)message;
• //false=signifie pas de transaction System.out.println(“Reception du
message”+textMessage.getText());}}}
• Destination
destination=session.createQueue(“rsi20.queue”)Ne pas oublier les try…catch
; Exécuter run java Application….encorepas de
• //pour un topic, on aurait écrit message dans la queu
createTopic(“rsi20.queue”);
MessageConsumer
Envoi d’un message
• Mêmes étapes, éliminer la partie Ecouteur
• On peut demander au broker de ne pas conserver une copie du
message(DeliveryMode.NON_PERSISTANT)
• Créer le message puis l’envoyer
• De préférence fermer la connexion et la session
Envoi d’un message: code java
JMS provider: ActiveMQ
• ConnectionFactory connectionFactory =new producer=session.createProducer(destination);
ActiveMQConnectionFactory(“tcp://localhost:61
616”); producer.setDeliveryMode(DeliveryMode.NON_PE
RSISTANT);
• Connection connection= connectionFactory
.createConnection(); TextMessage
textMessage=session.createTextMessage();
• Connection.start();
textMessage.setText(”Hello rsi20, bye
• Session session=connection.createSession (false, covid19…..”);
Session.AUTO_AKNOWLEDGE);
System.out.println(“Envoi du message….”);
• //false=signifie pas de transaction
Producer.send(textMessage);
• Destination
destination=session.createQueue(“rsi20.queue”)Session.close();
; Connection.close();
• //pour un topic, on aurait écrit
createTopic(“rsi20.queue”);
Ne pas oublier les try…catch(JMSException)
MessageProducer
Exécuter run java Application….
Ordre d’exécution:
• Démarrer le serveur JMS(dans notre cas Active MQ)
• Il faut commencer par exécuter le consommateur,
• Ensuite le producteur
• Essayer de lancer plusieurs consommateur, puis le producteur
• Vous allez remarquer qu’uns eul consommateur reçoit le message(car
on a utilisé..une Queue)
• Réexécuter l’exemple avec Topic et observez les différences
Exemple utilisant le broker ActiveMQ, avec
ses dependencies rajoutés à un projet Maven

• Le code précédant a été créé en ajoutant les dépendances ActiveMQ


au fichier pom.xml, d’un projet Maven.
• Pour comprendre son exécution:
• Vous devez suivre l’exemple très bien expliqué du prof Mohamed
Youssfi, et essayez de le pratiquer chez vous:

• https://www.youtube.com/watch?v=QRVmSxP7KVM
Exemple utilisant le context
exprimé par l’interface JNDI
Exemple Producteur
• import javax.jms.Connection; null; Session session = null; message");
import MessageProducer sender = null; sender.send(message);
javax.jms.ConnectionFactory; try { context = new System.out.println("Message
import javax.jms.Destination; InitialContext(); factory = envoye= " + message.getText());
import javax.jms.JMSException; (ConnectionFactory) } catch (Exception e) {
import context.lookup("ConnectionFact e.printStackTrace(); } finally { if
javax.jms.MessageProducer; ory"); destination = (context != null) { try {
import javax.jms.Session; (Destination) context.close(); } catch
import javax.jms.TextMessage; context.lookup("queue1"); (Exception e) {
import javax.naming.Context; connection = e.printStackTrace(); } } if
import factory.createConnection(); (connection != null) { try {
javax.naming.InitialContext; session = connection.close(); } catch
import connection.createSession(false, (Exception e) {
javax.naming.NamingException; Session.AUTO_ACKNOWLEDGE); e.printStackTrace(); } } } } }
public class TestOpenJMS1 { sender =
public static void main(final session.createProducer(destinat
String[] args) { Context context = ion); connection.start(); final
null; ConnectionFactory factory TextMessage message =
= null; Connection connection = session.createTextMessage();
null; Destination destination = message.setText("Mon
Exemple Consommateur
• import javax.jms.Connection; null; Session session = null; (TextMessage) message;
import MessageConsumer receiver = System.out.println("message
javax.jms.ConnectionFactory; null; try { context = new recu= " + text.getText()); } else if
import javax.jms.Destination; InitialContext(); factory = (message != null) {
import javax.jms.JMSException; (ConnectionFactory) System.out.println("Aucun
import javax.jms.Message; context.lookup("ConnectionFac message dans la file"); } } catch
import tory"); destination = (Exception e) {
javax.jms.MessageConsumer; (Destination) e.printStackTrace(); } finally { if
import javax.jms.Session; context.lookup("queue1"); (context != null) { try {
import javax.jms.TextMessage; connection = context.close(); } catch
import javax.naming.Context; factory.createConnection(); (NamingException e) {
import session = e.printStackTrace(); } } if
javax.naming.InitialContext; connection.createSession(false, (connection != null) { try {
import Session.AUTO_ACKNOWLEDGE) connection.close(); } catch
javax.naming.NamingException; ; receiver = (JMSException e) {
public class TestOpenJMS2 { session.createConsumer(destin e.printStackTrace(); } } } } }
public static void main(String[] ation); connection.start();
args) { Context context = null; Message message =
ConnectionFactory factory = receiver.receive(); if (message
null; Connection connection = instanceof TextMessage) {
null; Destination destination = TextMessage text =
Exemple fichier jndi.properties
En utilisant openJMS

java.naming.provider.url=tcp://localhost:3035
java.naming.factory.initial=org.exolab.jms.jndi.InitialContextFactory
java.naming.security.principal=admin
java.naming.security.credentials=openjms
En utilisant ActiveMQ
java.naming.factory.initial = org.apache.activemq.jndi.ActiveMQInitialContextFactory
# use the following property to configure the default connector
java.naming.provider.url = vm://localhost:61616
# use the following property to specify the JNDI name the connection factory
# should appear as.
#connectionFactoryNames = connectionFactory, queueConnectionFactory, topicConnectionFactry
# register some queues in JNDI using the form
# queue.[jndiName] = [physicalName]
queue.MyQueue = rsi20.MyQueue
# register some topics in JNDI using the form
# topic.[jndiName] = [physicalName]
topic.MyTopic = rsi20.MyTopic