简体   繁体   English

如果应用程序崩溃,JUnique锁定的应用程序不会运行

[英]JUnique locked application doesn't run if the application crashes

I'm developing a Java application. 我正在开发一个Java应用程序。 And I wanted to prevent a user to run simultaneously more instances of the same Java application. 我想阻止用户同时运行同一Java应用程序的更多实例。 I used JUnique app locking library for Java and it works great. 我使用JUnique app锁定库来实现Java,它运行得很好。 But has a serious issue when it crashes. 但是当它崩溃时有一个严重的问题。

The application cannot be started if it crashes, it just returns AlreadyLockedException. 如果应用程序崩溃,则无法启动它,它只返回AlreadyLockedException。 The code I used to lock my application is below. 我用来锁定我的应用程序的代码如下。

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;
}

And code to release my lock is: 释放锁的代码是:

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

I can use release() method for dealing with expected crashes. 我可以使用release()方法来处理预期的崩溃。 But the real problem occurs when application crashes unexpectedly during runtime. 但是,当应用程序在运行时意外崩溃时,会出现真正的问题。 The application is terminated without releasing the acquired lock for application. 终止应用程序而不释放获取的应用程序锁。

How can we release JUnique lock if the application unexpectedly crashes? 如果应用程序意外崩溃,我们如何释放JUnique锁?

It is a design flaw of JUnique (last version I found here ). 这是JUnique的设计缺陷(我在这里找到的最新版本)。 There is simply no support for the use case of a computer crash (BSOD, power interrupt). 根本不支持计算机崩溃的用例(BSOD,电源中断)。 It is assumed that the ShutdownHook (which removes the locks, see JUnique.java ) is always executed. 假设始终执行ShutdownHook (删除锁,请参阅JUnique.java )。 The flaw is evident in the releaseLock api-docs: 这个漏洞在releaseLock api-docs中很明显:

"Please note that a lock can be realeased only by the same JVM that has previously acquired it. If the given ID doens't correspond to a lock that belongs to the current JVM, no action will be taken." “请注意,锁只能由之前获取它的同一个JVM重新发布。如果给定的ID不对应于属于当前JVM的锁,则不会采取任何操作。

But there is no method forceReleaseLock(String id) which in turn means that after a computer crash, the application can no longer be started. 但是没有方法forceReleaseLock(String id) ,这反过来意味着在计算机崩溃后,应用程序无法再启动。

In these kind of cases it is quite common to present the user a dialog with a message "The application is already running" and an "OK" button that shows the window of the running application. 在这种情况下,向用户呈现带有“应用程序已在运行”消息的对话框和显示正在运行的应用程序窗口的“确定”按钮是很常见的。 In this case, you could add a button "No, it is not" and when clicked: 在这种情况下,您可以添加一个按钮“不,它不是”,点击时:

  • check that there is no open window of the application. 检查应用程序没有打开的窗口。
  • check that JUnique.sendMessage returns null. 检查JUnique.sendMessage返回null。
  • delete the contents of new File(System.getProperty("user.home"), ".junique"); 删除new File(System.getProperty("user.home"), ".junique");的内容new File(System.getProperty("user.home"), ".junique"); (the LOCK_FILES_DIR, see JUnique.java ), or something similar that is less crude. (LOCK_FILES_DIR,参见JUnique.java ),或类似的东西,不那么粗糙。
  • start the application. 启动应用程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM