When I launch any third-party application, e.g. Notepad (but you could take anything else), from a Java 9 application and then exit the Java application:
import java.io.*;
public class LaunchNotepad {
public static void main(String[] args) throws IOException {
Runtime.getRuntime().exec(new String[] {"C:\\Windows\\notepad.exe"});
}
}
the launched third party application keeps locking Java 9's lib\modules
file. This makes it hard for our Java application with a private JRE to update itself, because the original directory (containing the JRE) can't be renamed. Here's a screenshot from ProcessExplorer (Sysinternals):
This smells like a Java 9 bug (reported as JDK-8194734), but is there a work-around for launching an application on Windows without locking the lib\modules
file, e.g. by using an external (proxy) application that simply launches the passed parameter as an application?
I fixed this bug. Does this count as a workaround? :)
Otherwise, some workarounds are indeed possible.
Workaround 1: Use awt.Desktop
Scanning through the Java sources, I found that awt.Desktop
can call ShellExecute
for us.
Unfortunately, this method does not allow to pass commandline arguments. You can write a temporary batch file to disk and launch it as workaround.
import java.io.*;
import java.awt.Desktop;
public class LaunchNotepad {
public static void main(String[] args) throws IOException {
File program = new File("C:\\Windows\\notepad.exe");
Desktop.getDesktop().open(program);
}
}
Workaround 2: Use PsExec as proxy
SysInternals PsExec does not inherit files into processes started with it. Remember to use -d
parameter, or PsExec itself will hold the file.
Using cmd.exe
as proxy is not possible, because it always inherits handles.
Workaround 3: Make your own proxy
You will need to use one of two WINAPI's: CreateProcess (specifying bInheritHandles=FALSE
) or ShellExecute.
If you have an Oracle Java Support contract, you should go through the support channels to ask when a fix will be forthcoming.
UPDATE - Based on https://bugs.openjdk.java.net/browse/JDK-8194734, the current answer is likely be "when Java 11 is released". But Oracle may decide to backport the fix to Java 9 and 10.
If you are really desperate for a fix, then consider doing the following:
Download the OpenJDK source code and build your own JVM.
Figure out where the bug is. You seem to know what it is, so it should not be hard to figure out where to look.
Develop a fix for the bug.
Contribute the fix to the OpenJDK project as a patch.
That will increase the likelihood of the problem being fixed sooner in the standard codebase and the distributions produced from it. It will also give you a workaround for in-house testing and for customers who are willing to use your "fixed" JVM.
I mentioned one possible workaround that involved reworking your code which you rejected out of hand. There are others too. AFAIK there are no workarounds that don't involve work for you, one way or another.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With