从另一个 Java 程序编译并 运行 一个 Java 程序
Compile and run a Java program from another Java program
我正在编写一个程序,该程序使用 main 方法获取输入“.java”文件的路径。然后程序应该编译那个文件,然后 运行 它。
假设我正在尝试编译的程序 运行 看起来像这样:
Main.java
public class Main {
public static void main(String[] args) {
System.out.println("Hello, world!");
}
}
执行编译并尝试运行它的程序:
Evaluator.java
/**
* Matches any .java file.
*/
private static final PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:**.java");
private static String path;
/**
* Program entry point. Obtains the path to the .java file as a command line argument.
*
* @param args One argument from the command line: path to the .java file.
* @throws Exception
*/
public static void main(String[] args) throws Exception {
if (args.length != 1) {
throw new IllegalArgumentException(
"Expected exactly one argument from the command line.");
}
if (!matcher.matches(Paths.get(args[0]))) {
throw new IllegalArgumentException(
String.format("File %s is not a valid java file.", args[0]));
}
// path is in a valid format
path = args[0];
// compile a program
compile();
// run a program
run();
}
/**
* Compiles a program.
*
* @throws Exception
*/
private static void compile() throws Exception {
System.out.println("Compiling the program ...");
Process p = Runtime.getRuntime().exec("javac " + path);
output("Std.In", p.getInputStream());
output("Std.Out", p.getErrorStream());
p.waitFor();
System.out.println("Program successfully compiled!\n");
}
/**
* Runs a program.
*
* @throws Exception
*/
private static void run() throws Exception {
System.out.println("Executing the program ...");
Process p = Runtime.getRuntime().exec("java " + getProgramName(path));
output("Std.In", p.getInputStream());
output("Std.Out", p.getErrorStream());
p.waitFor();
System.out.println("Program finished!");
}
private static void output(String stream, InputStream in) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(in, CS));
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
System.out.println(String.format("%s: %s", stream, line));
}
}
private static String getProgramName(String path) {
return path.replace(".java", "");
}
}
我的 "Main.java" 文件位于项目根目录中。我正在 运行 使用命令行参数“./Main.java”连接程序。这样做,正确编译程序并产生一个新文件 "Main.class"。但是,run
方法输出如下:
Std.Out: 错误: 无法找到或加载 main class ..Main
这里应该是什么问题?
尝试设置为java process you're launching the correct working directory 然后设置相关的类路径。
这应该有所帮助。
更新
我建议使用方法Runtime.getRuntime().exec(String command, String[] envp, File dir)
。
最后一个参数dir
是进程工作目录。
这里的问题是你在传递参数
./Main.java
相反,您应该将 Main.java
作为参数传递,否则您需要将 getProgramName()
方法更改为 return 正确 Class 名称。
这将使您可以使用 javac
命令完美地编译程序,但是当您需要 运行 程序时会出现问题,因为该命令应该是
java Main
而您正在尝试执行
java ./Main
我正在编写一个程序,该程序使用 main 方法获取输入“.java”文件的路径。然后程序应该编译那个文件,然后 运行 它。
假设我正在尝试编译的程序 运行 看起来像这样:
Main.java
public class Main {
public static void main(String[] args) {
System.out.println("Hello, world!");
}
}
执行编译并尝试运行它的程序:
Evaluator.java
/**
* Matches any .java file.
*/
private static final PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:**.java");
private static String path;
/**
* Program entry point. Obtains the path to the .java file as a command line argument.
*
* @param args One argument from the command line: path to the .java file.
* @throws Exception
*/
public static void main(String[] args) throws Exception {
if (args.length != 1) {
throw new IllegalArgumentException(
"Expected exactly one argument from the command line.");
}
if (!matcher.matches(Paths.get(args[0]))) {
throw new IllegalArgumentException(
String.format("File %s is not a valid java file.", args[0]));
}
// path is in a valid format
path = args[0];
// compile a program
compile();
// run a program
run();
}
/**
* Compiles a program.
*
* @throws Exception
*/
private static void compile() throws Exception {
System.out.println("Compiling the program ...");
Process p = Runtime.getRuntime().exec("javac " + path);
output("Std.In", p.getInputStream());
output("Std.Out", p.getErrorStream());
p.waitFor();
System.out.println("Program successfully compiled!\n");
}
/**
* Runs a program.
*
* @throws Exception
*/
private static void run() throws Exception {
System.out.println("Executing the program ...");
Process p = Runtime.getRuntime().exec("java " + getProgramName(path));
output("Std.In", p.getInputStream());
output("Std.Out", p.getErrorStream());
p.waitFor();
System.out.println("Program finished!");
}
private static void output(String stream, InputStream in) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(in, CS));
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
System.out.println(String.format("%s: %s", stream, line));
}
}
private static String getProgramName(String path) {
return path.replace(".java", "");
}
}
我的 "Main.java" 文件位于项目根目录中。我正在 运行 使用命令行参数“./Main.java”连接程序。这样做,正确编译程序并产生一个新文件 "Main.class"。但是,run
方法输出如下:
Std.Out: 错误: 无法找到或加载 main class ..Main
这里应该是什么问题?
尝试设置为java process you're launching the correct working directory 然后设置相关的类路径。
这应该有所帮助。
更新
我建议使用方法Runtime.getRuntime().exec(String command, String[] envp, File dir)
。
最后一个参数dir
是进程工作目录。
这里的问题是你在传递参数
./Main.java
相反,您应该将 Main.java
作为参数传递,否则您需要将 getProgramName()
方法更改为 return 正确 Class 名称。
这将使您可以使用 javac
命令完美地编译程序,但是当您需要 运行 程序时会出现问题,因为该命令应该是
java Main
而您正在尝试执行
java ./Main