Заблокированное приложение JUnique не запускается в случае сбоя приложения

1

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

Приложение не может быть запущено, если оно сработает, оно просто возвращает AlreadyLockedException. Код, который я использовал для блокировки моего приложения, приведен ниже.

public static boolean isRunning() {
    boolean alreadyRunning = false;
    try {
        JUnique.acquireLock(appId);
        alreadyRunning = false;
    } catch (AlreadyLockedException e) {
        logger.error("Unable to acquire lock. There is an instance already running");
        alreadyRunning = true;
    } catch (Throwable t) {
        logger.error("Unable to acquire lock. ", t);
    }
    return alreadyRunning;
}

И код для освобождения моего замка:

public static void release() {
    try {
        JUnique.releaseLock(appId);
    } catch (Throwable t) {
        logger.error("Error releasing the lock", t);
    }
}

Я могу использовать метод release() для решения ожидаемых сбоев. Но реальная проблема возникает, когда приложение неожиданно появляется во время выполнения. Приложение прекращается без освобождения приобретенной блокировки для приложения.

Как мы можем освободить блокировку JUnique, если приложение неожиданно выйдет из строя?

  • 0
    Определите «вылеты». В документации говорится, что блокировка «будет автоматически снята при остановке JVM». Кроме того, распечатайте и AlreadyLockedException трассировку стека этого AlreadyLockedException .
  • 2
    Вы пытаетесь зарегистрировать Thread.UncaughtExceptionHandler
Показать ещё 4 комментария
Теги:
multithreading
swing
uncaughtexceptionhandler

1 ответ

3
Лучший ответ

Это ошибка дизайна JUnique (последняя версия, которую я нашел здесь). Просто нет поддержки для случая сбоя компьютера (BSOD, прерывание питания). Предполагается, что ShutdownHook (который удаляет блокировки, см. JUnique.java) всегда выполняется. Недостаток очевидна в api-docs releaseLock:

"Обратите внимание, что блокировка может быть показана только той же JVM, которая ранее ее приобрела. Если данный идентификатор не соответствует блокировке, принадлежащей текущей JVM, никаких действий не будет предпринято".

Но нет метода forceReleaseLock(String id) который, в свою очередь, означает, что после сбоя компьютера приложение больше не может быть запущено.

В таких случаях довольно часто сообщать пользователю диалог с сообщением "Приложение уже запущено" и кнопкой "ОК", которая показывает окно запущенного приложения. В этом случае вы можете добавить кнопку "Нет, это не так" и при нажатии:

  • убедитесь, что нет открытого окна приложения.
  • проверьте, что JUnique.sendMessage возвращает значение null.
  • удалить содержимое new File(System.getProperty("user.home"), ".junique"); (LOCK_FILES_DIR, см. JUnique.java) или что-то подобное, что менее грубо.
  • запустите приложение.
  • 0
    Я отредактировал ответ и добавил код, который решил мою проблему. Спасибо vanOekel. @MadProgrammer спасибо за ваше предложение.
  • 0
    @Crawler Я не думаю , добавив UncaughtExceptionHandler улучшает , что угодно: ShutdownHook зарегистрирован JUnique уже обеспечивает блокировку удаляется перед нанесением / JVM останавливается (без сбоев).
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню