Запуск 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));

    }  
}  

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


person AKA    schedule 05.03.2013    source источник
comment
вам нужно будет сделать какой-то канал от STDIN sam к sam2, но это может быть больше проблем, чем оно того стоит.   -  person Alex Gittemeier    schedule 05.03.2013
comment
Пожалуйста, изучите соглашения об именах в Java и придерживайтесь их здесь: имена классов должны начинаться с заглавной буквы.   -  person kleopatra    schedule 05.03.2013
comment
я пытался представить простой пример. Спасибо за совет.. :)   -  person AKA    schedule 05.03.2013


Ответы (5)


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

sam2.main(new String[0]);

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

person András Tóth    schedule 05.03.2013
comment
Я не мог понять, что ты имеешь в виду под этим утверждением..!! :( - person AKA; 05.03.2013
comment
Это работает .. :) большое спасибо .. Но когда я использую этот способ .. весь контроль перейдет ко второй программе. поэтому мастер будет выполняться только после завершения второй программы.. должен ли я использовать потоки для решения этой проблемы..?? - person AKA; 05.03.2013
comment
Проблема..!!! когда я сохраняю имя класса второй программы в строковую переменную, возникает следующая ошибка. не удается найти символ tempfile.main(new String[0]); символ: метод main(String []) местоположение: временный файл переменной типа String Что мне делать..?? - person AKA; 06.03.2013
comment
Что ты хочешь? Вы не можете использовать String в качестве экземпляра класса. Возможно, вам следует использовать отражение Java для этой работы. Но отражение обычно не требуется. - person András Tóth; 07.03.2013

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

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

person MadProgrammer    schedule 05.03.2013

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

person Jay Q.    schedule 05.03.2013

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

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

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

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

Вот и все...

person Srinivasan. B    schedule 23.01.2019