24

How does one obtain the location of the executable of the currently running JVM during runtime? I would like to instantiate another JVM as a subprocess using the ProcessBuilder class.

I am aware that there is the java.home System property, but this doesn't specify the location of the JVM executable. I understand I could do something like this to get the path:

System.getProperties().getProperty("java.home") + File.pathSeparator + "bin" + File.pathSeparator + "java"

This code isn't platform independent, because the Windows executable's name is java.exe, not java. Is there a way to get the path of the JVM executable that takes the platform's idiosyncrasies into account?

Samad Lotia
  • 723
  • 1
  • 7
  • 14
  • 1
    JAVA_HOME points to the JDK and not the JRE. So you're out of luck when the user doesn't have the JDK installed. Also I *do* have the JDK and don't have the environment variable. Still everything works fine. Also on Windows you can drop the `.exe` on the file name for programs you want to run. – Joey Aug 02 '10 at 22:57
  • By the `java.home` System property, I am not referring to an environment variable; rather, I mean the property that exists in `System.getProperties()`. I have verified that JREs have the System property of `java.home`. It's useful to know that the `.exe` extension is optional in Windows. Thanks. – Samad Lotia Aug 02 '10 at 23:00
  • You can do wath the first comment says and assume "bin/java.exe" on Windows and assume "bin/java" on other platforms. There is also "javaw.exe" to consider depending on what you are trying to do. – Paul Jowett Aug 03 '10 at 02:35
  • (Windows only) Here a "funny" way to retrieve it . Get the JVM pid, launch a VBScript to extract the corresponding path : http://www.rgagnon.com/javadetails/java-get-running-jvm-path.html – RealHowTo Jun 18 '14 at 21:19
  • Hmm, is there a special reason why you never accepted an answer here? – GhostCat Jun 09 '19 at 11:53

5 Answers5

13

You could always just use os.name to check if the user is running Windows or not. That'll work on OS X, Linux and Windows at

String jvm_location;
if (System.getProperty("os.name").startsWith("Win")) {
    jvm_location = System.getProperties().getProperty("java.home") + File.separator + "bin" + File.separator + "java.exe";
} else {
    jvm_location = System.getProperties().getProperty("java.home") + File.separator + "bin" + File.separator + "java";
}
cello
  • 5,356
  • 3
  • 23
  • 28
Xenxier
  • 431
  • 4
  • 7
11

Following code obtains path to current java executable by using ProcessHandle.Info of current ProcessHandle.

Result is wrapped in Optional since the access to command info may be restricted by operating system permissions.

String javaExecutablePath = ProcessHandle.current()
    .info()
    .command()
    .orElseThrow();
czerny
  • 15,090
  • 14
  • 68
  • 96
  • `ProcessHandle` has been added in Java 9, if anybody wonders. :) – Bombe Nov 17 '21 at 11:03
  • this doesnt work from install4j or presumably exe4j, and possibly in embedded contexts – Groostav Jan 06 '22 at 23:52
  • It works in embedded context in the sense that the executable the OS spawned will be returned. It is not necessarily an executable that behaves like `java` - as I saw in a jpackaged application. – Queeg May 11 '22 at 08:12
2

This thread has an interesting discussion of the issue covering several platforms: Finding current executable's path without /proc/self/exe

Given that discussion, it should be possible, if you really needed it, to write some JNI wrapper that #ifdef's the current platform and makes the proper native call.

If you're only on Linux the '/proc/self/exe' is a symbolic link to the actual executable being run. This has the advantage of not relying on any environment variables (i.e. PATH or JAVA_HOME). But as I said, it's definitely not platform independent.

Community
  • 1
  • 1
pedorro
  • 3,079
  • 1
  • 24
  • 24
0

Yes, there is a way to get the path of the JVM executable (if it exists). Include it in the configuration of the application. There are lots of ways to do that: Command line argument -- java myApp.Main /path/to/Java; Properties -- java -Dpath.to.java=/path/to/java; etc.

If you want true platform independence, then your whole scheme is flawed because the existence of a JVM executable is not guaranteed. I could imagine a JVM with no need for a java executable.

If you want 99.99% platform independence, then I think you have the tools needed.

emory
  • 10,725
  • 2
  • 30
  • 58
  • 6
    This doesn't answer my question. I am asking how to determine the location of the JVM executable *at runtime*, not a priori before the JVM is started. You assume is that I'm in control of how the JVM is invoked, and this isn't the case. – Samad Lotia Aug 05 '10 at 22:43
  • The OP wants to determine the JVM's executable from inside the program. This means that (a) yes the existence of the JVM executable is guaranteed (though it may not be in a file system, but if that were a possibility the question would have mentioned that), (b) this answer is imposing restrictions on the program's command-line parameters, and requires that this data be threaded through the appliation to the point where it's needed, which means this is the last fallback in case nothing else works. – toolforger May 15 '20 at 06:51
-4

You are trying to fork the entire JVM.

  1. That is extremely inefficient, mainly because of the heaviness of yet another java process. If your heavily doing this, then your program is going to be really slow
  2. Threads exist for this very reason

But if you really must, you can try just executing java -arguments directly, since most standard java installations put java on the cli path.

TheLQ
  • 14,830
  • 14
  • 69
  • 107
  • The question doesn't say anything about launching so you should probably say "if you are using java.exe to launch beware...". The question is only about getting the running java exe. – Paul Jowett Aug 03 '10 at 02:32
  • 1
    In addition to what jowierun wrote, there *are* benefits to forking a JVM: 1. no class loading conflicts between JVMs -- this is important for large applications 2. when running an expensive algorithm, running it as a separate process is a good idea; it gets around the memory limitations – Samad Lotia Aug 05 '10 at 22:39
  • I need the Java path to pass it to a Python subprocess which MAY need to use a library which needs a valid java path itself... kinda odd and ugly, but there you are: a situation where you actually need to know you java.exe path inside a Java VM. – DGoiko Mar 18 '19 at 23:27