你有没有想过从另一个Java程序编译和运行一个Java程序是可能的?我们可以使用Runtime.exec(字符串cmd)
向底层操作系统下发命令。我们将使用相同的方法从另一个Java程序编译和运行Java程序。
从另一个Java程序编译并运行Java程序
让我们编写一个简单的Java程序,它将从另一个Java程序编译和运行。
1package com.journaldev.files;
2
3public class Test {
4
5 public static void main(String[] args) {
6 System.out.println("Start");
7 for(String str : args){
8 System.out.println(str);
9 }
10
11 }
12
13}
下面是我编译和运行测试类的另一个程序。
1package com.journaldev.files;
2
3import java.io.BufferedReader;
4import java.io.InputStream;
5import java.io.InputStreamReader;
6
7public class CompileRunJavaProgram {
8
9 public static void main(String[] args) {
10 try {
11 runProcess("pwd");
12 System.out.println("**********");
13 runProcess("javac -cp src src/com/journaldev/files/Test.java");
14 System.out.println("**********");
15 runProcess("java -cp src com/journaldev/files/Test Hi Pankaj");
16 } catch (Exception e) {
17 e.printStackTrace();
18 }
19
20 }
21
22 private static void printLines(String cmd, InputStream ins) throws Exception {
23 String line = null;
24 BufferedReader in = new BufferedReader(
25 new InputStreamReader(ins));
26 while ((line = in.readLine()) != null) {
27 System.out.println(cmd + " " + line);
28 }
29 }
30
31 private static void runProcess(String command) throws Exception {
32 Process pro = Runtime.getRuntime().exec(command);
33 printLines(command + " stdout:", pro.getInputStream());
34 printLines(command + " stderr:", pro.getErrorStream());
35 pro.waitFor();
36 System.out.println(command + " exitValue() " + pro.exitValue());
37 }
38
39}
注意javac
和java
命令的区别。我们需要这样做,因为Eclipse工作目录是项目根目录,而我的类源目录是src。当我从Eclipse运行上面的程序时,下面是产生的输出。
1pwd stdout: /Users/pankaj/Documents/eclipse-workspace/JavaExceptions
2pwd exitValue() 0
3**********
4Path Serapartor = /
5javac -cp src src/com/journaldev/files/Test.java exitValue() 0
6**********
7java -cp src com/journaldev/files/Test Hi Pankaj stdout: Start
8java -cp src com/journaldev/files/Test Hi Pankaj stdout: Hi
9java -cp src com/journaldev/files/Test Hi Pankaj stdout: Pankaj
10java -cp src com/journaldev/files/Test Hi Pankaj exitValue() 0
下面是我从命令行运行同一个程序时的输出,工作目录是项目根目录。
1pankaj:~ pankaj$ cd /Users/pankaj/Documents/eclipse-workspace/JavaExceptions
2pankaj:JavaExceptions pankaj$ javac -cp src src/com/journaldev/files/Test.java
3pankaj:JavaExceptions pankaj$ javac -cp src src/com/journaldev/files/CompileRunJavaProgram.java
4pankaj:JavaExceptions pankaj$ java -cp src com/journaldev/files/CompileRunJavaProgram
5pwd stdout: /Users/pankaj/Documents/eclipse-workspace/JavaExceptions
6pwd exitValue() 0
7**********
8javac -cp src src/com/journaldev/files/Test.java exitValue() 0
9**********
10java -cp src com/journaldev/files/Test Hi Pankaj stdout: Start
11java -cp src com/journaldev/files/Test Hi Pankaj stdout: Hi
12java -cp src com/journaldev/files/Test Hi Pankaj stdout: Pankaj
13java -cp src com/journaldev/files/Test Hi Pankaj exitValue() 0
14pankaj:JavaExceptions pankaj$
上述程序在unix系统中运行良好,但不能在windows系统中运行,因为windows文件分隔符与unix文件分隔符不同。为了确保它与平台无关,我们可以将命令作为参数传递给Main function.Main函数如下所示:
1public static void main(String[] args) {
2 try {
3 if(args.length < 2) throw new Exception("Mandatory Arguments missing");
4 runProcess(args[0]);
5 runProcess(args[1]);
6 } catch (Exception e) {
7 e.printStackTrace();
8 }
9
10}
我们也可以使用File.separator
以平台无关的方式创建命令。我们也可以从系统getProperty方法System.getProperty()
中获取该属性。对于系统无关的代码,上述程序可按如下方式更改。
1String separator = File.separator;
2System.out.println("File Serapartor = "+separator);
3
4separator = System.getProperty("file.separator");
5System.out.println("File Serapartor = "+separator);
6
7runProcess("javac -cp src src"+separator+"com"+separator+"journaldev"+separator+"files"+separator+"Test.java");
8System.out.println("**********");
9runProcess("java -cp src com"+separator+"journaldev"+separator+"files"+separator+"Test Hi Pankaj");
您将得到与上面相同的输出。以上就是使用Runtime exec方法从另一个Java程序编译和运行Java程序的全部内容。PrintLines()和runProcess()方法取自此post.