1

私はJavaアプリケーションを開発しています。また、ユーザーが同じ Java アプリケーションの複数のインスタンスを同時に実行できないようにしたいと考えていました。Java用のJUniqueアプリロックライブラリを使用しましたが、うまく機能します。しかし、クラッシュすると深刻な問題が発生します。

アプリケーションがクラッシュすると起動できず、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 ロックを解除できますか?

4

1 に答える 1

4

これは、JUnique (ここで見つけた最後のバージョン) の設計上の欠陥です。コンピューター クラッシュ (BSOD、電源中断) のユース ケースに対するサポートはまったくありません。ShutdownHook(ロックを解除します。 JUnique.javaを参照) は常に実行されると想定されます。欠陥はreleaseLockapi-docs で明らかです:

「ロックは、以前に取得した同じ JVM によってのみ解放できることに注意してください。指定された ID が現在の JVM に属するロックに対応していない場合、アクションは実行されません。」

しかしforceReleaseLock(String id)、コンピューターがクラッシュした後にアプリケーションを起動できなくなるという方法はありません。

このような場合、「アプリケーションは既に実行されています」というメッセージと、実行中のアプリケーションのウィンドウを表示する「OK」ボタンを含むダイアログをユーザーに表示するのが一般的です。この場合、「いいえ、そうではありません」というボタンを追加して、クリックすると次のようになります。

  • アプリケーションのウィンドウが開いていないことを確認してください。
  • JUnique.sendMessagenullを返すチェック。
  • (LOCK_FILES_DIR、 JUnique.javanew File(System.getProperty("user.home"), ".junique");を参照)の内容を削除するか、それほど粗雑ではない同様のものを削除します。
  • アプリケーションを開始します。
于 2014-08-29T13:13:01.207 に答える