在Java程序中执行另一个jar

在Java程序中执行另一个jar,java,jar,executable-jar,Java,Jar,Executable Jar,我已经编写了几个简单的java应用程序,命名为A.jar、B.jar 现在我想编写一个GUI java程序,这样用户可以按按钮a执行a.jar,按按钮B执行B.jar 我还想在GUI程序中输出运行时过程的详细信息 有什么建议吗?.jar不可执行。实例化类或调用任何静态方法 编辑: 在创建JAR时添加主类条目 >p.mf(p.mf的内容) 主类:pk.Test 使用Process类及其方法 public class Exec { public static void main(String

我已经编写了几个简单的java应用程序,命名为A.jar、B.jar

现在我想编写一个GUI java程序,这样用户可以按按钮a执行a.jar,按按钮B执行B.jar

我还想在GUI程序中输出运行时过程的详细信息


有什么建议吗?

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

编辑: 在创建JAR时添加主类条目

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

主类:pk.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));
    }
}

如果我理解正确,那么您似乎希望在JavaGUI应用程序内部的单独进程中运行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();

缓冲进程的输出始终是一种很好的做法。

如果您是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");
        }
    }
}

如果jar在类路径中,并且您知道它的主类,那么您可以调用主类。以DITA-OT为例:

import org.dita.dost.invoker.CommandLineInvoker;
....
CommandLineInvoker.main('-f', 'html5', '-i', 'samples/sequence.ditamap', '-o', 'test')
请注意,这将使从属jar与您的jar共享内存空间和类路径,并且可能会造成干扰。如果你不想让这些东西被污染,你还有其他选择,如上所述,即:

  • 创建一个包含jar的新类加载器。这样更安全;如果您使用将要使用外来jar的知识来构建东西,那么您至少可以将新jar的知识隔离到核心类加载器中。这是我们在我的商店为我们的插件系统所做的;主应用程序是一个带有类加载器工厂的小shell,一个API副本,并且知道真正的应用程序是它应该为其构建类加载器的第一个插件。插件是一对JAR——接口和实现——压缩在一起。类加载器都共享所有接口,而每个类加载器只知道自己的实现。堆栈有点复杂,但它通过了所有测试,工作得很好
  • 使用
    Runtime.getRuntime.exec(…)
    (它完全隔离了jar,但在运行系统命令时存在正常的“查找应用程序”、“正确转义字符串”、“特定于平台的WTF”和“OMG系统线程”陷阱
    • 希望这有助于:

      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;
      }
      }
      
      公共类执行器{
      私有缓冲读取错误;
      专用缓冲读取器op;
      私人进出口;
      public void executeJar(字符串jarFilePath,列表args)引发jarexecutejar异常{
      //为
      最终列表实际值=新的ArrayList();
      添加(0,“java”);
      增加(1,“-jar”);
      add(2,jarFilePath);
      实际加总(args);
      试一试{
      final Runtime re=Runtime.getRuntime();
      //final Process command=re.exec(cmdString,args.toArray(新字符串[0]);
      final Process command=re.exec(actualArgs.toArray(新字符串[0]);
      this.error=new BufferedReader(new InputStreamReader(command.getErrorStream());
      this.op=新的BufferedReader(新的InputStreamReader(command.getInputStream());
      //等待应用程序完成
      command.waitFor();
      this.exitVal=command.exitValue();
      如果(this.exitVal!=0){
      抛出新IOException(“未能执行jar,”+this.getExecutionLog());
      }
      }捕获(最终IOException | InterruptedException e){
      抛出新异常(e);
      }
      }
      公共字符串getExecutionLog(){
      字符串错误=”;
      弦线;
      试一试{
      而((line=this.error.readLine())!=null){
      错误=错误+“\n”+行;
      }
      }捕获(最终IOE例外){
      }
      字符串输出=”;
      试一试{
      而((line=this.op.readLine())!=null){
      输出=输出+“\n”+行;
      }
      }捕获(最终IOE例外){
      }
      试一试{
      this.error.close();
      这个.op.close();
      }捕获(最终IOE例外){
      }
      返回“exitVal:+this.exitVal+”,错误:+error+,输出:+output;
      }
      }
      
      如果程序作为独立程序运行,则以下操作通过使用批处理文件启动jar来实现:

      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);
          }
      
      在batchfile.bat中,我们可以说:

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

      首先,我们创建一个类FirstFileOutput,该类有一个main方法,该方法输出一行到稳定输出和一行到稳定错误。在所有第一个过程中,我们将再次创建一个类RuntimeExecCheck,该类将在启动进程时运行我们的FirstFileOutput类,然后RuntimeExecCheck类将读取稳定输出和稳定错误从FirstFileOutput和output开始

      package check;
      
      public class FirstFileOutput{
      
          public static void main(String[] args) {
              System.out.println("This is output to stable output");
              System.err.println("This is output to stable error");
          }
      }
      
      
      
      package check;
      
      import java.io.InputStream;
      import java.io.IOException;
      import java.io.InputStreamReader;
      
      public class RuntimeExecCheck {
      
          public static void main(String[] args) {
              try {
                  Runtime runTime = Runtime.getRuntime();
                  Process process = runTime.exec("java -classpath C:\\projects\\workspace\\check\\bin check.FirstFileOutput");
                  InputStream inputStream = process.getInputStream();
                  InputStreamReader isr = new InputStreamReader(inputStream);
                  InputStream errorStream = process.getErrorStream();
                  InputStreamReader esr = new InputStreamReader(errorStream);
      
                  int n1;
                  char[] c1 = new char[1024];
                  StringBuffer stableOutput = new StringBuffer();
                  while ((n1 = isr.read(c1)) > 0) {
                      stableOutput.append(c1, 0, n1);
                  }
                  System.out.println("Stable Output: " + stableOutput.toString());
      
                  int n2;
                  char[] c2 = new char[1024];
                  StringBuffer stableError = new StringBuffer();
                  while ((n2 = esr.read(c2)) > 0) {
                      stableError.append(c2, 0, n2);
                  }
                  System.out.println("Stable Error: " + stableError.toString());
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }
      

      不知道为什么会被否决。解释为什么他的假设可能是错误的,但是不要降低问题。- 1个基本的java术语没有正确使用,问题非常模糊,留下很多猜测的余地。考虑用更多的细节来重新整理你的问题,或者简单地阅读java类囊体和其他基础知识。y:你看,这是你应该首先问的问题,而不是马上投反对票。不要求更多信息就投反对票没有任何好处…@William,很抱歉比你晚了几秒钟才按下按钮。我保留投票反对的权利,并随后发表评论。看到没有基本准备的问题令人沮丧对问题的理解和/或努力。投票就像在餐馆给我的小费:你根据服务质量给出超过或低于标准12%的分数。因此,让我们在这里同意不同意。@topchef我迟到了11年,但你说“看到没有基本准备的问题令人沮丧…”。然后帮助修复它。解释为什么你投了否决票。否则你根本帮不上忙。我认为,如果你有权访问一个jar,你应该如何将它添加到类路径中,以便从中加载类。注意:这只会因为你的路径中有java bin而起作用,而对于默认的windows则不是这样installation@AVD:sh在哪里乌尔德
      package check;
      
      public class FirstFileOutput{
      
          public static void main(String[] args) {
              System.out.println("This is output to stable output");
              System.err.println("This is output to stable error");
          }
      }
      
      
      
      package check;
      
      import java.io.InputStream;
      import java.io.IOException;
      import java.io.InputStreamReader;
      
      public class RuntimeExecCheck {
      
          public static void main(String[] args) {
              try {
                  Runtime runTime = Runtime.getRuntime();
                  Process process = runTime.exec("java -classpath C:\\projects\\workspace\\check\\bin check.FirstFileOutput");
                  InputStream inputStream = process.getInputStream();
                  InputStreamReader isr = new InputStreamReader(inputStream);
                  InputStream errorStream = process.getErrorStream();
                  InputStreamReader esr = new InputStreamReader(errorStream);
      
                  int n1;
                  char[] c1 = new char[1024];
                  StringBuffer stableOutput = new StringBuffer();
                  while ((n1 = isr.read(c1)) > 0) {
                      stableOutput.append(c1, 0, n1);
                  }
                  System.out.println("Stable Output: " + stableOutput.toString());
      
                  int n2;
                  char[] c2 = new char[1024];
                  StringBuffer stableError = new StringBuffer();
                  while ((n2 = esr.read(c2)) > 0) {
                      stableError.append(c2, 0, n2);
                  }
                  System.out.println("Stable Error: " + stableError.toString());
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }