Можно ли уничтожить виртуальную машину Java с другой виртуальной машины?
-
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().Затем первая виртуальная машина может вызвать этот удаленный метод для завершения работы второй виртуальной машины.