我有一个 Main.java 和 Test.java 类,我想在 Test.java 代码中编译并运行 Main.java 。这是我的代码
Process pro1 = Runtime.getRuntime().exec("javac Main.java");
pro1.waitFor();
Process pro2 = Runtime.getRuntime().exec("java Main");
BufferedReader in = new BufferedReader(new InputStreamReader(pro2.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
我只是在 Main.java 中打印“ok”,但此代码不打印任何内容。有什么问题吗?
我修改了代码以包含一些检查:
public class Laj {
private static void printLines(String name, InputStream ins) throws Exception {
String line = null;
BufferedReader in = new BufferedReader(
new InputStreamReader(ins));
while ((line = in.readLine()) != null) {
System.out.println(name + " " + 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());
}
public static void main(String[] args) {
try {
runProcess("javac Main.java");
runProcess("java Main");
} catch (Exception e) {
e.printStackTrace();
}
}
}
这是Main.java:
public class Main {
public static void main(String[] args) {
System.out.println("ok");
}
}
当一切正常时,它就可以工作了:
alqualos@ubuntu:~/tmp$ java Laj
javac Main.java exitValue() 0
java Main stdout: ok
java Main exitValue() 0
现在,例如,如果我在 Main.java 中出现一些错误:
alqualos@ubuntu:~/tmp$ java Laj
javac Main.java stderr: Main.java:3: package Systems does not exist
javac Main.java stderr: Systems.out.println("ok");
javac Main.java stderr: ^
javac Main.java stderr: 1 error
javac Main.java exitValue() 1
java Main stdout: ok
java Main exitValue() 0
它仍然打印“ok”,因为之前编译的 Main.class 仍然存在,但至少您可以看到进程运行时到底发生了什么。
你还需要
pro2.waitFor();
因为执行该过程需要一些时间,并且在该过程完成之前您无法获取 exitValue() 。
我在 Laj 类主函数中添加了条件来检查编译过程是否成功完成..
public class Laj {
private static void printLines(String name, InputStream ins) throws Exception {
String line = null;
BufferedReader in = new BufferedReader(
new InputStreamReader(ins));
while ((line = in.readLine()) != null) {
System.out.println(name + " " + line);
}
}
private static int 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());
return pro.exitValue();
}
public static void main(String[] args) {
try {
int k = runProcess("javac Main.java");
if (k==0)
k=runProcess("java Main");
} catch (Exception e) {
e.printStackTrace();
}
}
}
您可以尝试组合使用两个开源库:jaxec和jhome(我是它们的作者)。这是从 Java 程序调用 Java 程序的方式:
import com.yegor256.Jaxec;
import com.yegor256.Jhome;
// compile it first:
new Jaxec()
.with(new Jhome().path("bin/javac").toString())
.with("Hello.java") // the file name
.exec();
// next, execute it:
new Jaxec()
.with(new Jhome().path("bin/java").toString())
.with("Hello") // the name of the class
.exec();
在后台,它会找到
JAVA_HOME
的位置并调用ProcessBuilder
来运行两个新进程。