Почему моя перезапущенная Java-программа теряет фокус клавиатуры?
Я попытался создать упрощенное отказоустойчивое Java-приложение, которое будет перезапускать себя всякий раз, когда оно было принудительно завершено (в Windows, используя команду CMD CTRL+C).
Пакетный код выглядит так:
@echo off
setlocal
start /wait java BatchWakeMeUpSomehow
if errorlevel 1 goto retry
echo Finished successfully
exit
:retry
echo retrying...
start /wait java BatchWakeMeUpSomehow
И этот код Java:
public class WakeMeUpSomehow {
static class Message extends Thread {
public void run() {
try {
while(true)
{
System.out.println("Hello World from run");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
try {
Runtime.getRuntime().addShutdownHook(new Message());
while(true)
{
System.out.println("Hello World");
Thread.sleep(100);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Я хотел уточнить мое понимание. Я думаю, что поскольку Java работает в среде JVM, у нее есть некоторые ограничения в отношении перезапуска JVM, который был принудительно закрыт (если мы перезапускаем JVM с принудительным отключением через пакетный файл, то он теряет фокусировку курсора и просто запускается в новом окне CMD, которое не может иметь фокус клавиатуры.
Моя цель состояла в том, чтобы это приложение продолжало работать в цикле ("цифровой wackamole"), но я могу когда-либо перезапустить его только один раз (когда оно работает в неотвечающем окне CMD)
Кто-то предложил мне посмотреть на инструмент Apache Daemon, но я не уверен, как это поможет.
1 ответ
Чтобы сделать бесконечный цикл в случае уровня ошибки 1 и выше, добавьте метку перед start
линия:
:run
start /wait java BatchWakeMeUpSomehow
if errorlevel 1 echo retrying... & goto run
echo Finished successfully
Однако это также откроет новое окно, поэтому, если вы хотите перезапустить java
процесс в уже запущенном окне вы можете использовать typeperf
проверить использование процессора (чтобы можно было принудительно закрыть процесс и перезапустить его) или просто запустить java
заново, как только выполнение возвращается в командный файл.
В случае, если
java
процесс выходит (не зависает), мы можем обнаружить егоtasklist
::run start java BatchWakeMeUpSomehow :check timeout 1 >nul tasklist /fi "imagename eq java.exe" | find "java.exe" >nul if errorlevel 1 echo retrying... & goto run goto check
В случае, если
java
процесс зависает и загрузка процессора составляет 0% в течение 1 минуты:if not "%~1"=="childprocess" goto main :loop java BatchWakeMeUpSomehow goto loop :main start "" "%~dpnx0" childprocess :check for /f "skip=2 delims=, tokens=2" %%a in (' typeperf "\process(java)\%% processor time" -sc 1 -si 60 ') do if %%a=="0.000000" taskkill /f /im java.exe goto check