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

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

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

Спасибо!

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
4
0
4 049
9
Перейти к ответу Данный вопрос помечен как решенный

Ответы 9

Вы должны уметь делать это с помощью команд java.lang.Runtime.exec и оболочки.

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

Также есть Process.destroy (), если вы используете ProcessBuilder API

Ответ принят как подходящий

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

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

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

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

Вы можете использовать java.lang.Process, чтобы делать то, что хотите. Создав вложенный процесс и получив ссылку на экземпляр процесса, вы можете получить ссылки на его стандартные потоки вывода и ошибки. Вы можете периодически отслеживать их и вызывать .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
}

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

Шон

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

Хорошо, суть в следующем:

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

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

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

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

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

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

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

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