Как бороться с ^ C в консольных приложениях JVM? - PullRequest
5 голосов
/ 03 февраля 2012

Когда запускаемая JVM (на самом деле написанная на Scala, но я склонен полагать, что решение будет примерно таким же для Groovy, Clojure или чистой Java), моя консольная программа завершается пользователем, нажимающим Ctrl + C (или по последовательности выключения системы, я не знаю, есть ли какая-либо разница для программы), как мне убедиться, что внешние ресурсы, которые изменяет приложение (базы данных, файлы, абстрагированные ресурсы веб-службы) остаются в предсказуемом, нелогически поврежденном состоянии?

Ответы [ 3 ]

10 голосов
/ 03 февраля 2012

Вы можете попытаться внедрить ловушку отключения, как указали другие, НО:

В редких случаях виртуальная машина может прерваться, то есть прекратить работу, не выключившись полностью.Это происходит, когда виртуальная машина завершается извне, например, с помощью сигнала SIGKILL в Unix или вызова TerminateProcess в Microsoft Windows.Виртуальная машина также может прервать работу, если собственный метод не работает, например, из-за повреждения внутренних структур данных или попытки доступа к несуществующей памяти.Если виртуальная машина прерывается, тогда нельзя дать никаких гарантий относительно того, будут ли запущены какие-либо перехватчики завершения работы.

Полагаю, вам придется ввести транзакционный контекст в ваше приложение.Для баз данных это довольно просто, для файловой системы вы можете посмотреть на Apache Commons Transaction

7 голосов
/ 03 февраля 2012

Взгляните на Runtime.addShutdownHook .

Обычно вы используете его так:

Runtime.addShutdownHook(new Thread() {
    public void run() {
        // do your clean up here.
    }
});
3 голосов
/ 03 февраля 2012

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

...