Java-приложение с одним экземпляром на пользователя - PullRequest
0 голосов
/ 22 октября 2018

В настоящее время я борюсь с проблемой приложения JavaFX для одного экземпляра, упакованного в .exe с использованием install4j .Приложение должно работать на терминальном сервере Windows, и каждый пользователь должен иметь возможность запускать только один его экземпляр.Это означает, что Алиса и Боб могут использовать отдельные экземпляры приложения, но Алиса может иметь только один открытый экземпляр.

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

Поскольку я использую install4j для упаковки приложения, я переключил «только один экземпляр»функция, которая работает хорошо при подключении через полный сеанс RDP.Однако приложение может быть развернуто с использованием функции RemoteApp, которая каким-то образом обходит механизм проверки install4j , позволяя запускать один экземпляр в сеансе RDP, а другой - с помощью RemoteApp.

Это приводит меня к двум вопросам:

  1. Как работает проверка install4j?(Я не смог найти какие-либо подробности ...)
  2. Каково было бы наилучшее решение для обеспечения единственного экземпляра на пользователя в любое время?(А также быть отказоустойчивым, например, восстанавливаться после сбоев JVM)
  3. Относительно возможности FileLock: поскольку разные операционные системы могут по-разному обрабатывать блокировки файлов, можно ли быть уверенным, что блокировка файла приобретается исключительно одной JVMэкземпляр на всю систему?

Ответы [ 2 ]

0 голосов
/ 23 октября 2018

Сокеты будут немного проблематичными, если вы хотите, чтобы приложение запускалось одновременно под разными пользователями.

Возможна возможность использования NIO FileLock.Вы создаете файл в каталоге пользователя, чтобы другой пользователь мог иметь свой собственный файл блокировки.Ключевым моментом здесь является попытка установить блокировку файла, если файл уже существует, путем попытки удалить его перед повторным созданием.Таким образом, если приложение аварийно завершает работу, а файл все еще там, вы все равно сможете получить блокировку для него.Помните, что ОС должна освободить все блокировки, дескрипторы открытых файлов и системные ресурсы после завершения процесса.

Примерно так:

 public ExclusiveApplicationLock
     throws Exception {

   private final File file;
   private final FileChannel channel;
   private final FileLock lock;

   private ExclusiveApplicationLock()  {

       String homeDir = System.getProperty("user.home");

       file = new File(homeDir + "/.myapp", app.lock");
       if (file.exists()) {
          file.delete();
       }

       channel = new RandomAccessFile(file, "rw").getChannel();
       lock = channel.tryLock();
       if (lock == null)  {
          channel.close();
          throw new RuntimeException("Application already running.");
       }

       Runtime.getRuntime().addShutdownHook(new Thread(() -> releaseLock());            
  }

  private void releaseLock() {
    try {
      if (lock != null) {
        lock.release();
        channel.close();
        file.delete();
      }
    }
    catch (Exception ex) {
       throw new RuntimeException("Unable to release application process lock", ex);
    }
  }
}

Другой альтернативой является использование библиотеки, которая делает это длятебе нравится ЮникЯ сам не пробовал, но ты можешь попробовать.Это кажется очень старым, но я полагаю, что не нужно много чего-то менять, ничего не изменилось в NIO со времен Java 1.4.

http://www.sauronsoftware.it/projects/junique/

Это на Maven Central, так что вы можете легко импортировать его.https://mvnrepository.com/artifact/it.sauronsoftware/junique/1.0.4

Если вы посмотрите на код, то увидите, что он делает то же самое с блокировками файлов: https://github.com/poolborges/it.sauronsoftware.junique/blob/master/src/main/java/it/sauronsoftware/junique/JUnique.java

0 голосов
/ 23 октября 2018

Что касается 1: В Windows программы запуска install4j создают семафор с функцией CreateSemaphore в Windows API.Вы можете проверить имя семафора, запустив модуль запуска из командной строки с аргументом

/create-i4j-log

.

...