Используя Java, я могу иметь одну икру JVM другой и затем иметь исходный выход?

Править: Это кажется моим тестом, чтобы определить, вышла ли исходная JVM, был испорчен для начала (см. комментарии к принятому ответу). Извините за шум.

У меня есть потребность иметь рабочую JVM, запускают другую JVM и затем выходят. Я в настоящее время пытаюсь сделать это через Runtime.getRuntime().exec(). Другая JVM запускается, но моя исходная JVM не выйдет, пока "дочерний" процесс JVM не останавливается. Это появляется то использование Runtime.getRuntime().exec() создает отношения отцов и детей между процессами. Там некоторый путь состоит в том, чтобы отделить порожденный процесс так, чтобы родитель мог умереть, или некоторый другой механизм для порождения процесса без каких-либо отношений к процессу создания?

Обратите внимание, что это точно походит на этот вопрос: Используя Java, чтобы породить процесс и сохранить его бегущий за родительскими выходами, но принятым ответом там на самом деле не работает, по крайней мере, не в моей системе (Windows 7, Java 5 и 6). Кажется, что, возможно, это - зависимое от платформы поведение. Я ищу независимый от платформы способ надежно вызвать другой процесс и позволить моему исходному процессу умереть.

Например, предположите, что у меня есть файл банки в C:\myjar.jar и я хочу выполнить класс com.example.RunMe это живет в той банке. Позволяет говорят, что класс открывается JOptionPane и затем выходит, после того как пользователь совершил нападки хорошо.

Теперь, следующее является программой, работающей в JVM № 1:

public static void main(String[] args) {
    String javaHome = System.getProperty("java.home");
    String os = System.getProperty("os.name");
    String javawBin = javaHome + File.separator + "bin" + File.separator + "javaw";

    if (os.toLowerCase().contains("win")) {
        javawBin += ".exe";
    }

    List cmd = new ArrayList();

    cmd.add("\"" + javawBin + "\"");
    cmd.add("-cp");
    cmd.add("\"C:\\myjar.jar\"");
    cmd.add("com.example.RunMe");

    System.out.println("Running: " + cmd);

    try {

        System.out.println("Launching...");
        Process p = Runtime.getRuntime().exec(cmd.toArray(new String[cmd.size()]));

        new Thread(new StreamGobbler(p.getInputStream())).start();
        new Thread(new StreamGobbler(p.getErrorStream())).start();

        System.out.println("Launched JVM.");

        System.exit(0);

    } catch (IOException e) {
        e.printStackTrace();
    }

}

private static class StreamGobbler implements Runnable {
    InputStream stream;

    StreamGobbler(InputStream stream) {
        this.stream = stream;
    }

    public void run() {
        byte[] buf = new byte[64];

        try {
            while (stream.read(buf) != -1)
                ;
        } catch (IOException e) {

        }
    }
}

Наблюдаемое поведение состоит в том что и "Запускающийся..." и "Запущенная JVM". печатаются, но JVM № 1 только выходит после удара хорошо в JOptionPane, запущенном JVM № 2. Также - поведение является тем же, начинаете ли Вы против течения потоки индюка или нет.

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

12
задан Community 23 May 2017 в 10:32
поделиться

4 ответа

Я только что попробовал следующий код, и я вижу порождение процессов и выход главного из них на Vista и Java 6. Я думаю, что с вашим кодом может происходить что-то другое.

public class Test {
    public static void main(String[] args) throws Exception {
        if(args.length == 0)
            Runtime.getRuntime().exec("javaw Test loop");
        else
            while(true){}
    }
}
4
ответ дан 2 December 2019 в 23:42
поделиться

Насколько мне известно, завершение процесса довольно часто приводит к уничтожению всех дочерних процессов. Я сомневаюсь, что есть независимый от платформы способ сделать это.

0
ответ дан 2 December 2019 в 23:42
поделиться

Windows не устанавливает между процессами отношения "родитель-ребенок", как это делают системы Unix. Вполне вероятно, что ваш родительский процесс не завершается, потому что в нем все еще выполняется поток. Этот поток может ждать завершения дочернего процесса, что может объяснить, почему родительский процесс завершается, когда завершается дочерний.

0
ответ дан 2 December 2019 в 23:42
поделиться

Ваши потоки, выполняющие StreamGobblers , находятся внутри процесса №1 и не являются потоками демона, поэтому процесс №1 не завершается до тех пор, пока эти потоки не будут завершены, когда потоки они поглощение уйти, как только процесс № 2 закончится.

Выньте две линии, которые образуют эти нити.

0
ответ дан 2 December 2019 в 23:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: