在java程序中执行另一个jar

我写了几个简单的Java应用程序,名为A.jar,B.jar。 现在我想编写一个GUI Java程序,以便用户可以按下buttonA来执行A.jar和buttonB来执行B.jar。我也想在GUI程序中输出运行时过程的详细信息。 任何build议?

如果我理解正确,看来你想要在你的Java GUI应用程序内的一个单独的进程中运行jar子。

要做到这一点,你可以使用:

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

它总是很好的做法来缓冲过程的输出。

.jar不可执行。 实例化类或调用任何静态方法。

编辑:创buildJAR时添加Main-Class条目。

> p.mf(p.mf的内容)

主要类:pk.Test

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

使用Process类和它的方法,

 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)); } } 

希望这可以帮助:

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

你可以创build你自己的类加载器,它知道有问题的jar文件,让它分别调用A.jar或B.jar中的main方法。 那么当你完成后,你可以丢弃类加载器。

注意:它在当前的JVM中运行,并不保护主应用程序不受新代码的影响。 为正在运行的程序添加新的function很方便。

如果jar包在你的类path中,并且你知道它的Main类,那么你可以调用主类。 以DITA-OT为例:

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

注意,这将使下级jar与你的jar共享内存空间和类path,以及所有可能导致干扰的可能性。 如果你不想让这些东西受到污染,那么你还有其他的select,如上所述 – 即:

  • 用它创build一个新的ClassLoader。 这更安全; 你至less可以把新jar子的知识隔离到核心类加载器,如果你build立的东西与你将使用外星人jar子的知识。 这就是我们为我们的插件系统所做的事情。 主要的应用程序是一个带有ClassLoader工厂的微型shell,API的副本,以及真正应用程序是构buildClassLoader的第一个插件的知识。 插件是一对jar – 接口和实现 – 一起压缩。 ClassLoader都共享所有的接口,而每个ClassLoader只知道它自己的实现。 这个堆栈有点复杂,但它通过了所有的testing,并且工作得很漂亮。
  • 使用Runtime.getRuntime.exec(...) (它完全隔离jar,但具有正常的“find应用程序”,“逃避你的string”,“特定于平台的WTF”和“OMG系统线程”的陷阱运行系统命令。

如果你是java 1.6,那么也可以这样做:

 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"); } } }