Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Starting a Java process with the same executable as the current [duplicate]

Tags:

java

I have some Java code that launches a new Java process, effectively using the default system JRE (in my case JDK 8). Instead I need it to run with the version that is running the original process (e.g. JDK 9).

How can I do that? (The solution needs to work on both Java 8 and 9.)

Details

The code currently relies on the default system JRE by simply issuing a java ... command. An alternative would be to use something akin to System.getProperty("java.home") + "/bin/java" (but platform independent), but both have the same problem (for me): They launch a Java process with the JVM version known to the system.

UPDATE: That's utterly wrong, System.getProperty("java.home") indeed does what I want and returns the current JVM's home directory. (Stupid me, I thought I tried that.)

One way to launch with the same Java version, would be to ask the current process for it's executable and reuse that one, but I found no API for that.

like image 733
Nicolai Parlog Avatar asked Dec 21 '17 12:12

Nicolai Parlog


2 Answers

Solution for Java 9 only. With

ProcessHandle.current().info().command().map(Paths::get).orElseThrow();

you get a handle to the current java executable: <JAVA_HOME>/bin/java[.exe]

Now, use that (absolute) path with the new Process API to your liking.

like image 74
Sormuras Avatar answered Nov 14 '22 21:11

Sormuras


If you cannot use the new Java 9 API yet, here you go:

static String getJavaRuntime() throws IOException {
    String os = System.getProperty("os.name");
    String java = System.getProperty("java.home") + File.separator + "bin" + File.separator +
            (os != null && os.toLowerCase(Locale.ENGLISH).startsWith("windows") ? "java.exe" : "java");
    if (!new File(java).isFile()) {
        throw new IOException("Unable to find suitable java runtime at "+java);
    }
    return java;
}

For more details you can take a look how we do it in JOSM's restart action, which has the following requirements:

  • work on Java 8+, Linux, Windows and macOS
  • work with java running a jar file or class files directly (e.g. from an IDE)
  • work with Java Web Start and macOS packaged applications
  • work with paths containing space characters

The code proceeds as follows:

  • finds the java runtime using java.home system property
  • checks whether the sun.java.command system property is available (not the case for IBM JVM), then extracts program main class and program arguments from it.
  • reconstructs the command line either by adding -cp or -jar arguments, depending on what we found at previous step
  • runs the command using Runtime.getRuntime().exec

There is also a lot of stuff concerning JNLP (WebStart) and macOS applications. I assume you're not interested in it but I can explain it if you want.

like image 28
vip Avatar answered Nov 14 '22 22:11

vip