2014-01-29 4 views
0

Я пытаюсь запустить hookdown для запуска в java. Цель этого крючка - записать в файл журнала, что программа была прервана. Приложение java скомпилировано в файл jar и выполняется с использованием пакетного файла, что означает, что выход приложения переходит в окно cmd.exe. Когда это окно cmd закрыто, я хочу, чтобы приложение регистрировалось, что оно было закрыто.Проблема с запуском завершающего крюка в java

Приложение предназначено для неограниченного использования и выполнения определенных задач в определенное время. Таким образом, программа выполняет серию проверок в цикле «Пока истина». Я не понимаю, почему этот крючок не будет регистрировать, что приложение закрывается!

В основном методе мы имеем:

final Thread mainThread = Thread.currentThread(); 
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() 
{ 
    @Override 
    public void run() 
    { 
     try { mainThread.join(); } 
     catch (InterruptedException e) { } 
     mission.log("Program Closed.", true); 
    } 
} 
)); 

Все «миссия» есть, является экземпляром пользовательского класса моего, который делает запись данных. Когда вы вызываете метод «log», он имеет BufferedWriter и вызывает его методы .write(), .newLine() и .flush().

Я не могу получить строку «Программа закрыта» в моем файле журнала, когда я убью пакетное окно. Что я делаю не так?

+1

Убивание серийного окна убивает процесс, оно не останавливает его изящно. –

+0

Тогда нет ли вообще способа обнаружить пакетный файл и ввести его в журнал? Вы, кажется, говорите мне, что это невозможно вообще. – Drifter64

+0

Я не думаю, что есть способ определить, был ли процесс убит изнутри процесса. –

ответ

3

Принудительно убивает приложение, то есть не изящно, поэтому JVM не знает, что приложение выходит из строя, поэтому крючки отключения не вызываются.

К сожалению, нет способа (в Windows, по крайней мере) предоставить механизм, гарантирующий, что крючок всегда вызывается. Это просто то, что может быть использовано, но нет никакой гарантии.

0

Невозможно всегда выполнять что-либо до выхода вашего процесса. Например. если вы вытащите вилку из розетки, компьютер немедленно выключится. Или, если процесс был убит операционной системой, удалив его из планировщика для процессорного времени, у него также нет никаких шансов.

Однако, если вы удалите код

try { mainThread.join(); } 
    catch (InterruptedException e) { } 

Тогда это будет по крайней мере, быть выполнены в определенных случаях, например, нормальное завершение процесса. Проверка на основной поток здесь не имеет смысла, потому что либо завершающий крюк выполняется в результате завершения основного потока (он вышел из метода main()), либо основной поток будет продолжать работать до тех пор, пока JVM решает прекратить (в случае прекращения извне).

Сравните принятый ответ How to gracefully handle the SIGKILL signal in Java, в котором содержится еще один пример того, что вы пытаетесь сделать.

+0

Хорошо, пример, который вы связали, рассказывает о операционных системах * nix и apple. Насколько я знаю, Windows не имеет эквивалента «kill -9». Я предполагаю, что, закрывая мое окно пакетного файла, отправляет ту же команду уничтожения в JVM. (SIGKILL?) – Drifter64

+0

Я этого не знаю, но вы попытались удалить 2 строки кода и закрыть окно? –

+0

Да. Тем не менее, это все равно не вызовет крючок, что заставляет меня думать, что Джаффар Рамай и Додд10х правы. – Drifter64

0

Закрытие окна убивает процесс, поэтому крюк отключения не будет работать.

Похоже, что вы не хотите, чтобы этот процесс был убит вообще. Вы должны рассмотреть возможность использования чего-то другого, кроме командного скрипта. Вы можете запускать исполняемую банку из планировщика задач Windows и постоянно работать в фоновом режиме - если кто-то не намеренно убивает java или возникает ошибка. В этом случае вы должны пытаться поймать исключения и зарегистрировать их таким образом.

0

Все здесь правильно - вы не можете зарегистрировать принудительную остановку в своей программе. Однако вы можете использовать другую программу для «просмотра» вашей программы и дождаться ее выхода. Затем программа «watcher» может зарегистрировать окончание исходной программы и выйти из нее.

Смежные вопросы