Bonsoir,

dans le cadre d'un projet type "réseau social", je veux intégrer une feature consistant à notifier les utilisateurs de certains évènements concernant leurs relations dans le réseau. Je considère que chaque utilisateur est un "topic" auquel d'autres utilisateurs peuvent s'abonner.

Pour cela je compte utiliser JMS et j'essaie de tester quelques actions simples comme souscrire à un topic ou créer un topic.

J'utilise OpenJMS qui fonctionne correctement avec les exemples fournis par OpenJMS (en ligne de commande).

J'ai bricolé une classe qui est censée faire le job (désolé pour les println qui alourdissent la lecture, mais je souhaitais vérifier que tout allait bien) :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/**
 * 
 */
package com.citizenweb.utilz;

import java.util.Hashtable;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.Topic;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

/**
 * @author Fred
 *
 */
public class NotificationManager {

	Context context = null;
	ConnectionFactory jmsFactory = null;
	Connection connection = null;
	String factoryName = "ConnectionFactory";
	String destName = null;
	Destination dest = null;
	Session session = null;
	MessageProducer sender = null;
	MessageConsumer receiver = null;

	public NotificationManager(){
		
	}
	
	private void connect(){
		try{
			//create the JNDI initial context
			System.out.println("CONNECT");
			Hashtable<String,String> properties = new Hashtable<String,String>();
			properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.exolab.jms.jndi.InitialContextFactory");
			properties.put(Context.PROVIDER_URL, "tcp://localhost:3035/");
			properties.put(Context.SECURITY_CREDENTIALS, "openjms");
			properties.put(Context.SECURITY_PRINCIPAL, "admin");
			
			context = new InitialContext(properties);
			System.out.println(context.toString());
			//lookup the ConnectionFactory
			jmsFactory=(ConnectionFactory)context.lookup(factoryName);
			System.out.println(jmsFactory.toString());
			
			//create connection
			connection = jmsFactory.createConnection();
			System.out.println(connection.toString());
			//create the session
			session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
			System.out.println(session.toString());

			
		}catch(JMSException e){
			System.out.println("<< ERREUR in " + this.getClass().getSimpleName()+" | Méthode : connect()");
			e.printStackTrace();
		}catch(NamingException e){
			System.out.println("<< ERREUR in " + this.getClass().getSimpleName()+" | Méthode : connect()");
			e.printStackTrace();
		}
	}

	public Boolean createTopicUser(String topicUser){
		System.out.println("CREATE TOPIC");
		boolean done = false;
		try {
			connect();
			connection.start();
			System.out.println("TOPIC USER = " + topicUser);
			session.createTopic(topicUser);
			done = true;
			System.out.println("DONE = " + done);
			System.out.println("CONNECT META DATA : " + connection.getMetaData());
		} catch (JMSException e) {
			System.out.println("<< ERREUR in " + this.getClass().getSimpleName()+" | Méthode : createTopicUser()");
			e.printStackTrace();
		} finally {
			if(context != null){
				try {
					context.close();
				} catch(NamingException e){
					System.out.println("<< ERREUR in " + this.getClass().getSimpleName()+" | Méthode : createTopicUser()");
					e.printStackTrace();
				}
			}
			if(connection != null){
				try {
					connection.close();
				} catch (JMSException e) {
					System.out.println("<< ERREUR in " + this.getClass().getSimpleName()+" | Méthode : createTopicUser()");
					e.printStackTrace();
				}
			}
		}
		return done;
	}
	
	public Boolean subscribeTopic(String topic, String idUser){
		boolean done = false;
		try {
			connect();
			connection.start();
			dest = (Destination) context.lookup(topic);
			session.createDurableSubscriber((Topic) dest, idUser);
			done = true;
		} catch (NamingException e) {
			System.out.println("<< ERREUR in " + this.getClass().getSimpleName()+" | Méthode : createTopicUser()");
			e.printStackTrace();
		} catch (JMSException e) {
			System.out.println("<< ERREUR in " + this.getClass().getSimpleName()+" | Méthode : createTopicUser()");
			e.printStackTrace();
		} finally {
			if(context != null){
				try {
					context.close();
				} catch(NamingException e){
					System.out.println("<< ERREUR in " + this.getClass().getSimpleName()+" | Méthode : createTopicUser()");
					e.printStackTrace();
				}
			}
			if(connection != null){
				try {
					connection.close();
				} catch (JMSException e) {
					System.out.println("<< ERREUR in " + this.getClass().getSimpleName()+" | Méthode : createTopicUser()");
					e.printStackTrace();
				}
			}
		}
		return done;
	}
	
}
Le résultat que j'obtiens est quelque peu décevant : j'ai bien des objets qui sont créés (sessionfactory, session, connection, etc. -> j'imprime leur hashcode), mais jamais le Topic que je passe en argument à la méthode "createTopicUser()" n'est créé.

Si je vais vérifier dans la "console admin" d'OpenJMS le topic n'est pas créé et je n'en trouve bien sûr aucune trace dans la base de données d'OpenJMS (sous MySQL dans mon cas).

Voilà ce que j'imprime dans la console à l'exécution (pas de message d'erreur) :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
 
CREATE TOPIC
CONNECT
javax.naming.InitialContext@5b464ce8
org.exolab.jms.client.JmsConnectionFactory@246ae04d
org.exolab.jms.client.JmsConnection@68c4039c
org.exolab.jms.client.JmsSession@29ca901e
TOPIC USER = tata
DONE = true
CONNECT META DATA : org.exolab.jms.client.JmsConnectionMetaData@5025a98f
Voici le 'main' que j'exécute directement depuis Eclipse :

package com.citizenweb.utilz;

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
/**
 * @author Fred
 *
 */
public class Run {
 
	/**
         * @param args
         */
	public static void main(String[] args) {
		NotificationManager nm = new NotificationManager();
		nm.createTopicUser("tata");
	}
 
}
Avez-vous une idée de pourquoi le Topic n'est pas créé ?

Question subsidiaire : j'ai fait un 'main()' parce qu'il m'était impossible de faire tourner cette classe depuis jUnit -> je ne comprends pas pourquoi jUnit ne peut pas utiliser cette classe ??

Merci d'avance pour votre aide.

Fred