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

Java Discussion :

Utiliser un jar externe dans un projet


Sujet :

Java

  1. #1
    Membre du Club
    Femme Profil pro
    Ingénieur Recherche
    Inscrit en
    Octobre 2014
    Messages
    69
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Ingénieur Recherche

    Informations forums :
    Inscription : Octobre 2014
    Messages : 69
    Points : 41
    Points
    41
    Par défaut Utiliser un jar externe dans un projet
    Bonjour,

    j'aimerai votre aide afin d'utiliser un programme java dans mon propre projet.
    J'ai un fichier .jar que j'utilise régulièrement dans un terminal (java -jar ApplicationExterne.jar arguments).
    Je voudrai l'utiliser dans mon projet eclipse. Puisque le readme le définit comme un "java package", j'ai ajouter le jar à mes librairies.
    Jusque là, pas de problèmes.

    Mon problème est que je ne sais pas comment l'utiliser, j'aurai besoin d'une méthode qui lancerait le main avec les argument de mon choix, puis mettrai les résultats dans un buffer plutôt que de les afficher.
    Quelque chose du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ApplicationExterne app = new ApplicationExterne();
    res = app.main(arguments);
    Est-ce possible?

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    Puisque tu lances ton application par la ligne de commande java -jar ApplicationExterne.jar arguments, c'est que ton jar est un jar "exécutable".

    Tu as deux solutions :

    1. En incluant effectivement le jar en tant que bibliothèque à ton programme. Mais ceci implique que tu vas devoir exécuter l'application en appelant directement la méthode main() de la classe, comme dans n'importe quel cas d'appel de méthode en Java. Il te faut donc connaitre le nom de la classe. Si tu ne le connais pas, tu peux aller le voir dans le jar, en l'ouvrant par exemple avec un logiciel de compression (winzip, 7zip, winrar...), en regardant, dans le fichier META-INF/MANIFEST.MF qui s'y trouve, la propriété Main-Class. Pour les paramètres, comme la méthode main a
      • soit un seul argument de type String[], il te faudra donc passer tes arguments sous cette forme (MaClasse.main(new String[]{ "arg1", "arg2"});) ;
      • soit un varargs (String...args), qui te permettra te passer tes arguments sans passer par un tableau intermédiaire (MaClasse.main( "arg1", "arg2"); ) ;
      • si tu es à l'origine des classes dans le jar, tu peux aussi simplement te prévoir une méthode d'appel, avec des arguments typés, sans passer par des String, ce qui peut nettement te simplifier les appels et les rendre plus lisibles aussi.


    2. En l'exécutant comme un programme externe. Pas besoin d'inculre le jar en tant que bibiothèque externe. Pour faire ça, regarde la classe ProcessBuilder (regarde aussi à ce sujet http://blog.developpez.com/adiguba/p...ilder_redirect).


    En revanche, dans aucun cas, tu ne pourras récupérer un résultat comme tu as écrit : res = Machin.main( arguments ). La méthode main est forcément void. Là aussi, l'intérêt de faire une méthode spécifque pour un appel pur Java est aussi de pouvoir avoir un type de retour.

    On peut avoir par exemple simplement quelque chose comme ça :

    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    public class MaClasseQuiFaitUnTrucAvecUneImage {
     
     
         public static void main(String... args) {
              if ( args.length==2 ) {
     
                     try {
                          writeImage( args[1], process( readImage( args[0] ) );
                     }
                     catch(IOException e) {
                             System.err.println( "Error: cannot process image");
                             e.printStackTrace();
                     }
     
              }
              else {
                 System.err.println( "Error: missing argument");
              }
         }
     
         public static BufferedImage process(BufferedImage image) {
                    /*...*/
         }
     
         private static BufferedImage readImage(String path) throws IOException {
                    /*...*/
          }
     
         private static void writeImage(String path, BufferedImage image) throws IOException {
                   /*...*/
          }
     
    }
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Membre du Club
    Femme Profil pro
    Ingénieur Recherche
    Inscrit en
    Octobre 2014
    Messages
    69
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Ingénieur Recherche

    Informations forums :
    Inscription : Octobre 2014
    Messages : 69
    Points : 41
    Points
    41
    Par défaut
    Ok, je vois comment faire dans les deux cas. Merci beaucoup!
    D'un point de vue efficacité, tu me conseille lequel des deux?
    Sachant que j'aimerai transformer mon projet en exécutable à un certain point...

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    L'avantage de la solution d'appel en Java (donc l'inclusion du jar en bibliothèque), outre les possibilités de pouvoir avoir des méthodes avec des arguments typés, voire d'avoir différentes méthodes selon les cas, donc de favoriser la lisibilité, c'est que tu n'auras pas à gérer la problématique de l'emplacement du fichier (enfin elle sera beaucoup plus simple : à partir du moment où le jar est dans le classpath, la classe est accessible directement, alors que pour lancer une commande externe, il faut pouvoir savoir son chemin physique exact, ou pouvoir le déterminer automatiquement).
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  5. #5
    Membre du Club
    Femme Profil pro
    Ingénieur Recherche
    Inscrit en
    Octobre 2014
    Messages
    69
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Ingénieur Recherche

    Informations forums :
    Inscription : Octobre 2014
    Messages : 69
    Points : 41
    Points
    41
    Par défaut
    Hello,
    je suis parvenue à utiliser le jar externe, et pensait la question résolue.
    Mais en voulant boucler le processus, je suis tombée sur un problème qui me laisse perplexe:
    Utiliser l'appli une fois est facile:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Boot boot = new Boot();
    try {
    	boot.run(new String[]{"-targ1"});			
    } catch (Exception e) {
    	e.printStackTrace();
    }
    Je ne semble pas pouvoir l'utiliser plus d'une fois cependant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Boot boot = new Boot();
    try {
    	boot.run(new String[]{"-targ1"});			
    	boot.run(new String[]{"-targ2"});
    } catch (Exception e) {
    	e.printStackTrace();
    }
    me fait une erreur. En regardant le code de Boot, j'ai repéré le problème: il y a un paramètre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    private static JarClassLoader loader = null;
    qui est initialisé dans run(), mais seulement s'il est null: sinon erreur.
    J'ai donc essayé de réinitialiser la classe:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Boot boot = new Boot();
    try {
    	boot.run(new String[]{"-targ1"});			
    } catch (Exception e) {
    	e.printStackTrace();
    	new ErrorDialog(e);
    }
    boot = new Boot();
    try {
    	boot.run(new String[]{"-targ2"});
    } catch (Exception e) {
    	e.printStackTrace();
    	new ErrorDialog(e);
    }
    mais j'ai la même erreur.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Boot boot = new Boot();
    try {
    	boot.run(new String[]{"-targ1"});			
    } catch (Exception e) {
    	e.printStackTrace();
    	new ErrorDialog(e);
    }
    Boot b = new Boot();
    try {
    	b.run(new String[]{"-targ2"});
    } catch (Exception e) {
    	e.printStackTrace();
    }
    Fait la même chose, tout comme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Boot boot = new Boot();
    try {
    	boot.run(new String[]{"-targ1"});			
    } catch (Exception e) {
    	e.printStackTrace();
    	new ErrorDialog(e);
    }
    boot = null;
    try {
    	boot.run(new String[]{"-targ2"});
    } catch (Exception e) {
    	e.printStackTrace();
    }
    Y aurait-il un moyen d'obliger le programme à "oublier" boot?

  6. #6
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    1. C'est quoi cette classe Boot ? Pourquoi aurait-elle besoin d'un JarClassLoader ?
    2. C'est quoi l'erreur ?
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  7. #7
    Membre du Club
    Femme Profil pro
    Ingénieur Recherche
    Inscrit en
    Octobre 2014
    Messages
    69
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Ingénieur Recherche

    Informations forums :
    Inscription : Octobre 2014
    Messages : 69
    Points : 41
    Points
    41
    Par défaut
    La classe Boot est la classe Main de l'appli.
    Son main appelle la fonction setClassLoader:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public synchronized static void setClassLoader(JarClassLoader $loader) {
            if (loader != null) throw new RuntimeException("Attempt to set a second Boot loader");
            loader = $loader;
            setProperties(loader);
    }
    Et donc, l'erreur que j'obtiens:
    java.lang.RuntimeException: Attempt to set a second Boot loader
    at com.simontuffs.onejar.Boot.setClassLoader(Boot.java:137)
    at com.simontuffs.onejar.Boot.run(Boot.java:277)
    at annot.MainApp.test(MainApp.java:701)
    at annot.MainApp.start(MainApp.java:140)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
    at com.sun.glass.ui.gtk.GtkApplication.lambda$null$49(GtkApplication.java:139)
    at java.lang.Thread.run(Thread.java:745)

  8. #8
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    C'est un code à toi donc. A ce que je vois, c'est même toi qui gère l'exception : tu as une variable static et tu empêches de lui affecter une valeur alors qu'elle en a déjà une.
    Donc je repose la question une première fois : pourquoi avoir besoin d'un classloader particulier (c'est très particulier d'en avoir besoin) ? Et seconde question, pourquoi une variable statique ?

    On peut se toujours se passer de variable statique. Je dirais même qu'on devrait toujours s'en passer (les seules vraiment utilies sont les "static final" de type standard (pour des "constantes" de référence, pas pour des composants comme un classloader), qu'on peut souvent remplacer par des enums d'ailleurs (ce qui revient techniquement au même avec plus de souplesse et de simplicité). Justement, pour éviter ce genre de problème.

    Question annexe : si un classloader est indispensable pour ton programme, ce ne serait pas le même quelque soit l'exécution ?

    Sans plus de code, il m'est difficile de t'indiquer une solution spécifique.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  9. #9
    Membre du Club
    Femme Profil pro
    Ingénieur Recherche
    Inscrit en
    Octobre 2014
    Messages
    69
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Ingénieur Recherche

    Informations forums :
    Inscription : Octobre 2014
    Messages : 69
    Points : 41
    Points
    41
    Par défaut
    En fait, le code est à l'appli externe que je ne peux pas modifier. Je peux juste le voir. Je suis bien d'accord que la manière de gérer la variable static est très particulière, mais je n'ai pas la main la-dessus.
    Le code entier est trop gros pour que je le "reconstruise" sans cette variable static, et il y aurait de toute façon des problèmes de licence.
    Je pense que je vais passer par un Process et utiliser l'appli comme un programme externe. Dommage, mais pas le choix
    En tout cas, merci pour ton aide!

  10. #10
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Tu ne pourras donc effectivement pas lancer deux fois la classe boot. Il ne reste plus qu'à lancer l'application comme une application externe. Si tu inclus le jar de l'application externe dans ton jar exécutable, tu pourras le lancer en utilisant la classe JarRunner.

    Eventuellement, tu peux reprendre le code et l'adapter pour avoir les 2 comportements dans le même main() : celui qui fait le lancement (ton prog), et celui qui lance Boot, en faisant la distinction par les paramètres.

    Reste la problématique d'indiquer les bons chemins. Tu peux obtenir dynamiquement le chemin de ton application (l'emplacement) par TaClasse.class.getProtectionDomain().getCodeSource().getLocation();, qui va te donner une url de protocole file:, que tu pourras transformer en file par

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    try {
      f = new File(url.toURI());
    } catch(URISyntaxException e) {
      f = new File(url.getPath());
    }
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  11. #11
    Membre du Club
    Femme Profil pro
    Ingénieur Recherche
    Inscrit en
    Octobre 2014
    Messages
    69
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Ingénieur Recherche

    Informations forums :
    Inscription : Octobre 2014
    Messages : 69
    Points : 41
    Points
    41
    Par défaut
    Uhm, je comptais utiliser un process, mais s'il y a une classe spécifique aux .jar, c'est mieux.
    Je ne comprend pas comment m'en servir, cependant.
    J'ai mon path, et la commande en terminal serait:
    cd monPath
    java -jar appli.jar -t arg
    donc, je devrait faire quelque chose comme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    String command = "java -jar evsClient.jar -t AARS";
    JarRunner jr = new JarRunner();
    jr.main(new String[]{command});
    Ça semble bizarre, où est-ce que je met le path?
    Je n'ai pas trouvé de tuto pour la classe...
    Et bien, il y a ça: https://docs.oracle.com/javase/tutor...jarrunner.html
    mais ça n'explique pas comment utiliser la classe..

  12. #12
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Non, mais il faut bien un ProcessBuilder pour lancer la commande "java".

    L'idée c'est de mettre le jar avec la classe Boot dans ton jar, comme n'importe quel fichier. Tu obtiens donc une url de ce jar avec Class.getResource().
    Et le lancer de ton appli :
    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
    25
    26
    if ( args.length==0 ) {
    			// lancement de mon appli
    			URL urlAppli = Launcher.class.getProtectionDomain().getCodeSource().getLocation();
    			File emplacementDeAppli;
    			try {
    				emplacementDeAppli = new File(urlAppli.toURI());
    			} catch(URISyntaxException e) {
    				emplacementDeAppli = new File(urlAppli.getPath());
    			}
     
    			System.out.println("MyAppli: " + emplacementDeAppli);
     
    			URL url = Launcher.class.getResource("external.jar");
    			System.out.println("JAR url: " + url);
    			String javaexe = System.getProperty("java.home")+"\\bin\\java.exe";
    			System.out.println("Java exe: " + javaexe);
     
    			// je lance trois fois mon prog
    			runExternal(emplacementDeAppli, url, javaexe);
    			runExternal(emplacementDeAppli, url, javaexe);
    			runExternal(emplacementDeAppli, url, javaexe); 
     
    		}
    		else {
    			JarRunner.main(new String[]{args[0]});
    		}
    avec
    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
    private static void runExternal(File emplacementDeAppli, URL url, String javaexe) {
    		ProcessBuilder p = new ProcessBuilder(javaexe,
    				"-jar",
    				emplacementDeAppli.getName(),
    				url.toString()
    				);
    		p.directory(emplacementDeAppli.getParentFile());
    		p.inheritIO();
    		try {
    			p.start();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    Mais il y a un problème auquel je n'avais pas pensé qui fait que ça ne fonctionne pas, et je n'ai pas le temps de creuser.

    La solution alternative est de déposer le fichier external.jar (c'est comme çà que je l'ai appelé dans mon exemple, mais c'est celui de la bibliothèque avec la classe Boot) dans un dossier temporaire (de le sortir de ton jar en sorte).

    Comme ça, par exemple (ici je le mets direct dans le dossier où se trouve mon jar).

    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
    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
    public static void main(String[] args) {
     
    		if ( args.length==0 ) {
    			// lancement de mon appli
    			URL urlAppli = Launcher.class.getProtectionDomain().getCodeSource().getLocation();
    			File emplacementDeAppli;
    			try {
    				emplacementDeAppli = new File(urlAppli.toURI());
    			} catch(URISyntaxException e) {
    				emplacementDeAppli = new File(urlAppli.getPath());
    			}
     
    			System.out.println("MyAppli: " + emplacementDeAppli);
     
    			URL url = Launcher.class.getResource("external.jar");
    			System.out.println("JAR url: " + url);
    			String javaexe = System.getProperty("java.home")+"\\bin\\java.exe";
    			System.out.println("Java exe: " + javaexe);
     
    			File deployed = new File(emplacementDeAppli.getParentFile(),"external.jar");
    			try(InputStream inputStream = url.openStream();
    				OutputStream outputStream = Files.newOutputStream(deployed.toPath());) {
     
    				int r;
    				while( (r=inputStream.read())!=-1 ) {
    					outputStream.write(r);
    				}
     
    			} catch (IOException e) { 
    				e.printStackTrace();
    				System.exit(-1);
    			}
     
    			runDeployed(deployed, url, javaexe);
    			runDeployed(deployed, url, javaexe);
    			runDeployed(deployed, url, javaexe); 
     
     
    		}
    		else {
    			JarRunner.main(new String[]{args[0]});
    		}
     
    	}
     
    	private static void runDeployed(File emplacementDeAppli, URL url, String javaexe) {
    		ProcessBuilder p = new ProcessBuilder(javaexe,
    				"-jar",
    				emplacementDeAppli.getName(),
    				url.toString()
    				);
    		p.directory(emplacementDeAppli.getParentFile());
    		p.inheritIO();
    		try {
    			p.start();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    Remarque qu'avec cette méthode on a plus besoin du JarRunner : on peut directement lancer la commande java -jar external.jarNB je suis parti du principe que java.home était configuré pour déterminer l'emplacement de java.exe
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

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

Discussions similaires

  1. [Débutant] Utilisation d'un style "externe" dans un projet
    Par elfdav dans le forum Windows Presentation Foundation
    Réponses: 1
    Dernier message: 09/12/2013, 09h45
  2. Utiliser des DLL externes dans un projet Qt
    Par Kermichou dans le forum Qt
    Réponses: 2
    Dernier message: 18/07/2013, 16h28
  3. [JAR]Pb utilisation de Jar externes
    Par El_touristo dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 23/02/2005, 22h22
  4. utiliser le même fichier dans plusieurs projets vc++6
    Par yannick_sch dans le forum MFC
    Réponses: 5
    Dernier message: 12/02/2004, 18h39

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