Précédent   Forum du club des développeurs et IT Pro > Java > Serveurs, conteneurs, et Java EE > Java EE
Java EE Forum d'entraide sur la norme Java EE (EJB, JMS, etc.). Avant de poster -> FAQ Java EE
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 13/11/2012, 19h40   #1
kranagard
Candidat au titre de Membre du Club
 
Inscription : octobre 2008
Messages : 70
Détails du profil
Informations forums :
Inscription : octobre 2008
Messages : 70
Points : 13
Points : 13
Par défaut synchronisation de client

bonjour, je développe actuellement un programme dans lequel un client doit attendre qu'un autre fasse une action pour mettre à jour ses données.
En java j'utiliserai une méthode synchronized avec un wait et un notify pour le realiser mais en java ee je sèche.

en gros pour donner un exemple simple je pourrais avoir:

un client(1) pose des sous sur la table et attend qu'un autre les prenne
un client(2) prend les sous et prévient l'autre que c'est fait
1 rafraîchi son affichage

je suis dans un singleton déployé sur glassfish mais je ne pense pas que ça change grand chose (glassfish).

en attendant vos idées, moi je suis à cours d'idées après avoir regardé du cotés des lock (les synchronized étant interdit dans les ejb)
kranagard est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/11/2012, 21h17   #2
fxrobin
Membre Expert
 
Avatar de fxrobin
 
Homme
Formateur JAVA / XML
Inscription : novembre 2007
Messages : 852
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Formateur JAVA / XML
Secteur : Service public

Informations forums :
Inscription : novembre 2007
Messages : 852
Points : 1 300
Points : 1 300
Alors 2 solutions :

1 - soit du JMS et Message Driven Bean pur (pas simple)
2 - soit @Asynchronous avec Future<V> sur un Session Bean En gros des méthodes EJB asynchrones : http://docs.oracle.com/javaee/6/tutorial/doc/gkkqg.html

Perso, je ferai la solution 2.

Si tu n'es pas en mode "EJB", tu peux toujours faire avec "Callable" et "Future" du framework Executor apparu avec Java 5.
__________________
Moins on code, moins il y a de bug ... et vice-versa ainsi qu'inversement ...
fxrobin est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/11/2012, 23h13   #3
kranagard
Candidat au titre de Membre du Club
 
Inscription : octobre 2008
Messages : 70
Détails du profil
Informations forums :
Inscription : octobre 2008
Messages : 70
Points : 13
Points : 13
j'avais pensé à JMS mais ça me parait trop gros pour ce que je veux faire, asynchronous me parait bien mais... Comment je fais vu que la fonction que j'utilise est courte mais doit être bloquante?


si je comprends bien asynchronous c'est pour pouvoir continuer cotes client à faire des opérations en attendant la réponse du serveur, or moi je cherche à ce que le serveur bloque tant qu'un évènement n'a pas eu lieu (un commit sur une bd en fait).
donc je dois faire une méthode dans laquelle je bloque en attendant qu'une autre méthode soit appelé par un autre client. je regarde asynchronous quand même, je suis peut être passé à cotes d'un truc.

merci en tout cas pour ta réponse
kranagard est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/11/2012, 23h33   #4
fxrobin
Membre Expert
 
Avatar de fxrobin
 
Homme
Formateur JAVA / XML
Inscription : novembre 2007
Messages : 852
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Formateur JAVA / XML
Secteur : Service public

Informations forums :
Inscription : novembre 2007
Messages : 852
Points : 1 300
Points : 1 300
ah j'avais pas bien compris.

Alors oui, un Singleton me parait pas mal.
Bloquant en Lock Write par défaut.

Ou alors les Interceptor ... à creuser.
Je vais continuer d'y réfléchir.

Tu peux me donner un cas d'utilisation pour que j'ai les même "entrées" que toi ?
__________________
Moins on code, moins il y a de bug ... et vice-versa ainsi qu'inversement ...
fxrobin est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/11/2012, 23h34   #5
fxrobin
Membre Expert
 
Avatar de fxrobin
 
Homme
Formateur JAVA / XML
Inscription : novembre 2007
Messages : 852
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Formateur JAVA / XML
Secteur : Service public

Informations forums :
Inscription : novembre 2007
Messages : 852
Points : 1 300
Points : 1 300
Regarde dans l'API Concurrency, y'a peut-être ce qu'il te faut.
__________________
Moins on code, moins il y a de bug ... et vice-versa ainsi qu'inversement ...
fxrobin est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/11/2012, 23h41   #6
kranagard
Candidat au titre de Membre du Club
 
Inscription : octobre 2008
Messages : 70
Détails du profil
Informations forums :
Inscription : octobre 2008
Messages : 70
Points : 13
Points : 13
client A:
fait appel à objetReponse methodeA();
cette methode modifie des valeurs et attend la validation des changements => commit dans une bd. elle attend en retour les nouvelles valeurs contenu dans la bd apres changement.

client B:
fait appel à void methodeB();
cette méthode valide les modification et lance le commit. Elle est aussi sensé débloquer le client A.


le @lock ne m'a pas paru pertinent (d'ou mon post) vu qu'il ne permet que de limiter les accès à une ressource, dans mon cas le client B peut intervenir 2 minutes plus tard (asynchronous va donc me servir dans tous les cas), je n'ai donc pas d’accès concurrent.
je vais regarder concurrency (et continuer asynchronous), merci pour ton aide
kranagard est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/11/2012, 13h35   #7
kranagard
Candidat au titre de Membre du Club
 
Inscription : octobre 2008
Messages : 70
Détails du profil
Informations forums :
Inscription : octobre 2008
Messages : 70
Points : 13
Points : 13
je me suis finalement tourné vers jms...
j'ai ecris une mini classe qui encapsule le peu d'utilisation que je veux en faire mais j'obtient une erreur à l'execution:
Code :
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
Grave: MQJMSRA_DS4001: JMSServiceException on send message:sendMessage: Sending message failed. Connection ID: 2829732807136585216
Grave: javax.jms.JMSException: MQJMSRA_DS4001: JMSServiceException on send message:sendMessage: Sending message failed. Connection ID: 2829732807136585216
	at com.sun.messaging.jms.ra.DirectSession._sendMessage(DirectSession.java:1844)
	at com.sun.messaging.jms.ra.DirectProducer._send(DirectProducer.java:1085)
	at com.sun.messaging.jms.ra.DirectProducer.send(DirectProducer.java:453)
	at utils.JmsUtils.send(JmsUtils.java:55)
	at ejb.facade.FacadeUser.move(FacadeUser.java:122)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1052)
	at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1124)
	at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:5388)
	at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:619)
	at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
	at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571)
	at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doAround(SystemInterceptorProxy.java:162)
	at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:144)
	at sun.reflect.GeneratedMethodAccessor166.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:861)
	at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
	at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:370)
	at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5360)
	at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5348)
	at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:214)
	at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:89)
	at $Proxy272.move(Unknown Source)
	at ejb.facade.__EJB31_Generated__FacadeUser__Intf____Bean__.move(Unknown Source)
	at ejb.SessionBean.move(SessionBean.java:174)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1052)
	at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1124)
	at com.sun.ejb.containers.BaseContainer.invokeTargetBeanMethod(BaseContainer.java:4180)
	at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5368)
	at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5348)
	at com.sun.ejb.containers.EJBObjectInvocationHandler.invoke(EJBObjectInvocationHandler.java:206)
	at com.sun.ejb.containers.EJBObjectInvocationHandlerDelegate.invoke(EJBObjectInvocationHandlerDelegate.java:79)
	at $Proxy282.move(Unknown Source)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at com.sun.corba.ee.impl.presentation.rmi.ReflectiveTie.dispatchToMethod(ReflectiveTie.java:144)
	at com.sun.corba.ee.impl.presentation.rmi.ReflectiveTie._invoke(ReflectiveTie.java:174)
	at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(CorbaServerRequestDispatcherImpl.java:528)
	at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:199)
	at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(CorbaMessageMediatorImpl.java:1624)
	at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:1486)
	at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleInput(CorbaMessageMediatorImpl.java:990)
	at com.sun.corba.ee.impl.protocol.giopmsgheaders.RequestMessage_1_2.callback(RequestMessage_1_2.java:214)
	at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:742)
	at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.dispatch(CorbaMessageMediatorImpl.java:539)
	at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.doWork(CorbaMessageMediatorImpl.java:2324)
	at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.performWork(ThreadPoolImpl.java:497)
	at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:540)
Caused by: com.sun.messaging.jmq.jmsservice.JMSServiceException: sendMessage: Sending message failed. Connection ID: 2829732807136585216
	at com.sun.messaging.jmq.jmsserver.service.imq.IMQDirectService.sendMessage(IMQDirectService.java:1955)
	at com.sun.messaging.jms.ra.DirectSession._sendMessage(DirectSession.java:1839)
	... 58 more
Caused by: com.sun.messaging.jmq.jmsserver.util.BrokerException: transaction failed: [B4391]: Received message 93-192.168.56.1(ac:d7:ca:77:9d:a1)-1-1352895533654 with unknown transaction id 2829732807146002944
	at com.sun.messaging.jmq.jmsserver.data.handlers.DataHandler.routeMessage(DataHandler.java:467)
	at com.sun.messaging.jmq.jmsserver.data.protocol.ProtocolImpl.processMessage(ProtocolImpl.java:941)
	at com.sun.messaging.jmq.jmsserver.service.imq.IMQDirectService.sendMessage(IMQDirectService.java:1948)
	... 59 more

j'ai créé la factory ainsi que la queue dans glassfish et je l'obtient par lookup:

Code :
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
public class JmsUtils {
    private static ConnectionFactory connectionFactory;
    private static Queue queue;
    
    private MessageProducer producer;
    private MessageConsumer consumer;
    private Session session;
    
    
    public JmsUtils(String id){
        try {
            Context ctx = new InitialContext();
            connectionFactory = (ConnectionFactory)ctx.lookup("jms/ConnectionFactory");
            queue = (Queue)ctx.lookup("jms/Queue");
            
            
            
            Connection connection = connectionFactory.createConnection(); 
            connection.start();
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            producer = session.createProducer(queue);
            if(id != null)
                consumer = session.createConsumer(queue, "client = " + id);
            else
                consumer = session.createConsumer(queue);
            
        } catch (JMSException | NamingException ex) {
            Logger.getLogger(JmsUtils.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public void send(Serializable mess, String dest){
        try {
            ObjectMessage message = session.createObjectMessage(mess);
            message.setStringProperty("client", dest);
            producer.send(message);
            session.commit();
        } catch (JMSException ex) {
            Logger.getLogger(JmsUtils.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public Serializable receive(){
        try {
            
            ObjectMessage om = (ObjectMessage) consumer.receive();
            return om.getObject();
            
        } catch (JMSException ex) {
            Logger.getLogger(JmsUtils.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }
    
}
en rouge la ligne qui retourne l'erreur.

je continue à chercher sur le net mais j'ai encore beaucoup de lacune en jms donc beaucoup de lecture à faire.

ps: pour la logique du mon code, seul le serveur va envoyer des messages, il donne le client à qui il envoie le message lors du send.
kranagard est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/11/2012, 23h38   #8
kranagard
Candidat au titre de Membre du Club
 
Inscription : octobre 2008
Messages : 70
Détails du profil
Informations forums :
Inscription : octobre 2008
Messages : 70
Points : 13
Points : 13
apres un peu de doc j'ai modifié ma classe jms comme suit:

Code :
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
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package utils;
 
import java.io.Serializable;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
 
/**
 *
 * @author jerome
 */
public class JmsUtils {
    private static QueueConnectionFactory connectionFactory;
    private static Queue queue;
 
    private QueueSender producer;
    private QueueReceiver consumer;
    private QueueSession session;
    private QueueConnection connection;
 
    public JmsUtils(String id){
        try {
            Context ctx = new InitialContext();
            connectionFactory = (QueueConnectionFactory) ctx.lookup("jms/ConnectionFactory");
            queue = (Queue)ctx.lookup("jms/Queue");
 
 
 
            connection = connectionFactory.createQueueConnection();
            connection.start();
            session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
            producer = session.createSender(queue);
 
            if(id != null)
                consumer = session.createReceiver(queue, "client = " + id);
            else
                consumer = session.createReceiver(queue);
 
        } catch (JMSException | NamingException ex) {
            Logger.getLogger(JmsUtils.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
 
    public void send(Serializable mess, String dest){
        try {
            System.out.println("jms.send> "+dest);
            ObjectMessage message = session.createObjectMessage(mess);
            message.setStringProperty("client", dest);
            producer.send(message);
        } catch (JMSException ex) {
            Logger.getLogger(JmsUtils.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
 
    public Serializable receive(){
        try {
            System.out.println("jms.rcv> "+consumer.getMessageSelector());
            ObjectMessage om = (ObjectMessage) consumer.receive();
            return om.getObject();
 
        } catch (JMSException ex) {
            Logger.getLogger(JmsUtils.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }
 
}
je n'obtiens plus la moindre erreur mais mes clients ne reçoivent pas les messages, un problème sur le selector peut être? je vérifie ça mais si quelqu'un voit une erreur je suis open


ah bah j'ai juste fais une pause café et en revenant ça tourne :/
merci pour tes conseils fxrobin
kranagard est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/11/2012, 00h34   #9
fxrobin
Membre Expert
 
Avatar de fxrobin
 
Homme
Formateur JAVA / XML
Inscription : novembre 2007
Messages : 852
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Formateur JAVA / XML
Secteur : Service public

Informations forums :
Inscription : novembre 2007
Messages : 852
Points : 1 300
Points : 1 300


Joli.
__________________
Moins on code, moins il y a de bug ... et vice-versa ainsi qu'inversement ...
fxrobin est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 09h23.


 
 
 
 
Partenaires

Hébergement Web