Comment savoir si une application Java est déjà lancée

Comment savoir si une application Java est déjà lancée - Java - Programmation

Marsh Posté le 26-03-2004 à 11:35:12    

Bonjour,
 
Comment détecter qu'une application JAVA est déjà lancée pour ne pas autoriser plus d'une instance de cette application dans le JRE ?
 
Merci

Reply

Marsh Posté le 26-03-2004 à 11:35:12   

Reply

Marsh Posté le 26-03-2004 à 12:06:19    

Créer un fichier sur disque au lancement de l'application avec la méthode File.createNewFile() puis s'assurer que ce fichier sera détruit quelque soit la manière dont ton aplication s'arrête en appelant la méthode File.deleteOnExit();
 
Si le fichier existe déjà au lancement, c'est qu'une instance de ton programme tourne déjà
 

Reply

Marsh Posté le 26-03-2004 à 16:26:09    

J'ai déjà utilisé avec succé la méthode citée ci-dessus. Mais ça ne fait pas trés "JAVA".
N'y aurait-il pas un moyen de savoir si la classe est déjà chargée en utilisant les ressources du ClassLoader par défaut utilisé par la classe ?

Reply

Marsh Posté le 26-03-2004 à 17:08:47    

et si l'appli se crache avant d'avoir pu effacer le fichier?
 
peut etre recupere la liste des thread qui tournent et comparer? une idée?


Message édité par meumeul le 26-03-2004 à 17:09:24
Reply

Marsh Posté le 26-03-2004 à 17:13:41    

vallot a écrit :

J'ai déjà utilisé avec succé la méthode citée ci-dessus. Mais ça ne fait pas trés "JAVA".
N'y aurait-il pas un moyen de savoir si la classe est déjà chargée en utilisant les ressources du ClassLoader par défaut utilisé par la classe ?


 
Ben je vois pas trop comment... quand les deux versions de ton applic tournent dans des vm différentes, y'a pas trop de moyen de communiquer... remarque qu'on peut faire une version "pure java" (et surtout inutilement compliquée) de truc du fichier.. par exemple en enregstrant un objet rmi sur un serveur au début de l'applic... ensuite y'a qu'à tester si l'objet répond ou non... enfin y'a surement moyen de faire encore plus compliqué et moins fiable  :lol:  

Reply

Marsh Posté le 26-03-2004 à 17:16:42    

leonhard a écrit :


Ben je vois pas trop comment... quand les deux versions de ton applic tournent dans des vm différentes,  


 
il a pas parle de JVM differentes  :??:


---------------
IVG en france
Reply

Marsh Posté le 26-03-2004 à 17:27:50    

uriel a écrit :


 
il a pas parle de JVM differentes  :??:  


 
ok, je sors... (et je vais essayer d'apprendre à lire)

Reply

Marsh Posté le 26-03-2004 à 17:49:23    

uriel a écrit :


 
il a pas parle de JVM differentes  :??:  

Ben à priori si ; il veut détecter au lancement de son appli si elle est deja lancée. en général quand tu lances une appli tu lance une nouvelle jvm pour l'éxécuter. Je comprends sa question comme "comment savoir si une jvm éxécutant mon appli est deja lancée ?"
Mais je peux me tromper...


---------------
Au royaume des sourds, les borgnes sont sourds.
Reply

Marsh Posté le 26-03-2004 à 17:51:40    

R3g a écrit :

Ben à priori si ; il veut détecter au lancement de son appli si elle est deja lancée. en général quand tu lances une appli tu lance une nouvelle jvm pour l'éxécuter.  


 
alors j'ai tout simplement pas compris comment ca fonctionnait, parce que pour moi il y avait une seule JVM par JRE, meme si il y a plusieurs process :??:


---------------
IVG en france
Reply

Marsh Posté le 26-03-2004 à 17:54:13    

uriel a écrit :


 
alors j'ai tout simplement pas compris comment ca fonctionnait, parce que pour moi il y avait une seule JVM par JRE, meme si il y a plusieurs process :??:

ben je suis pas spécialiste, c'est peut-être moi qui ai pas compris...
Pour moi à chaque fois que tu fais java MonAppli, tu lances une nouvelle jvm.


---------------
Au royaume des sourds, les borgnes sont sourds.
Reply

Marsh Posté le 26-03-2004 à 17:54:13   

Reply

Marsh Posté le 26-03-2004 à 17:57:21    

mince, faudrait voir, je pensais que la JVM gerait ca via un genre de systeme de queue pour gerer les differents jobs a faire... mais c'est possible, je suis pas sur de moi la.


---------------
IVG en france
Reply

Marsh Posté le 26-03-2004 à 18:01:51    

non non qd tu invoques java tu lances une nouvelle JVM pour ton main

Reply

Marsh Posté le 26-03-2004 à 18:06:49    

donc en fait, il va chercher a faire communiquer 2 programmes sur 2 JVM :/  
 
aucune idee...


Message édité par uriel le 26-03-2004 à 18:07:04

---------------
IVG en france
Reply

Marsh Posté le 26-03-2004 à 18:07:30    

Euh ...
 
Si tu lances 2 fois "java maclasse" ben t'auras 2 "applications" (au sens Windows), donc 2 instances de JVM, ie 2 processus distincts (je parle pas de Thread là). Nan ? :ange:  
 
Pour savoir si une appli tourne déjà, j'avais fait un truc y'a longtemps (peut être un peu "bourrin" mais bon ...)
En gros, au lancement de l'appli tu démarre une ServerSocket sur un port "applicatif". Si le démarrage échoue (genre port in use) c'est que ton appli tourne déjà. Lorsque la VM sera arrêtée le port sera libéré tout seul si mes souvenirs sont bons, donc pas de pb en cas de crash de l'appli.
Faut faire attention au SecurityManager par contre ...

Reply

Marsh Posté le 26-03-2004 à 18:08:23    

Oups, partially grillaid ...  :D

Reply

Marsh Posté le 26-03-2004 à 18:11:33    

Ygrec a écrit :

Euh ...
 
Si tu lances 2 fois "java maclasse" ben t'auras 2 "applications" (au sens Windows), donc 2 instances de JVM, ie 2 processus distincts (je parle pas de Thread là). Nan ? :ange:  
 
Pour savoir si une appli tourne déjà, j'avais fait un truc y'a longtemps (peut être un peu "bourrin" mais bon ...)
En gros, au lancement de l'appli tu démarre une ServerSocket sur un port "applicatif". Si le démarrage échoue (genre port in use) c'est que ton appli tourne déjà. Lorsque la VM sera arrêtée le port sera libéré tout seul si mes souvenirs sont bons, donc pas de pb en cas de crash de l'appli.
Faut faire attention au SecurityManager par contre ...

très hasardeux comme methode, car certains applis s'accaparent des ports "au hasard" (genre outlook qui une fois sur 10 me laisse pas demarrer mon jndi [:kiki])


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 26-03-2004 à 19:08:21    

bon, j'ai mis en oeuvre la solution que j'ai donné plus haut chez l'un de mes clients. Elle n'a (pour l'instant) jamais posé de problème.  
 
Je redonne le topic que j'avais fait à l'époque
 
ici
 
Pour info, quand je faisais deux fois de suite "java maclasse", c'était bien 2 JVMS différentes qui se lançaient ! J'avais fait mes développements en pensant que mes 2 instances se lanceraient dans la même JVM (utilisation de synchronized...) mais j'ai dû déchanter...


Message édité par machinbidule1974 le 26-03-2004 à 19:09:58
Reply

Marsh Posté le 26-03-2004 à 20:07:58    

J'ai potassé cet aprés midi. Et ceci m'a conduit plus loin que prévu.  Comme il est dit plus haut, chaque appli tourne dans sa JVM semble-t-il. De là la difficulté de détecter si mon appli tourne déjà.
Merci pour toutes vos réponse.

Reply

Marsh Posté le 26-03-2004 à 21:57:43    

heu j 'ai peut etre pas compris mais bon :
 
si tu fait une variable static qui s'increment dans le contructeur de ta classe principal ca passe non ?
 
static int cptInstance=0;
 
public MainClass(){
cptInstance++;
if(cptInstance>0)
//le prog est deja lancé  
}
 

Reply

Marsh Posté le 26-03-2004 à 22:10:20    

Non car deux instances de son programme vont se lancer dans 2 JVMs différentes. Donc il aura 2 ClassLoader et deux variables statiques...

Reply

Marsh Posté le 26-03-2004 à 22:18:44    

veryfree a écrit :

heu j 'ai peut etre pas compris


 
Je confirme, t'as rien compris [:joce]

Reply

Marsh Posté le 26-03-2004 à 22:23:35    

DarkLord a écrit :


 
Je confirme, t'as rien compris [:joce]


 
j'ai lu vite fait hein , c'est le Week end  [:veryfree]

Reply

Marsh Posté le 27-03-2004 à 03:24:42    

Va pour le ServerSocket avec les précautions d'usage (ne pas prendre un port déjà utilisé si possible)
C'est, avec le fichier, la solution que j'ai retrouvée sur différents forums.
Merci à tous

Reply

Marsh Posté le 29-03-2004 à 22:49:34    

Essaie de faire une commande système avec le nom de ton programme :
// Version Unix
Runtime.getRuntime().exec("ps | grep monProg" );
 
Le mieux est de lancer une Registry avec ton programme sur un port déterminé et si tu lances ton appli une deuxième fois, la registry ne peut s'initialiser et génère une erreur qui fait tombé ton programme n°2.
 
Vu que tu débutes, commence par le premier example.

Reply

Marsh Posté le 30-03-2004 à 00:48:13    

http://java.sun.com/j2se/1.4.2/doc [...] ences.html
 
je pose ça là innocement hein.


---------------
trainoo.com, c'est fini
Reply

Marsh Posté le 31-03-2004 à 11:53:40    

Merci encore pour vos suggestions. A partir d'un problème ça foisonne!
Le mettre mot étant portabilité, je vais creuser l'emploi de la classe Preferences et voir si il est facile de tester/écrire une valeur
 
Aux innocents les mains pleines

Reply

Marsh Posté le 31-03-2004 à 20:21:06    

Bon, je ne veux pas polémiquer, mais ...
La solution avec une entrée de Preferences, même si elle est facile à mettre en oeuvre, peut te poser des pbs si jamais ton appli tombe violemment ...
En gros tu vas faire :

Code :
  1. Preferences node = Preferences.systemRoot().node("semaphores" );
  2. String semaphore = node.get("monapp","non lancée" );
  3. if (semaphore.equals("non lancée" ))
  4.     // Une seule instance tourne, on positionne la sémaphore
  5.     node.put("monapp","lancée" );
  6. else
  7.     // Une autre instance existe déjà, etc.


 
Et à la "sortie" de ton appli, tu fais l'inverse soit

Code :
  1. node.remove("monapp" );


 
Maintenant si tu n'exécutes jamais le code de terminaison (crash de VM par ex), tu ne pourras plus jamais lancer ton appli.  
(Même si on peut un peu minimiser les risques en mettant tout ça dans un try catch finally au niveau "main" principal).
Tant que ta préférence sera stockée dans le backing store (qui dépend de l'OS : registry sous windows, fichiers sur unix & co par ex) ton appli sera "bloquée"...
Donc tu seras bon pour te faire une appli d'administration qui ira effacer les sémaphores si besoin, paske tes users ne vont pas apprécier de devoir aller farfouiller dans la registry ou ailleurs pour se débloquer tout seuls ...
 
AMHA ce n'est pas la bonne solution.
 

Reply

Marsh Posté le 31-03-2004 à 20:27:29    

Ygrec a écrit :

Bon, je ne veux pas polémiquer, mais ...
La solution avec une entrée de Preferences, même si elle est facile à mettre en oeuvre, peut te poser des pbs si jamais ton appli tombe violemment ...
En gros tu vas faire :

Code :
  1. Preferences node = Preferences.systemRoot().node("semaphores" );
  2. String semaphore = node.get("monapp","non lancée" );
  3. if (semaphore.equals("non lancée" ))
  4.     // Une seule instance tourne, on positionne la sémaphore
  5.     node.put("monapp","lancée" );
  6. else
  7.     // Une autre instance existe déjà, etc.


 
Et à la "sortie" de ton appli, tu fais l'inverse soit

Code :
  1. node.remove("monapp" );


 
Maintenant si tu n'exécutes jamais le code de terminaison (crash de VM par ex), tu ne pourras plus jamais lancer ton appli.  
(Même si on peut un peu minimiser les risques en mettant tout ça dans un try catch finally au niveau "main" principal).
Tant que ta préférence sera stockée dans le backing store (qui dépend de l'OS : registry sous windows, fichiers sur unix & co par ex) ton appli sera "bloquée"...
Donc tu seras bon pour te faire une appli d'administration qui ira effacer les sémaphores si besoin, paske tes users ne vont pas apprécier de devoir aller farfouiller dans la registry ou ailleurs pour se débloquer tout seuls ...
 
AMHA ce n'est pas la bonne solution.
 
 


 
le probleme du crash de la VM est résolu par Runtime.getRuntime().addShutdownHook
non ?

Reply

Marsh Posté le 31-03-2004 à 20:29:30    

veryfree a écrit :


 
le probleme du crash de la VM est résolu par Runtime.getRuntime().addShutdownHook
non ?
 

si tu débranche l'alim de ton pc, chuis pas sur que le shutdownhook sera executé ;)


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 31-03-2004 à 20:32:39    

tr-- +1  :D  
Tu connais pas l'histoire de la chambre 12 de réa dans un hosto de l'APHP ou y'avait 100% de morts de plus qu'à côté ?
Y'avait la femme de ménage qui débranchait les appareils pour y brancher son aspi pour le couloir ...
 :D  :D

Reply

Marsh Posté le 31-03-2004 à 20:34:36    

Bon sérieusement là ...
Le truc du shutdown hook ça peut le faire, c'est une sécurité en cas de fonctionnement "normal --".
Ca résiste pas aux coupures de courant, aux chutes de météorites, aux effets de la désintégration de l'atome ...

Reply

Marsh Posté le 31-03-2004 à 20:34:47    

Ygrec a écrit :


Code :
  1. Preferences node = Preferences.systemRoot().node("semaphores" );
  2. String semaphore = node.get("monapp","non lancée" );
  3. if (semaphore.equals("non lancée" ))
  4.     // Une seule instance tourne, on positionne la sémaphore
  5.     node.put("monapp","lancée" );
  6. else
  7.     // Une autre instance existe déjà, etc.




Code :
  1. Preferences node = Preferences.systemRoot().node("semaphores" );
  2. String semaphore = node.get("monapp","non lancée" );
  3. if (semaphore.equals("non lancée" )) {
  4.     // Une seule instance tourne, on positionne la sémaphore
  5.     node.put("monapp","lancée" );
  6.     node.sync();
  7. } else
  8.     // Une autre instance existe déjà, etc.


déjà, ensuite, il existe plusieurs méthodes pour résoudre ce pb, telles que celle de veryfree ou celle consistant à mettre une clef de contact avec l'instance dans la préférence et a tenter de contacter réellement l'application pour voir si elle est réellement là.


Message édité par nraynaud le 31-03-2004 à 20:35:51

---------------
trainoo.com, c'est fini
Reply

Marsh Posté le 31-03-2004 à 20:37:11    

Le "node.sync" n'est pas forcément utile à l'endroit ou tu le mets, mais après le node.remove("monapp" ) plutôt nan ?
edit : en fait même si le user lance 2 instances l'une deriière l'autre, on peut considérer que le flush() aura le temps de se faire au niveau de la première (et donc commiter le node.put())
Sinon le truc de la clef de contact j'ai pas suivi ...


Message édité par Ygrec le 31-03-2004 à 20:39:42
Reply

Marsh Posté le 31-03-2004 à 21:03:16    

perso, j'ai deja fait ça en ouvrant un port sur le localhost via un socket, si le port est deja en ecoute alors la nouvelle instance se termine ;)


---------------
VA APPRENDRE ET REVIENS QUAND TU SAIS, SINON ABSTIENT TOI C'EST UN GRAND CONSEIL QUE JE TE DONNE... TU ES INCOMPÉTENT ET C'EST UNE RÉALITÉ, TU N'AS RIEN A FAIRE ICI FAUT S'Y CONNAITRE ... -Jojo1998 - RIP - http://tinyurl.com/qc47ftk
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed