IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Interfaces Graphiques en Java Discussion :

Ne pas lancer une interface plusieurs fois en même temps


Sujet :

Interfaces Graphiques en Java

  1. #1
    Membre régulier
    Homme Profil pro
    responsable technique
    Inscrit en
    Novembre 2002
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : responsable technique

    Informations forums :
    Inscription : Novembre 2002
    Messages : 100
    Points : 89
    Points
    89
    Par défaut Ne pas lancer une interface plusieurs fois en même temps
    Bonjour,
    J'ai un client lourd Java qui peut être lancé en double-cliquant sur un jar exécutable. Pour diverses raisons, je veux que ce client ne puisse pas être lancé plusieurs fois en même temps (pour faire bref : l'exécution de l'interface plusieurs fois en parallèle peut provoquer des comportements bizarres, voire le plantage de l'application).
    Pour cela, j'ai mis en place la solution suivante :
    - Au premier lancement, l'application crée un fichier monappli.log (dans windows\temp par exemple), dans lequel je mets juste la date et l'heure de lancement de l'appli
    - Lorsque l'appli fermée en cliquant sur la croix en haut à droite, le fichier est supprimé comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    public void processWindowEvent(WindowEvent e)
    {
       if (e.getID() == WindowEvent.WINDOW_CLOSING)
       {
           // suppression du fichier
       }
       super.processWindowEvent(e);
    }
    - A chaque démarrage de l'application, on vérifie si ce fichier existe, si c'est le cas, c'est que l'appli est déjà lancée et j'affiche un message adéquat.

    Le problème est que cette solution ne marche que si on ferme l'application "normalement" (via la croix en haut à droite). Si l'application est lancée par un script (qui exécute java -jar monjar.jar) et que ce script est stoppé, le fichier monappli.log ne sera pas effacé. De même, si on kill violemment le processus, le fichier ne sera pas effacé. Du coup, au redémarrage de l'appli, ça dit qu'elle est déjà lancée alors que ce n'est pas le cas.
    C'est très moyen. Auriez-vous une autre solution à proposer ?
    Merci d'avance
    Le marlou

  2. #2
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Points : 4 141
    Points
    4 141
    Par défaut
    De mémoire, tu as des techniques expliquées dans la FAQ.

  3. #3
    Membre régulier
    Homme Profil pro
    responsable technique
    Inscrit en
    Novembre 2002
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : responsable technique

    Informations forums :
    Inscription : Novembre 2002
    Messages : 100
    Points : 89
    Points
    89
    Par défaut
    j'ai regardé dans le FAQ Java GUI mais je n'ai rien trouvé qui corresponde à mon problème.

  4. #4
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Points : 4 141
    Points
    4 141
    Par défaut
    http://java.developpez.com/faq/java/...nceApplication

    Tu peux également adapter ta méthode de lock de fichier en utilisant la méthode addShutdownHook() de la classe Runtime. Ce code sera alors appelé même en cas de fermeture brutale de ton application.

  5. #5
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    Tu peux tout simplement utiliser deleteOnExit() juste après la création du fichier. Comme cela il sera supprimé à la fermeture du programme quoi qu'il arrive (sauf méchant plantage de la JVM).


    Sinon tu peux aussi utiliser les FileLock...

    a++

    [edit] PS : mais la solution de la socket permet un dialogue simple entre les deux applications. On peut par exemple passer les arguments de la nouvelle application à l'application d'origine afin qu'elle les traitent...

  6. #6
    Membre régulier
    Homme Profil pro
    responsable technique
    Inscrit en
    Novembre 2002
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : responsable technique

    Informations forums :
    Inscription : Novembre 2002
    Messages : 100
    Points : 89
    Points
    89
    Par défaut
    merci pour vos réponses. alors :
    1) pour la solution avec la socket, ça marche bien mais le fait de devoir utiliser un port ne n'emballe pas et je suis a peu pres sur que ça sera critiqué lors du prochain audit de sécurité sur notre produit.
    2) le deleteOnExit() marche bien mais pas quand on kille violemment le processus java
    3) idem pour le addShutdownHook(), ça marche bien mais pas quand on kille violemment le processus java
    4) Je n'ai pas besoin de FileLock dans mon cas.

    Donc pour résumer les 2 solutions deleteOnExit() et addShutdownHook() me plaisent bien mais ne marchient pas si on kille le processus java.
    Voici mon code avec le hook :
    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
     
    public class ShutdownThread extends Thread 
    {
       private File file;
     
       ShutdownThread(File file) 
       {
          this.file = file;
       }
     
       public void run() 
       {
          if (file != null && file.exists())
          {
             file.delete();
          } 
       }
    }
    et l'init dans ma classe principale :
    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
     
       ...
       final File file = new File(filename);
       if (file.exists())
       {
          // l'appli est deja lancée
          isStarted = true;
       }
       else
       {
          // creation du fichier
          ...
          Runtime.getRuntime().addShutdownHook(new ShutdownThread(file));
       }
       ...
    Si qq'un a une idée pour supprimer le fichier à coup sûr qd l'appli est arrêtée (de manière correcte ou pas)...

  7. #7
    Expert éminent sénior Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 621
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 621
    Points : 15 705
    Points
    15 705
    Par défaut
    4) Je n'ai pas besoin de FileLock dans mon cas.
    Je ne suis pas sur que tu aie compris ce qu'adiGuba a proposé.

    En fait l'idée est de faire un lock sur un fichier quelconque de la même manière que l'on ouvre un socket. Si le fichier est déjà verrouillé, c'est que l'application a déjà été lancée.
    Si l'application est tuée violemment le système va lever le verrou sur le fichier.

  8. #8
    Membre régulier
    Homme Profil pro
    responsable technique
    Inscrit en
    Novembre 2002
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : responsable technique

    Informations forums :
    Inscription : Novembre 2002
    Messages : 100
    Points : 89
    Points
    89
    Par défaut
    Citation Envoyé par Uther Voir le message
    Je ne suis pas sur que tu aie compris ce qu'adiGuba a proposé.
    En fait l'idée est de faire un lock sur un fichier quelconque de la même manière que l'on ouvre un socket. Si le fichier est déjà verrouillé, c'est que l'application a déjà été lancée.
    Si l'application est tuée violemment le système va lever le verrou sur le fichier.
    Bonjour,
    J'ai essayé le FileLock avec ce code :
    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
     
          ...
          final File file = new File(filename);
          try
          {
             final FileChannel channel = new RandomAccessFile(file, "rw").getChannel();
             // Use the file channel to create a lock on the file.
             // This method blocks until it can retrieve the lock.
             FileLock lock = channel.lock();
             // Try acquiring the lock without blocking. This method returns
             // null or throws an exception if the file is already locked.
             try
             {
                lock = channel.tryLock();
             }
             catch (OverlappingFileLockException e)
             {
                isStarted = true;
             }
          }
          catch (Exception e)
          {
             logger.error("error while lock file : " + e.getMessage());
          }
    Mais il passe tout le temps dans le catch OverlappingFileLockException, alors que je viens juste de créer le fichier...

  9. #9
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Tu lockes deux fois le fichier. Une fois avec lock() et une autre fois avec tryLock()...

    Utilises seulement tryLock() !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    final FileChannel channel = ...
    lock = channel.tryLock();
    a++

  10. #10
    Membre régulier
    Homme Profil pro
    responsable technique
    Inscrit en
    Novembre 2002
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : responsable technique

    Informations forums :
    Inscription : Novembre 2002
    Messages : 100
    Points : 89
    Points
    89
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Tu lockes deux fois le fichier. Une fois avec lock() et une autre fois avec tryLock()...

    Utilises seulement tryLock() !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    final FileChannel channel = ...
    lock = channel.tryLock();
    a++
    Si je fais juste le tryLock, il ne passe jamais dans le catch OverlappingFileLockException...

  11. #11
    Expert éminent sénior Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 621
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 621
    Points : 15 705
    Points
    15 705
    Par défaut
    C'est normal car si le fichier est locké, il n'y a pas de OverlappingFileLockException, tryLock() retourne juste null

  12. #12
    Membre régulier
    Homme Profil pro
    responsable technique
    Inscrit en
    Novembre 2002
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : responsable technique

    Informations forums :
    Inscription : Novembre 2002
    Messages : 100
    Points : 89
    Points
    89
    Par défaut
    ah ok, c'est bon ça marche. Donc pour résumer, il ne faut pas utiliser la méthode lock() mais plutôt tryLock(), et ne pas utiliser la OverlappingFileLockException. Il faut juste regarder si tryLock renvoie null ou pas :
    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
     
          .....
          final File file = new File(filename);
          try
          {
             final FileChannel channel = new RandomAccessFile(file, "rw").getChannel();
             final FileLock lock = channel.tryLock();
             if (lock == null)
             {
                // le fichier est déjà locké
                channel.close();
                isStarted = true;
             }
             else
             {
                // je peux démarrer mon appli
                .......
             }
          }
          catch (Exception e)
          {
             .......
          }
    Merci à tous pour vos réponses.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 19/02/2014, 10h41
  2. [AC-2007] affecter une valeur à plusieurs champs en même temps
    Par pepper18 dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 21/01/2010, 11h11
  3. Lancer une vm plusieurs fois en parallèle
    Par asouquieres dans le forum VirtualBox
    Réponses: 0
    Dernier message: 17/08/2009, 12h15
  4. [Servlet] Comment utilisé une servlet plusieurs fois ?
    Par gandalf_le_blanc dans le forum Servlets/JSP
    Réponses: 9
    Dernier message: 03/06/2004, 14h49
  5. [Débutant] Lancer une interface sous éclipse
    Par bonnefr dans le forum SWT/JFace
    Réponses: 11
    Dernier message: 11/05/2004, 15h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo