【问题标题】:Compile and run a Java program from another Java program从另一个 Java 程序编译并运行一个 Java 程序
【发布时间】:2017-05-03 10:20:59
【问题描述】:

我正在编写一个程序,该程序使用 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

这里应该是什么问题?

【问题讨论】:

  • 尝试将文件作为Main.java而不是./Main.java传递。

标签: java javac


【解决方案1】:

尝试将您正在启动的工作目录设置为 java 进程,然后设置相关的类路径。

这应该会有所帮助。

更新

我建议使用Runtime.getRuntime().exec(String command, String[] envp, File dir)的方法。

最后一个参数dir是进程工作目录。

【讨论】:

【解决方案2】:

这里的问题是你在传递参数

./Main.java

相反,您应该将Main.java 作为参数传递,否则您需要更改getProgramName() 方法以正确返回类名。

这将让您使用javac 命令完美地编译程序,但是当您需要运行程序时会出现问题,因为该命令应该是

java Main

而你正在尝试执行

java ./Main

【讨论】:

  • 但是你必须给它程序的路径,对吧?如果程序不在项目根目录中,而是在“./data/Main.java”中怎么办?那么运行命令应该如何呢?
  • 是的,您必须这样做,但是您需要更改 getProgramName() 方法以返回正确的类名
  • 编译后的文件ie在“./data/Main.class”会怎样?那你如何执行程序呢?它应该有所作为,不是吗?
  • 在这种情况下,您需要使用-cp 标志来提供正确的类路径,然后是类名称java -cp ../somepath../ Main
  • 无论谁投了反对票,请发表评论,以便我可以改进答案或将其删除。如果答案不合适。但请注意评论
猜你喜欢
  • 2013-02-19
  • 2011-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-12
相关资源
最近更新 更多