Я написал сервис для JIRA (веб-приложение, работающее на tomcat), который запускается периодически (скажем, 1 час).По сути, служба выполняет системную команду через runtime.exec(command)
и анализирует выходные данные, сгенерированные этой командой, а затем обновляет индекс Lucene, и выходные данные будут огромными.
Проблемы:
1) Если я отключу tomcat с помощью shutdown.sh
во время выполнения вышеуказанного сервиса, процесс java (или catalina) не будет уничтожен.И java, и дочерний процесс живут некоторое время, то есть до тех пор, пока системная команда не завершит & service не обработает вывод.Но затем службе не удается обновить индекс, оставляя индекс в несовместимом состоянии.
Если я выключаю tomcat, когда вышеуказанная служба не запущена, все хорошо.Я думаю, это объясняется здесь .Я до сих пор не понимаю, почему JVM не отключается, так как вышеуказанный сервис работает в tomcat?
Обратите внимание, что это единственное java-приложение, работающее на этом компьютере.
2) Затем, если я убью java с помощью kill <pid>
, оба процесса java и child будут уничтожены, что противоречит этот пост .
Это потому, что дочерний процесс отправляет вывод родительскому элементу (java) и после того, как родительский объект убит, дочерний процесс не знает, куда отправить вывод и, таким образом, был убит?пытался использовать shutdownhook , как объяснено в этом посте , но это не работает для меня.Код внутри shutdownhook
выполняется только после того, как процессы java и child завершены с их работой.Таким образом, вызов process.destroy()
внутри shutdownhook здесь бесполезен.
Это кажется очевидным, поскольку JVM все еще работает в моем случае, он не будет вызывать shutdownhooks, пока не запустит свою последовательность выключения.Не знаю, как это работает для другого парня, я имею в виду, почему дочерний процесс, порожденный Java, все еще работает, когда JVM не работает.
4) Если я перезапущу tomcat, новый процесс Java с другим pid
Можно ли программно остановить дочерний процесс при отключении tomcat?
Дайте мне знать, если мне не понятно мое объяснение ...
Здеськод, который выполняет системную команду:
String command = getCommand();
File view = new File(viewPath);
Runtime runtime = Runtime.getRuntime();
try
{
final Process process = runtime.exec(command, null, view);
StreamReader errorStreamReader = new StreamReader(process
.getErrorStream());
Thread errorStreamThread = new Thread(errorStreamReader);
errorStreamThread.start();
revisions = parseRevisionLogs(process.getInputStream());
process.waitFor();
process.getInputStream().close();
process.getErrorStream().close();
process.getOutputStream().close();
}