Got a task to make new version of our software to new client, and I need to make application behave so, that originally started application starts another and stays open at the back. At the moment original one is closed when new starts. Original application is kind of a loader, it's whole purpose is to download other applications from server and run one of them. That's why FileLock is used and that is probably the reason why I can't figure out how to keep the original open at the back and succesfully open the new one. I managed to make that work in Linux, but unfortunately our client uses Windows 10...
Some variables:
private final List<FileLock> locks = new ArrayList<FileLock>();
private final File applicationPath;
private final String application;
Loader constructor
public Loader(String[] args) throws IOException {
this.args = args;
applicationPath = new File(THIS_DIRECTORY, application + ".jar");
tryLock("loader");
tryLock(application);
}
load() is called in main after the constructor is made, nothing fancy there.
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;
}
}
}
In Linux I was able to make application work as I wanted by replacing content of tryLock() with just return and adding waitFor() to Processbuilder's command. In windows new application doesn't start until first one is killed.
Problem seems to occur when new process is launched, in Windows 10 Java calls Unsafe.park() method and it halts until original process is closed.
So I had to ProcessBuilder's inheritIO method be able to open new process. Now it works as intended. Also added waitFor() for process:
ProcessBuilder builder = new ProcessBuilder(command);
builder.directory(new File(workingDir.toString()));
builder.inheritIO();
Process p = builder.start();
p.waitFor();