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

时间:2013-07-05 15:10:15

标签: java processbuilder

使用CompileAndRun类,我现在可以编译并运行我的HelloWorld类。 现在我想用它来运行一个需要用户输入的程序。这可以是命令行参数或通过stdin接收的输入。

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

public class CompileAndRun {

public static void main(String[] args) {
    new CompileAndRun();
}

public CompileAndRun() {
    try {
        int result = compile("compileandrun/HelloWorld.java");
        System.out.println("javac returned " + result);
        result = run("compileandrun.HelloWorld");
    } catch (IOException | InterruptedException ex) {
        ex.printStackTrace();
    }
}

public int run(String clazz) throws IOException, InterruptedException {        
    ProcessBuilder pb = new ProcessBuilder("java", clazz);
    pb.redirectError();
    pb.directory(new File("src"));
    Process p = pb.start();
    InputStreamConsumer consumer = new InputStreamConsumer(p.getInputStream());
    consumer.start();

    int result = p.waitFor();

    consumer.join();

    System.out.println(consumer.getOutput());

    return result;
}

public int compile(String file) throws IOException, InterruptedException {        
    ProcessBuilder pb = new ProcessBuilder("javac", file);
    pb.redirectError();
    pb.directory(new File("src"));
    Process p = pb.start();
    InputStreamConsumer consumer = new InputStreamConsumer(p.getInputStream());
    consumer.start();

    int result = p.waitFor();

    consumer.join();

    System.out.println(consumer.getOutput());

    return result;        
}

public class InputStreamConsumer extends Thread {

    private InputStream is;
    private IOException exp;
    private StringBuilder output;

    public InputStreamConsumer(InputStream is) {
        this.is = is;
    }

    @Override
    public void run() {
        int in = -1;
        output = new StringBuilder(64);
        try {
            while ((in = is.read()) != -1) {
                output.append((char) in);
            }
        } catch (IOException ex) {
            ex.printStackTrace();
            exp = ex;
        }
    }

    public StringBuilder getOutput() {
        return output;
    }

    public IOException getException() {
        return exp;
    }
}
}

3 个答案:

答案 0 :(得分:1)

在我看来,更好的解决方案是使用Java 6 Compiler API。你也应该看看javax.tools package documentation

答案 1 :(得分:0)

您应该使用Runtime类来执行此操作。

代码文件--x.java 执行-y.java

现在你应该使用Runtime类的“exec”函数。

像这样

进程p = Runtime.getRuntime()。exec(“cmd / c javac y.java&& java y.java”);

所以现在程序执行from.a这个类的过程。

此方法返回一个进程

所以为了接收刚才执行的这个命令的输出就像这样

p.getOutputStream() //将此outputStream包装在输出流wtiter中,或者可以是Printwriter并读取它直到它不为空

最后输出。

答案 2 :(得分:0)

您可以通过在ProcessBuilder构造函数中添加另一个字符串来添加命令行参数 比如ProcessBuilder pb = new ProcessBuilder("java", clazz,"argument");