如何从另一个Java程序编译和运行Java程序

时间:2020-02-23 14:34:00  来源:igfitidea点击:

您是否曾经想过可以从另一个Java程序编译并运行一个Java程序?我们可以使用Runtime.exec(String cmd)向底层操作系统发出命令。
我们将使用相同的方法从另一个Java程序编译并运行一个Java程序。

从另一个Java程序编译并运行Java程序

让我们编写一个简单的Java程序,该程序将从另一个Java程序编译并运行。

package com.theitroad.files;

public class Test {

  public static void main(String[] args) {
      System.out.println("Start");
      for(String str : args){
          System.out.println(str);
      }

  }

}

这是我正在编译和运行Test类的另一个程序。

package com.theitroad.files;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

public class CompileRunJavaProgram {

  public static void main(String[] args) {
      try {
          runProcess("pwd");
          System.out.println("**");
          runProcess("javac -cp src src/com/theitroad/files/Test.java");
          System.out.println("**");
          runProcess("java -cp src com/theitroad/files/Test Hi Pankaj");
      } catch (Exception e) {
          e.printStackTrace();
      }
      
  }

  private static void printLines(String cmd, InputStream ins) throws Exception {
      String line = null;
      BufferedReader in = new BufferedReader(
          new InputStreamReader(ins));
      while ((line = in.readLine()) != null) {
          System.out.println(cmd + " " + line);
      }
    }

    private static void runProcess(String command) throws Exception {
      Process pro = Runtime.getRuntime().exec(command);
      printLines(command + " stdout:", pro.getInputStream());
      printLines(command + " stderr:", pro.getErrorStream());
      pro.waitFor();
      System.out.println(command + " exitValue() " + pro.exitValue());
    }

}

注意" javac"和" java"命令的区别。
我们需要这样做,因为Eclipse工作目录是项目的根目录,但是我的类源目录是src。

当我从Eclipse运行上述程序时,这是产生的输出。

pwd stdout: /Users/pankaj/Documents/eclipse-workspace/JavaExceptions
pwd exitValue() 0
**
Path Serapartor = /
javac -cp src src/com/theitroad/files/Test.java exitValue() 0
**
java -cp src com/theitroad/files/Test Hi Pankaj stdout: Start
java -cp src com/theitroad/files/Test Hi Pankaj stdout: Hi
java -cp src com/theitroad/files/Test Hi Pankaj stdout: Pankaj
java -cp src com/theitroad/files/Test Hi Pankaj exitValue() 0

这是当我从命令行运行相同程序时的输出,工作目录是项目根目录。

pankaj:~ pankaj$cd /Users/pankaj/Documents/eclipse-workspace/JavaExceptions
pankaj:JavaExceptions pankaj$javac -cp src src/com/theitroad/files/Test.java
pankaj:JavaExceptions pankaj$javac -cp src src/com/theitroad/files/CompileRunJavaProgram.java 
pankaj:JavaExceptions pankaj$java -cp src com/theitroad/files/CompileRunJavaProgram
pwd stdout: /Users/pankaj/Documents/eclipse-workspace/JavaExceptions
pwd exitValue() 0
**
javac -cp src src/com/theitroad/files/Test.java exitValue() 0
**
java -cp src com/theitroad/files/Test Hi Pankaj stdout: Start
java -cp src com/theitroad/files/Test Hi Pankaj stdout: Hi
java -cp src com/theitroad/files/Test Hi Pankaj stdout: Pankaj
java -cp src com/theitroad/files/Test Hi Pankaj exitValue() 0
pankaj:JavaExceptions pankaj$

上面的程序在Unix系统上可以正常运行,但是在Windows系统中不能运行,因为Windows文件分隔符与Unix文件分隔符不同。

为了确保它与平台无关,我们可以将命令作为参数传递给main函数。
主要功能如下所示:

public static void main(String[] args) {
  try {
      if(args.length < 2) throw new Exception("Mandatory Arguments missing");
      runProcess(args[0]);
      runProcess(args[1]);
  } catch (Exception e) {
      e.printStackTrace();
  }
  
}

我们也可以使用File.separator以平台无关的方式创建命令。
我们也可以从System getProperty方法`System.getProperty(" file.separator")"获取此属性。

对于与系统无关的代码,可以像下面一样更改以上程序。

String separator = File.separator;
System.out.println("File Serapartor = "+separator);

separator = System.getProperty("file.separator");
System.out.println("File Serapartor = "+separator);

runProcess("javac -cp src src"+separator+"com"+separator+"theitroad"+separator+"files"+separator+"Test.java");
System.out.println("**");
runProcess("java -cp src com"+separator+"theitroad"+separator+"files"+separator+"Test Hi Pankaj");

您将获得与上述相同的输出。
这就是使用Runtime exec方法来编译和运行另一个Java程序中的Java程序。