5

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.

Nicolai Parlog
  • 47,972
  • 24
  • 125
  • 255

2 Answers2

4

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.

Sormuras
  • 8,491
  • 1
  • 38
  • 64
3

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.

vip
  • 1,707
  • 2
  • 16
  • 46
  • But doesn't that use the executable found in the `java.home` system property? Because that doesn't fit my bill. – Nicolai Parlog Dec 21 '17 at 13:28
  • It should be fine. All of our tests show that `java.home` property is filled in with the current Java runtime, not the default system one. Did you check? – vip Dec 21 '17 at 13:30
  • I'm sure I've tried that but I'm starting to discover the same... weird. I'll be back after more tests... – Nicolai Parlog Dec 21 '17 at 13:32
  • 1
    Shorter version: `Path java = Paths.get(System.getProperty("java.home") , "bin", (...) ? "java.exe" : "java"); if (!Files.isRegularFile(java)) ...` – DodgyCodeException Dec 22 '17 at 09:44