2009-08-24 13 views
83

Ich hatte mehrere einfache Java-Anwendungen namens A.jar, B.jar geschrieben. Jetzt möchte ich ein GUI Java-Programm schreiben, so dass der Benutzer Knopf A drücken kann, um A.jar auszuführen und Knopf B, um B.jar auszuführen. Außerdem möchte ich die Laufzeitprozessdetails in meinem GUI-Programm ausgeben. Irgendein Vorschlag?Führen Sie ein anderes jar in einem Java-Programm

+26

nicht sicher, warum diese überstimmt wurde ihm erklären, warum seine Annahmen falsch sein könnte, aber nicht downvote die Frage nicht. –

+0

-1 grundlegende Java-Terminologie wird nicht korrekt verwendet und die Frage ist sehr vage und lässt viel für das zweite Raten. Überlegen Sie, Ihre Frage mit mehr Details neu zu formulieren oder lesen Sie einfach zuerst den Java-Klassenpfad und andere Grundlagen. – topchef

+18

@grigory: Siehst du, das hättest du in erster Linie fragen sollen, anstatt sofort runter zu gehen. Downvoting, ohne auch nur nach weiteren Informationen zu fragen, bringt nichts Gutes ... –

Antwort

19

.jar ist nicht ausführbar. Instanziieren Sie Klassen oder rufen Sie eine statische Methode auf.

EDIT: Hinzufügen Main-Class-Eintrag beim Erstellen einer JAR.

> p.mf (Gehalt an p.mf)

Main-Klasse: pk.Test

>Test.java 

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

Verwenden Process-Klasse und es Methoden,

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

Ich denke, die Idee ist, dass der Zugriff auf ein Jar, wie fügen Sie es in den Klassenpfad, um Klassen daraus zu laden. – Jherico

+0

vielen dank es funktioniert! – winsontan520

+1

Hinweis: es funktioniert nur, weil Sie die Java-Bin in Ihrem Pfad haben, dies ist nicht der Fall für die Standard-Windows-Installation – poussma

50

Wenn ich richtig verstehe, scheint es, dass Sie die Gläser in einem separaten ausführen möchten Prozess von innerhalb Ihrer Java-GUI-Anwendung.

Um dies zu tun, die Sie verwenden können:

// 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(); 

Es ist immer eine gute Praxis, den Ausgang des Prozesses zu puffern.

+17

Ist diese Lösung tragbar? – Pacerier

+3

danke. Ich habe versucht, exec() func mit 3 Parametern, einschließlich der "dir" -Parameter und es funktioniert nicht. Mit nur einem müssen wir nur die 3 Dateien .jar an die gleiche Stelle setzen. – Silentbang

+0

Wissen Sie, wie man das 'Runtime'-Objekt dieser Java-Anwendung bekommt? –

-4

Wenn Sie Java 1.6 kann auch Folgendes geschehen:

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

Ich glaube nicht, dass dies die Frage des OP beantwortet –

0

Wenn das Glas ist in Ihrem Classpath, und Sie seine Hauptklasse kennen, können Sie nur die Hauptklasse aufrufen. Mit DITA-OT als Beispiel:

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

Hinweis: Das wird den untergeordneten jar Aktie Speicherplatz und einen Classpath mit Ihrem Glas macht, mit all dem Potenzial für Störungen, die verursachen können. Wenn Sie nicht das Zeug verschmutzt wollen, müssen Sie andere Optionen, wie oben erwähnt - nämlich:

  • einen neuen Classloader mit dem Glas in ihm erstellen. Das ist sicherer; Sie können das Wissen des neuen Jars zumindest zu einem Core-Classloader isolieren, wenn Sie die Dinge mit dem Wissen planen, dass Sie Alien-Jars verwenden werden. Genau das machen wir in meinem Shop für unser Plugins-System. Die Hauptanwendung ist eine kleine Shell mit einer ClassLoader-Factory, eine Kopie der API und das Wissen, dass die reale Anwendung das erste Plugin ist, für das sie einen ClassLoader erstellen soll. Plugins sind ein Paar von Jars - Schnittstelle und Implementierung - die zusammen gezippt werden. Die ClassLoader teilen sich alle Schnittstellen, während jeder ClassLoader nur die eigene Implementierung kennt. Der Stack ist ein wenig komplex, aber er besteht alle Tests und funktioniert wunderbar.
  • Verwendung Runtime.getRuntime.exec(...) (die vollständig das Glas isoliert, hat aber den normalen „die Anwendung finden“, „Ihre Saiten rechts entkommen“, „plattformspezifische WTF“ und „OMG-System Threads“ Tücken der Befehle System ausgeführt werden.
5

hoffe, das hilft.

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; 
} 
} 
Verwandte Themen