Можно ли уничтожить виртуальную машину Java с другой виртуальной машины?

StackOverflow https://stackoverflow.com/questions/63758

  •  09-06-2019
  •  | 
  •  

Вопрос

У меня есть Java-приложение, которое запускает другое Java-приложение.Программа запуска имеет сторожевой таймер и периодически получает уведомления от второй виртуальной машины.Однако, если уведомления не получены, то вторая виртуальная машина должна быть отключена, и программа запуска выполнит некоторые дополнительные действия по очистке.

Вопрос в том, есть ли какой-нибудь способ сделать это, используя только java?пока мне приходится использовать некоторые собственные методы для выполнения этой операции, и это как-то некрасиво.

Спасибо!

Это было полезно?

Решение

Возможно, я что-то упускаю, но не могли бы вы позвонить в destroy() метод на основе Process объект, возвращенный Runtime.exec()?

Другие советы

Вы можете использовать java.lang.Процесс делать то, что ты хочешь.После того как вы создали вложенный процесс и у вас есть ссылка на экземпляр процесса, вы можете получить ссылки на его стандартные потоки out и err.Вы можете периодически отслеживать их и вызывать .destroy(), если хотите закрыть процесс.Все это может выглядеть примерно так:

Process nestedProcess = new ProcessBuilder("java mysubprocess").start();
InputStream nestedStdOut = nestedProcess.getInputStream(); //kinda backwards, I know
InputStream nestedStdErr = nestedProcess.getErrorStream();
while (true) {
    /*
       TODO: read from the std out or std err (or get notifications some other way)
       Then put the real "kill-me" logic here instead of if (false)
    */
    if (false) {
        nestedProcess.destroy();
        //perform post-destruction cleanup here
        return;
    }

    Thread.currentThread().sleep(1000L); //wait for a bit
}

Надеюсь, это поможет,

Шон

Вы также можете опубликовать сервис (через burlap, hessian и т.д.) На второй виртуальной машине, которая вызывает System.exit(), и использовать его из JVM watchdog.Если вы хотите отключить вторую JVM только тогда, когда она перестанет отправлять эти периодические уведомления, возможно, она не в состоянии ответить на вызов службы.

Вызов команд оболочки с помощью java.lang.Runtime.exec(), вероятно, ваш лучший выбор.

Обычный способ сделать это - вызвать Process.destroy()...однако это неполное решение, поскольку при использовании sun JVM на * nix уничтожаются карты на SIGTERM, который не гарантирует завершение процесса (для этого вам также понадобится SIGKILL).Конечным результатом является то, что вы не можете осуществлять реальное управление процессами с помощью Java.

Есть несколько открытых ошибок по этой проблеме, см.:текст ссылки

java.lang.У процесса есть метод waitFor() для ожидания завершения процесса и метод destroy() для завершения подпроцесса.

Итак, суть дела заключается в следующем:

Я использовал Process API для закрытия второй виртуальной машины, но это не сработало.

Причина в том, что мое второе приложение - это приложение Eclipse RCP, и я запустил его с помощью прилагаемого лаунчера eclipse.exe.

Однако это означает, что метод Process API destroy() будет нацелен на процесс eclipse.exe.Завершение этого процесса оставляет Java-процесс невредимым.Итак, один из моих коллег написал небольшое приложение, которое уничтожит нужное приложение.

Итак, одно из решений для использования Process API (и удаления избыточных промежуточных шагов) - отказаться от Eclipse launcher, чтобы моя первая виртуальная машина дублировала все его функциональные возможности.

Думаю, мне пора приниматься за работу.

Вы должны быть в состоянии выполнять эти команды java.lang.Runtime.exec и shell.

Вы можете заставить java-код обнаружить платформу во время выполнения и запустить команду процесса kill платформы.Это действительно усовершенствование вашего текущего решения.

Есть также Обработать.уничтожить(), если вы используете ProcessBuilder - разработчик процессов API

Не совсем управление процессами, но вы могли бы запустить сервер rmi на виртуальной машине Java, которую вы запускаете, и привязать удаленный экземпляр с методом, который выполняет любую требуемую очистку и вызывает System.exit().Затем первая виртуальная машина может вызвать этот удаленный метод для завершения работы второй виртуальной машины.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top