Открытие нового процесса в Java и сохранение текущего открытым - PullRequest
0 голосов
/ 11 января 2019

У меня была задача создать новую версию нашего программного обеспечения для нового клиента, и мне нужно, чтобы приложение работало так, чтобы изначально запущенное приложение запускало другое и оставалось открытым сзади. На данный момент оригинал закрывается при запуске нового. Оригинальное приложение является своего рода загрузчиком, его цель - загрузить другие приложения с сервера и запустить одно из них. Вот почему используется FileLock, и это, вероятно, причина, по которой я не могу понять, как сохранить оригинал открытым сзади и успешно открыть новый. Мне удалось заставить это работать в Linux, но, к сожалению, наш клиент использует Windows 10 ...

Некоторые переменные:

private final List<FileLock> locks = new ArrayList<FileLock>();
private final File applicationPath;
private final String application;

Конструктор загрузчика

public Loader(String[] args) throws IOException {
    this.args = args;

    applicationPath = new File(THIS_DIRECTORY, application + ".jar");

    tryLock("loader");
    tryLock(application);
}

load () вызывается в main после того, как конструктор сделан, ничего особенного там нет.

private void load() throws Exception 
    checkAndDownloadUpdate(application, applicationPath);

    String javaBin = getJavaBinary();
    List<String> command = new ArrayList<String>();
    command.addAll(Arrays.asList(javaBin, THIS_FILE.getAbsolutePath(), "-jar", applicationPath.getAbsolutePath()));
    command.addAll(Arrays.asList(args));

    new ProcessBuilder(command).start();
}

TryLock:

private void tryLock(String name) {
    File path = new File(THIS_DIRECTORY, name + "_lock");
    long waitUntil = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(10);
    while (System.currentTimeMillis() < waitUntil) {
        try {
            FileLock fileLock = tryLock(path);
            if (fileLock != null) {
                locks.add(fileLock);
                return;
            }
        }
}

В Linux я смог заставить приложение работать так, как я хотел, заменив содержимое tryLock () просто на return и добавив waitFor () в команду Processbuilder. В Windows новое приложение не запускается, пока не будет убито первое.

Проблема возникает при запуске нового процесса, в Windows 10 Java вызывает метод Unsafe.park () и останавливается до закрытия исходного процесса.

Ответы [ 2 ]

0 голосов
/ 16 января 2019

Таким образом, мне пришлось, чтобы метод ProcessBuilder наследовал новый процесс. Теперь это работает как задумано. Также добавлен waitFor () для процесса:

    ProcessBuilder builder = new ProcessBuilder(command);
    builder.directory(new File(workingDir.toString()));
    builder.inheritIO();
    Process p = builder.start();
    p.waitFor();
0 голосов
/ 11 января 2019

Я думаю, это из-за дескриптора файла в Windows, который не позволит второму процессу получить блокировку файла. Только когда первый процесс снимет блокировку, второй сможет его получить.

Я бы попытался избежать блокировок файлов и отслеживал только дочерний процесс

ProcessBuilder builder = new ProcessBuilder("comman.exe");
Process process = builder.start();
if (process.isAlive()) {
  //wait
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...