3

I don't want to find the system's JAVA_HOME. I don't want to lookup system variables.

I need to know exactly where a standalone (bundled JRE) is located at from within the .jar that was launched by it.

Example: User installs application with bundled .jre, and launches it. The program needs to determine not only the current running directory, but also the location of the java.exe that was bundled with it. I could make assumptions based on relative path to the current running directory, but I would prefer a method of absolutely determining the full path of the currently running java.exe. I don't believe this is a duplicate question as I have been able to find no instance of it (or an answer) that isn't answered by referring back to the system or user profile java_home.

I would think this would be a simple task, but so far have found no answer.

Matthieu
  • 2,736
  • 4
  • 57
  • 87
Benjamin
  • 41
  • 5
  • *"... and launches it"* how? Double-clicking a runnable jar will use the `java` from `PATH`. Otherwise it's probably from a script, where the path is coded. Besides, if you want it *"from within the jar"*, chances are *you* developped the app, and would know if you bundled a JRE (unless you developped a plugin). – Matthieu Apr 27 '16 at 20:22
  • 1
    May we ask why you need that path? I'm curious :) – Matthieu Apr 27 '16 at 20:24
  • 1
    Well, in Java 9 there is going to be a relatively simple API for this, at least if I'm reading [this](http://download.java.net/jdk9/docs/api/java/lang/ProcessHandle.Info.html#command--) right. But in the current versions - it's hard. – RealSkeptic Apr 27 '16 at 20:26
  • 1
    @Matthieu: to double click a jar file, `javaw.exe` does not need to be in the path. The extension `.jar` just needs to be registered properly –  Apr 27 '16 at 20:45
  • 2
    Why doesn't `System.getProperty("java.home")` work for you? The only thing it does not give you if the JVM was started using `java.exe` or `javaw.exe` –  Apr 27 '16 at 20:46
  • @a_horse_with_no_name ah you're right! – Matthieu Apr 27 '16 at 20:46
  • @RealSkeptic can't wait... – Matthieu Apr 27 '16 at 20:47
  • Why do I need to know? Because App #1 will launch App #2. The two apps will communicate with each other allowing App #1 to shutdown App #2 whenever an updated .jar file is available. After the update, app #1 relaunches app #2. For stability reasons, the app must be bundled with a JRE. However, the user has ability to either install via unzipping the set to whatever folder structure they prefer, or to install via an installation wrapper (.msi or .exe). I have no control over the end user's choices or installed java version. Hence the bundled JRE. – Benjamin Apr 27 '16 at 22:03
  • @a_horse_with_no_name Because determining the path when it was started using java.exe or javaw.exe is exactly what I need. The question is how to find the path of the JRE when the .jar was NOT launched via the default JVM. – Benjamin Apr 27 '16 at 23:48
  • `System.getProperty("java.home")` does not look at the system's PATH. It shows you the directory where the JVM is installed that is currently running. If your app is a Swing application it doesn't really matter if it was `java.exe` or `javaw.exe` - I would always use `javaw.exe` in order to start a GUI application on Windows (*especially* if it's from within another application) –  Apr 28 '16 at 05:33

2 Answers2

2

If you're on windows, have a look at the last answer on this post : [Find absolute java.exe path programatically from java code

Here is the code

class WhichJava {
    public static void main(String args[]){
        String libPath = System.getProperty("java.library.path");
        String exePath = libPath.substring(0, libPath.indexOf(';')) + 
                                             ((System.console() == null)? “\\javaw.exe" :”\\java.exe");
        System.out.println(exePath);
    }
}
Community
  • 1
  • 1
Sanjeev
  • 1,517
  • 1
  • 18
  • 30
  • This code arbitrarily chooses to use Java.exe. if the current JVM is ran by javaw.exe, this code wont detect that. – RealSkeptic Apr 27 '16 at 21:32
  • 1
    It should be easy to test for both or either, but if all you care about is that path to the executable, it shouldn't matter. – Sanjeev Apr 27 '16 at 21:49
  • The OP wants the actual exe that launched his jar. How does your code provide that? – RealSkeptic Apr 27 '16 at 21:53
  • Thank you for the response, but this appears to lookup based on an environment variable created by the "System's" Java installation. The specific issue is finding the path of java.exe when the jvm is created with a bundled JRE, and not the system instance. – Benjamin Apr 27 '16 at 22:06
  • @Benjamin `java.library.path` is not an environment variable but a System property defined by the running JRE. It might actually be a good choice. Mine gives `C:\Program Files\Java\jdk1.7.0_80\bin` as the first path. – Matthieu Apr 28 '16 at 17:04
  • 1
    @RealSkeptic, the original post explicitly asks about finding the location of "java.exe". – Sanjeev Apr 29 '16 at 21:22
  • 1
    Anyway, I will update my response when I can get to it, but you can find out whether it's javaw.exe vs java.exe by checking (System.console == null); if true it's javaw.exe, otherwise java.exe. – Sanjeev Apr 29 '16 at 21:59
  • @Benjamin, I just update my post with working code. It is not dependent on environment variables and will work for both java.exe and javaw.exe (to see output for javaw redirect it to text file using '>'). – Sanjeev Apr 29 '16 at 23:51
0

I didn't tried this. Just an idea:

  1. Get the current process ID

How can a Java program get its own process ID?

  1. Get specific Windows information of the PID (execute and process the command from Java).

https://superuser.com/questions/768984/show-exe-file-path-of-running-processes-on-the-command-line-in-windows

Community
  • 1
  • 1
Ernesto Campohermoso
  • 7,213
  • 1
  • 40
  • 51
  • Thank you for taking the time to assist. Your proposal is similar to the solution I mentioned in the original post. It relies on the availability of powershell (vs VBS) to complete the task externally. I'm trying to determine if there is a way to accomplish this task completely within the original java app. – Benjamin Apr 27 '16 at 22:09