138 votes

Exécuter un autre jar dans un programme Java

J'ai écrit plusieurs applications java simples nommées A.jar, B.jar.

Maintenant je veux écrire un programme java GUI pour que l'utilisateur puisse appuyer sur le bouton A pour exécuter A.jar et le bouton B pour exécuter B.jar.

Je veux également afficher les détails du processus d'exécution dans mon programme GUI.

Une suggestion ?

41 votes

Je ne sais pas pourquoi cette proposition a été rejetée. Expliquez-lui pourquoi ses hypothèses sont peut-être erronées, mais ne votez pas la question.

0 votes

-La terminologie de base de Java n'est pas utilisée correctement et la question est très vague et laisse beaucoup de place à l'approximation. Envisagez de reformuler votre question en donnant plus de détails ou lisez simplement ce qu'est le classpath de Java et d'autres notions de base.

24 votes

@grigory : Tu vois, c'est ce que tu aurais dû demander en premier lieu, au lieu de downvoter tout de suite. Le downvoting sans même demander plus d'informations ne sert à rien...

85voto

gjrwebber Points 586

Si je comprends bien, il semble que vous vouliez exécuter les jars dans un processus distinct de votre application Java GUI.

Pour ce faire, vous pouvez utiliser :

// Run a java app in a separate system process
Process proc = Runtime.getRuntime().exec("java -jar A.jar");
// Then retreive the process output
InputStream in = proc.getInputStream();
InputStream err = proc.getErrorStream();

Il est toujours bon de mettre en mémoire tampon le résultat du processus.

21 votes

Cette solution est-elle portable ?

3 votes

Merci. J'ai essayé le func exec() avec 3 paramètres, dont le paramètre "dir" et ça ne marche pas. Avec un seul, il suffit de mettre les 3 fichiers .jar au même endroit.

0 votes

Savez-vous comment obtenir le Runtime de cette application java ?

33voto

AVD Points 57984

.jar n'est pas exécutable. Instanciez des classes ou faites appel à une méthode statique.

EDIT : Ajouter l'entrée Main-Class lors de la création d'un JAR.

>p.mf (contenu de p.mf)

Classe principale : pk.Test

Test.java

package pk;
public class Test{
  public static void main(String []args){
    System.out.println("Hello from Test");
  }
}

Utilisez la classe Process et ses méthodes,

public class Exec
{
   public static void main(String []args) throws Exception
    {
        Process ps=Runtime.getRuntime().exec(new String[]{"java","-jar","A.jar"});
        ps.waitFor();
        java.io.InputStream is=ps.getInputStream();
        byte b[]=new byte[is.available()];
        is.read(b,0,b.length);
        System.out.println(new String(b));
    }
}

3 votes

Je pense que l'idée est la suivante : si l'on a accès à un jar, comment l'ajouter au classpath afin de charger des classes à partir de celui-ci ?

1 votes

Note : cela ne fonctionne que si vous avez le bin java dans votre PATH, ce qui n'est pas le cas pour l'installation Windows par défaut.

0 votes

@AVD : où se trouve le fichier A.jar ?

22voto

Swarvanu Sengupta Points 312

J'espère que cela vous aidera :

public class JarExecutor {

private BufferedReader error;
private BufferedReader op;
private int exitVal;

public void executeJar(String jarFilePath, List<String> args) throws JarExecutorException {
    // Create run arguments for the

    final List<String> actualArgs = new ArrayList<String>();
    actualArgs.add(0, "java");
    actualArgs.add(1, "-jar");
    actualArgs.add(2, jarFilePath);
    actualArgs.addAll(args);
    try {
        final Runtime re = Runtime.getRuntime();
        //final Process command = re.exec(cmdString, args.toArray(new String[0]));
        final Process command = re.exec(actualArgs.toArray(new String[0]));
        this.error = new BufferedReader(new InputStreamReader(command.getErrorStream()));
        this.op = new BufferedReader(new InputStreamReader(command.getInputStream()));
        // Wait for the application to Finish
        command.waitFor();
        this.exitVal = command.exitValue();
        if (this.exitVal != 0) {
            throw new IOException("Failed to execure jar, " + this.getExecutionLog());
        }

    } catch (final IOException | InterruptedException e) {
        throw new JarExecutorException(e);
    }
}

public String getExecutionLog() {
    String error = "";
    String line;
    try {
        while((line = this.error.readLine()) != null) {
            error = error + "\n" + line;
        }
    } catch (final IOException e) {
    }
    String output = "";
    try {
        while((line = this.op.readLine()) != null) {
            output = output + "\n" + line;
        }
    } catch (final IOException e) {
    }
    try {
        this.error.close();
        this.op.close();
    } catch (final IOException e) {
    }
    return "exitVal: " + this.exitVal + ", error: " + error + ", output: " + output;
}
}

2voto

Dawood Morris Points 51

Ce qui suit fonctionne en démarrant le jar avec un fichier batch, dans le cas où le programme fonctionne de manière autonome :

public static void startExtJarProgram(){
        String extJar = Paths.get("C:\\absolute\\path\\to\\batchfile.bat").toString();
        ProcessBuilder processBuilder = new ProcessBuilder(extJar);
        processBuilder.redirectError(new File(Paths.get("C:\\path\\to\\JavaProcessOutput\\extJar_out_put.txt").toString()));
        processBuilder.redirectInput();
        try {
           final Process process = processBuilder.start();
            try {
                final int exitStatus = process.waitFor();
                if(exitStatus==0){
                    System.out.println("External Jar Started Successfully.");
                    System.exit(0); //or whatever suits 
                }else{
                    System.out.println("There was an error starting external Jar. Perhaps path issues. Use exit code "+exitStatus+" for details.");
                    System.out.println("Check also C:\\path\\to\\JavaProcessOutput\\extJar_out_put.txt file for additional details.");
                    System.exit(1);//whatever
                }
            } catch (InterruptedException ex) {
                System.out.println("InterruptedException: "+ex.getMessage());
            }
        } catch (IOException ex) {
            System.out.println("IOException. Faild to start process. Reason: "+ex.getMessage());
        }
        System.out.println("Process Terminated.");
        System.exit(0);
    }

Dans le fichier batchfile.bat on peut alors dire :

@echo off
start /min C:\path\to\jarprogram.jar

1voto

Vous pouvez créer votre propre chargeur de classe qui connaît le fichier jar en question, et le laisser appeler la méthode principale dans A.jar ou B.jar respectivement. Ensuite, lorsque vous avez terminé, vous pouvez vous débarrasser du classloader.

Note : Cette opération s'exécute à l'intérieur de la JVM actuelle et ne protège pas l'application principale du nouveau code. Elle est pratique pour ajouter une nouvelle fonctionnalité à un programme en cours d'exécution.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X