INSTANCE UNIQUE D'UNE APPLICATION

indiana_jules Messages postés 750 Date d'inscription mardi 9 mars 2004 Statut Membre Dernière intervention 23 décembre 2008 - 27 oct. 2006 à 09:35
blg81 Messages postés 2 Date d'inscription mercredi 8 juin 2005 Statut Membre Dernière intervention 1 décembre 2006 - 1 déc. 2006 à 05:27
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/40088-instance-unique-d-une-application

blg81 Messages postés 2 Date d'inscription mercredi 8 juin 2005 Statut Membre Dernière intervention 1 décembre 2006
1 déc. 2006 à 05:27
"Car je ne vois pas pour quel type d'appli on aurait besoin de ça."

Pourtant la plupart des applications en ont besoin, par exemple quand on clique sur des fichiers .xls depuis l'explorateur Windows ils sont ouverts dans la même instance d'Excel.
rom1v Messages postés 29 Date d'inscription lundi 20 décembre 2004 Statut Membre Dernière intervention 21 septembre 2007
30 nov. 2006 à 18:37
Tu ne passes pas d'arguments :(

Dans quel cas as-tu besoin de passer des arguments? Car je ne vois pas pour quel type d'appli on aurait besoin de ça.

Sinon il faut améliorer un peu, et rajouter cette possibilité avec la sérialisation par exemple?
blg81 Messages postés 2 Date d'inscription mercredi 8 juin 2005 Statut Membre Dernière intervention 1 décembre 2006
30 nov. 2006 à 14:46
Heu ... comment passe-t-on des arguments au concurrent pour une nouvelle instance?

Par exemple on appelle:
> uneApplication arg1, arg2 ...

Puis:
> uneApplication arg3, arg4 ...

comment l'instance existante reçoit-elle les arguments du second appel? par exemple, comment dans:
final Runnable RUN_ON_RECEIVE = new Runnable() {
public void run() {
if(mainFrame != null) {
// Si la fenêtre n'est pas visible (uniquement dans le systray par exemple), on la rend visible.
if(!mainFrame.isVisible())
mainFrame.setVisible(true);
// On demande à la mettre au premier plan.
mainFrame.toFront();
}

passer les nouveaux arguments?
rom1v Messages postés 29 Date d'inscription lundi 20 décembre 2004 Statut Membre Dernière intervention 21 septembre 2007
31 oct. 2006 à 10:24
Merci bien Ijinn j'ai complété mon article: http://rom.developpez.com/java-instance-unique/
rom1v Messages postés 29 Date d'inscription lundi 20 décembre 2004 Statut Membre Dernière intervention 21 septembre 2007
31 oct. 2006 à 09:51
Je n'avais pas pensé à cette solution, elle est en effet pas mal et sûr. Elle ne permet cependant pas de demander le passage au premier plan de l'instance déjà lancée, mais bon, on ne peut pas tout avoir...
Ijinn Messages postés 5 Date d'inscription lundi 30 décembre 2002 Statut Membre Dernière intervention 30 octobre 2006
30 oct. 2006 à 10:42
Salut,

Une autre solution consiste à utiliser un verrou sur un fichier donné, avec la méthode suivante :

//--------------------------------------------------------------------//
File fileLock = new File("Verrou.lock");
RandomAccessFile raFileLock = new RandomAccessFile(fileLock, "rw");

if (raFileLock.getChannel().tryLock() == null) {
locked = false;
}
else {
locked = true;
}
//--------------------------------------------------------------------//

Si on ne libère pas le verrou, celui-ci reste actif tant que la machine virtuelle tourne, et empêche tout autre processus de créer un autre verrou sur le même fichier. De cette façon on peut savoir avec certitude si une instance existe déjà, en testant la valeur de locked. (true si une instance existe déjà)
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
27 oct. 2006 à 13:42
Salut,

je ne conteste en rien la méthode que tu utilise je donne simplement une possibilité à Indiana_jules.
Perso pour la gestion des instances j'utilise du natif qui est une solution comme une autre......
rom1v Messages postés 29 Date d'inscription lundi 20 décembre 2004 Statut Membre Dernière intervention 21 septembre 2007
27 oct. 2006 à 13:32
@Indiana_jules:
La méthode de mettre une clé dans les propriétés systèmes rend ceci non multiplateforme... Une méthode équivalente est de créer un fichier qui indique si une instance est lancée (et le supprimer à la fermeture). Le problème, c'est si par exemple le programme est tué...

@Twinuts:
Mais si le programme est tué, le problème peut être (en partie) résolu par la méthode du hook pour le shutdown... Mais le problème, c'est que si, par exemple, il y a une panne de courant, et bien, tu pourras plus jamais relancer le logiciel... (à moins de supprimer le fichier).

Après plusieurs discussions sur developpez.com, cette méthode, même si elle a l'inconvénient de connaître un port libre (ce qui n'est que peu génant vu les probabilités), reste la meilleure solution...

@Lrequena:
Il ne s'agit pas d'un singleton, mais d'une instance d'application... Par exemple tu lances java MonApplication plusieurs fois, tu veux n'en avoir qu'un...
cs_lrequena Messages postés 10 Date d'inscription mercredi 18 mai 2005 Statut Membre Dernière intervention 24 juillet 2008
27 oct. 2006 à 13:15
bonjour, je ne sais pas si j'ai bien compris le probleme mais il me semble que pour obtenir une instance unique (par JVM) il suffit d'utiliser la methode suivante :

....
private static UniqueInstance uinstance = null;
...
private UniqueInstance(...){ ... }
...
public static UniqueInstance getInstance(...){
if(uinstance==null) uinstance = new UniqueInstance(...);
return uinstance;
}
...

Dites moi si je me trompe !! :)
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
27 oct. 2006 à 12:44
Salut,

mais il y a juste un défaut : le CTRL + ALT + SUPPR de Windows empêche la réecriture de cette clé à la fin de ton programme

Il te suffit simplement de creer un ShutdownHook exemple


Runtime.getRuntime().addShutdownHook(new Thread(new Runnable(){
public void run(){
System.out.println("Haaaaaaaaa on me kill");
}
}));

seule les kill -9 à la linux ne sont pas trappable et les ALT+F4 sur une fenetre graphique mais il y a une solution pour ce dernier.
indiana_jules Messages postés 750 Date d'inscription mardi 9 mars 2004 Statut Membre Dernière intervention 23 décembre 2008 22
27 oct. 2006 à 09:38
oups autant pour moi pour le codage de la documentaiton, j'avais pas vu toute la source ;p
indiana_jules Messages postés 750 Date d'inscription mardi 9 mars 2004 Statut Membre Dernière intervention 23 décembre 2008 22
27 oct. 2006 à 09:35
Salut,
il est vrai que cela a déjà été demandé, mais, de mon point de vue, cette solution n'est pas la meilleure (en tout cas en entreprise) car elle nécessiste de connaître un port de communication libre (qu'aucun logiciel protocole utilise, et ca peut devenir fastidieux), et cela peut posser un problème de sécurité.

Tu peux pour palier cela utiliser les propriétés systèmes en y insérant une clé permettant de savoir si une instance ou non de ton programme est en cours. Je l'ai déjà utilisé et cette méthode marche bien, mais il y a juste un défaut : le CTRL + ALT + SUPPR de Windows empêche la réecriture de cette clé à la fin de ton programme. Du coup je ne pouvais plus le relancer.

Néanmoins, ton code a le mérite de fournir une solution.

(je vais faire le pénible, mais il est conseillé de respecter les conventions de documentaiton de Java avec les tags @param, ....)

Voilà, et bonne continuation