Скомпилируйте и запустите программу Java из другой программы Java

используя класс CompileAndRun, теперь я могу скомпилировать и запустить свой класс HelloWorld. теперь я хочу использовать это для запуска программы, которая требует ввода пользователей. это может быть либо аргумент командной строки, либо ввод, полученный через стандартный ввод.

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;
    }
}
}

person user2549648    schedule 05.07.2013    source источник
comment
Вы описали проблему, но до сих пор не задали вопрос (не говоря уже о конкретном вопросе, на который можно было бы ответить). Какой у вас ваш вопрос?   -  person Andrew Thompson    schedule 05.07.2013
comment
Непонятно, в чем вопрос, поэтому прошу закрыть.   -  person Ingo    schedule 05.07.2013
comment
Обратите внимание, что пакет javax.tools обеспечивает программный доступ к компилятору: docs.oracle.com/javase/7/docs/api/javax/tools/   -  person Puce    schedule 05.07.2013


Ответы (3)


На мой взгляд, лучшим решением является использование Java 6. API компилятора. Вам следует ознакомиться с документацией по пакету javax.tools тоже.

person zacheusz    schedule 05.07.2013

Для этого следует использовать класс Runtime.

файл кода --x.java для выполнения-y.java

Теперь вы должны использовать функцию «exec» класса Runtime.

как это

Процесс p=Runtime.getRuntime().exec("cmd /c javac y.java && java y.java");

так что теперь программа выполняется из процесса, созданного этим классом.

Этот метод возвращает процесс

поэтому, чтобы получить вывод этой только что выполненной команды, сделайте так

p.getOutputStream() // обернуть этот outputStream в поток вывода wtiter или может быть Printwriter и прочитать его, пока он не станет нулевым

и, наконец, вывести его.

person cafebabe1991    schedule 05.07.2013
comment
мой вопрос: моя другая программа говорит, что HelloWorld требует, чтобы пользователь ввел свое имя через стандартный ввод, а затем печатает приветственное имя. теперь я создал графический интерфейс, в котором, когда пользователь нажимает кнопку «Скомпилировать и запустить», выполняется класс CompilandRun. теперь, когда программа CompileandRun запускается, она должна попросить пользователя ввести имя в графическом интерфейсе, обработать этот ввод и затем напечатать hello aaa - person user2549648; 06.07.2013
comment
затем вам нужно добавить полученный ввод к выводу другой программы, которая говорит привет` - person cafebabe1991; 09.07.2013

Вы можете добавить аргументы командной строки, добавив еще одну строку в конструктор ProcessBuilder, например ProcessBuilder pb = new ProcessBuilder("java", clazz,"argument");

person Gaurav Sharma    schedule 05.07.2013