Comment savoir si une application Java est déjà lancée - Java - Programmation
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à
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 ?
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?
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". |
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
Marsh Posté le 26-03-2004 à 17:16:42
leonhard a écrit : |
il a pas parle de JVM differentes
Marsh Posté le 26-03-2004 à 17:27:50
uriel a écrit : |
ok, je sors... (et je vais essayer d'apprendre à lire)
Marsh Posté le 26-03-2004 à 17:49:23
uriel 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. Je comprends sa question comme "comment savoir si une jvm éxécutant mon appli est deja lancée ?"
Mais je peux me tromper...
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
Marsh Posté le 26-03-2004 à 17:54:13
uriel a écrit : |
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.
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.
Marsh Posté le 26-03-2004 à 18:01:51
non non qd tu invoques java tu lances une nouvelle JVM pour ton main
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...
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 ?
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 ...
Marsh Posté le 26-03-2004 à 18:11:33
Ygrec a écrit : Euh ... |
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 )
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...
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.
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é
}
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...
Marsh Posté le 26-03-2004 à 22:18:44
ReplyMarsh Posté le 26-03-2004 à 22:23:35
ReplyMarsh 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
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.
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.
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
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 :
|
Et à la "sortie" de ton appli, tu fais l'inverse soit
Code :
|
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.
Marsh Posté le 31-03-2004 à 20:27:29
Ygrec a écrit : Bon, je ne veux pas polémiquer, mais ...
|
le probleme du crash de la VM est résolu par Runtime.getRuntime().addShutdownHook
non ?
Marsh Posté le 31-03-2004 à 20:29:30
veryfree a écrit : |
si tu débranche l'alim de ton pc, chuis pas sur que le shutdownhook sera executé
Marsh Posté le 31-03-2004 à 20:32:39
tr-- +1
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 ...
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 ...
Marsh Posté le 31-03-2004 à 20:34:47
Ygrec a écrit :
|
Code :
|
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à.
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 ...
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
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