it-roy-ru.com

Запуск программы 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));

    }  
}  

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

10
BheeMa

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

sam2.main(new String[0]);

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

21
András Tóth

Каждый процесс должен быть запущен и завершен. Вы можете использовать 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;
        }
    }
}

Теперь очевидно, что вы должны проверить возвращаемые результаты процессов и, возможно, создать лучший механизм взаимодействия с процессами, но это основная идея ...

11
MadProgrammer

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

1
Jay Q.

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

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

Это оно...

0
Srinivasan. B

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

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