2009-08-24 11 views
83

J'ai écrit plusieurs applications java simples nommées A.jar, B.jar. Maintenant, je veux écrire un programme Java GUI afin que l'utilisateur peut appuyer sur le bouton A pour exécuter A.jar et le bouton B pour exécuter B.jar. Aussi je veux sortir le détail du processus d'exécution dans mon programme GUI. Toute suggestion?Exécution d'un autre fichier jar dans un programme Java

+26

Je ne sais pas pourquoi cela a été voté contre lui expliquer pourquoi ses hypothèses peut-être tort, mais ne downvote pas la question. –

+0

-1 La terminologie Java de base n'est pas utilisée correctement et la question est très vague et laisse beaucoup à désirer. Envisagez de reformuler votre question avec plus de détails ou lisez tout d'abord à propos de classpath Java et d'autres bases. – topchef

+18

@grigory: Voyez, c'est ce que vous auriez dû demander en premier lieu, au lieu de downvoting tout de suite. Downvoting sans même demander plus d'informations ne fait rien ... –

Répondre

19

.jar n'est pas un exécutable. Instancier des classes ou appeler n'importe quelle méthode statique.

EDIT: Ajouter une entrée de classe principale lors de la création d'un fichier JAR.

> p.mf (teneur p.mf)

Main-Class: pk.Test

>Test.java 

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

Utiliser la classe Process et il est des 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)); 
    } 
} 
+1

Je pense que l'idée est que l'accès donné à un pot, comment l'ajoutez-vous au classpath pour en charger des classes. – Jherico

+0

merci beaucoup ça marche! – winsontan520

+1

Note: cela fonctionne uniquement parce que vous avez le bin java dans votre PATH, ce n'est pas le cas pour l'installation par défaut de Windows – poussma

50

Si je comprends bien, il semble que vous voulez exécuter les pots dans un autre processus à partir de l'intérieur de votre application graphique Java.

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 conseillé de tamponner la sortie du processus.

+17

Cette solution est-elle portable? – Pacerier

+3

merci. J'ai essayé exec() func avec 3 paramètres, y compris le paramètre "dir" et ça ne marche pas. Avec un seul, nous avons seulement besoin de mettre les 3 fichiers .jar au même endroit – Silentbang

+0

Savez-vous comment obtenir l'objet 'Runtime' de cette application Java? –

-4

Si vous êtes java 1.6 alors ce qui suit peut également être fait:

import javax.tools.JavaCompiler; 
import javax.tools.ToolProvider; 

public class CompilerExample { 

    public static void main(String[] args) { 
     String fileToCompile = "/Users/rupas/VolatileExample.java"; 

     JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 

     int compilationResult = compiler.run(null, null, null, fileToCompile); 

     if (compilationResult == 0) { 
      System.out.println("Compilation is successful"); 
     } else { 
      System.out.println("Compilation Failed"); 
     } 
    } 
} 
+0

Je ne pense pas que cela réponde à la question du PO –

0

Si le pot de votre classpath, et vous connaissez la classe principale, vous pouvez simplement appeler la classe principale. En utilisant DITA-OT comme exemple:

import org.dita.dost.invoker.CommandLineInvoker; 
.... 
CommandLineInvoker.main('-f', 'html5', '-i', 'samples/sequence.ditamap', '-o', 'test') 

Notez cela fera le pot subordonné partage l'espace mémoire et un classpath avec votre pot, avec tous les risques d'interférences qui peuvent causer. Si vous ne voulez pas polluer ce genre de choses, vous avez d'autres options, comme mentionné ci-dessus - à savoir:

  • créer un nouveau ClassLoader avec le pot dedans. C'est plus sûr. vous pouvez au moins isoler les connaissances du nouveau jar à un classloader de base si vous construisez des objets en sachant que vous utiliserez des pots aliens. C'est ce que nous faisons dans mon magasin pour notre système de plugins; l'application principale est un minuscule shell avec une fabrique ClassLoader, une copie de l'API, et la connaissance que l'application réelle est le premier plugin pour lequel elle doit construire un ClassLoader. Les plugins sont une paire de jars - interface et implémentation - qui sont zippés ensemble. Les ClassLoaders partagent tous toutes les interfaces, tandis que chaque ClassLoader a seulement connaissance de sa propre implémentation. La pile est un peu complexe, mais elle passe tous les tests et fonctionne magnifiquement.
  • utilisation Runtime.getRuntime.exec(...) (qui isole totalement le pot, mais a la normale pièges « trouver l'application », « échapper à vos cordes droite », « WTF spécifiques à la plate-forme », et « OMG Threads système » de commandes du système en cours d'exécution.
5

Hope this helps.

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; 
} 
} 
Questions connexes