【发布时间】:2018-10-22 14:24:14
【问题描述】:
目前我正在努力解决使用 install4j 打包到 .exe 中的单实例 JavaFX 应用程序的问题。该应用程序应该在 Windows 终端服务器上运行,并且每个用户应该只能运行它的一个实例。这意味着,Alice 和 Bob 可以使用应用程序的不同实例,但 Alice 可能只打开一个实例。
使用进程 ID 编写锁定文件不是一个可行的选择,因为应用程序以 Java 8 为目标,它无法始终如一地检索进程 ID。打开套接字也不是一个理想的解决方案,因为同一主机上可能有许多实例。此外,如果某些应用程序在其服务器上随机打开套接字,我想管理员不会那么高兴...
当我使用 install4j 打包应用程序时,我切换了“仅单个实例”功能,该功能在通过完整 RDP 会话连接时似乎运行良好。但是,可以使用 RemoteApp 功能部署应用程序,该功能以某种方式绕过 install4j 的检查机制,允许在 RDP 会话中启动一个实例,并使用 RemoteApp 启动另一个实例。
这引出了两个问题:
- install4j 检查如何工作? (我找不到任何细节......)
- 确保始终为每个用户提供一个实例的最佳解决方案是什么? (并且还要保证故障安全,例如从 JVM 崩溃中恢复)
- 关于
FileLock的可能性:由于不同的操作系统可能对文件锁的处理方式不同,能否保证文件锁是全系统的一个JVM实例独占获取的?
【问题讨论】:
-
为什么锁文件需要有进程id?无论如何,第二个进程都不会具有相同的进程 ID
-
如果 JVM 崩溃,我无法删除锁定文件。因此,应用程序无法再次启动,除非用户手动删除锁定文件
-
并非如此。一旦进程终止,操作系统将释放文件上的锁定。这是大多数操作系统上的标准行为。您只需要在启动时获取文件锁定,无论文件是否已经存在(如果不存在,您只需创建它)。
-
这取决于您如何使用文件进行锁定。您可以检查文件是否存在,或者尝试获取锁。如果您检查是否存在,则需要 pid 来确定该进程是否仍然存在。我补充了第三点我对文件锁定方法的担忧
-
是的,通常的做法是检查文件是否存在,可能尝试删除它(这样你就可以更加确定没有进程甚至试图从中读取),然后重新创建并锁定它。