Запуск java-программы из другой java-программы

Я работаю над простой java-программой. Он просто компилирует и выполняет другую java-программу. Я использую функцию Runtime.exec() для компиляции и запуска. Нет проблем с компиляцией. но когда он запускается, если второй программе нужен ввод для чтения с клавиатуры, я не могу дать его из мастер-процесса. Я использовал функцию getOutputStream(). но это не помогло. Я предоставлю свой код.

public class sam {  
    public static void main(String[] args) throws Exception {  
        try { 
             Process p = Runtime.getRuntime().exec("javac sam2.java");
             Process p2 = Runtime.getRuntime().exec("java sam2");
             BufferedReader in = new BufferedReader(  
                                new InputStreamReader(p2.getInputStream()));

             OutputStream out = p.getOutputStream();
             String line = null; 
             line = in.readLine();
             System.out.println(line);
             input=input+"\n";
             out.write(input.getBytes());
             p.wait(10000);
             out.flush();
        }catch (IOException e) {  
             e.printStackTrace();  
        }  
    }  
}  

Это моя основная программа (sam.java).

Ниже приведен код sam2.java

public class sam2 {  
public static void main(String[] args) throws Exception {  

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String str; 
    System.out.println("Enter the number..\n");
    str = br.readLine(); 
    System.out.println(Integer.parseInt(str));

    }  
}  

Нет проблем, если моя вторая программа имеет только инструкции печати. Но проблема возникает, когда я должен что-то читать с другого.

Ответ 1

Это немного странно, но вы можете запустить вторую программу, не разворачивая ее. Просто назовите основной метод. Поэтому забудьте раздел времени выполнения и сделайте следующее:

sam2.main(new String[0]);

Конечно, таким образом вы должны скомпилировать sam2 во время компиляции

Ответ 2

Каждый процесс должен быть разрешен для запуска и завершения. Вы можете использовать Process#waitFor для этой цели. В равной степени вам необходимо одновременно использовать любой результат процесса. waitFor будет заблокирован, поэтому вам потребуется использовать Thread для чтения ввода (и, если вам нужно, записать вывод в процесс)

В зависимости от местоположения файла java/class вам также может потребоваться указать начальную папку, с которой может начаться выполнение процесса.

Большая часть этого значительно проще с помощью ProcessBuilder

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

Вы можете просто вызвать основной метод второго класса. Основной метод аналогичен любому другому статическому методу.

Ответ 4

Вот что сработало для меня:

try {
    single.main(new String[0]);
} catch (Exception e) {
    JOptionPane.showMessageDialog(null, e);
}

Ответ 5

Просто вызовите файл основного класса. Например, если ваше имя файла класса java - xyz.java, вы можете вызывать и выполнять его в приложении java swing по щелчку JButton, код

private void Btn_createdatabaseActionPerformed(java.awt.event.ActionEvent evt) {                                                   
       xyz.main(new String[0]);
}

Это...