8

So, for a project I am working on, I need to find out where a javaw.exe is located on a user's machine. How do I do that? Assuming that user is on Windows machine

The method that I used is limited to English versions of Windows only.
I looked for where the OS is installed, locate the Program Files directory, locate Java, jdk directory, bin, then javaw.exe. I know this will not work on non-English versions of Windows.

What is the human-language-independent way to do this ?

An SO User
  • 24,612
  • 35
  • 133
  • 221
  • Do you want the executable running the current Java code, or any arbitrary javaw.exe? – Andy Thomas Jul 11 '13 at 19:56
  • @AndyThomas Any arbitrary. If multiple `javaw.exe` exist, then the latest one :) – An SO User Jul 11 '13 at 19:58
  • There exist OS-specific search APIs for finding files, and for getting the version from an executable. On Windows, you can use the Windows Search API to search, and ::GetFileVersionInfo(...) to get the version. Note that the search can take some time to complete. An alternative is to ship your own JVM, making it trivial to find by a relative path. – Andy Thomas Jul 11 '13 at 20:06
  • @LittleChild: Note that you usually won't find JDK installed on the average user's PC. Your chances are better looking for a JRE installation. – gkalpak Jul 12 '13 at 07:31

5 Answers5

9

For the sake of completeness, let me mention that there are some places (on a Windows PC) to look for javaw.exe in case it is not found in the path: (Still Reimeus' suggestion should be your first attempt.)

1.
Java usually stores it's location in Registry, under the following key:
HKLM\Software\JavaSoft\Java Runtime Environement\<CurrentVersion>\JavaHome

2.
Newer versions of JRE/JDK, seem to also place a copy of javaw.exe in 'C:\Windows\System32', so one might want to check there too (although chances are, if it is there, it will be found in the path as well).

3.
Of course there are the "usual" install locations:

  • 'C:\Program Files\Java\jre*\bin'
  • 'C:\Program Files\Java\jdk*\bin'
  • 'C:\Program Files (x86)\Java\jre*\bin'
  • 'C:\Program Files (x86)\Java\jdk*\bin'

[Note, that for older versions of Windows (XP, Vista(?)), this will only help on english versions of the OS. Fortunately, on later version of Windows "Program Files" will point to the directory regardless of its "display name" (which is language-specific).]

A little while back, I wrote this piece of code to check for javaw.exe in the aforementioned places. Maybe someone finds it useful:

static protected String findJavaw() {
    Path pathToJavaw = null;
    Path temp;

    /* Check in Registry: HKLM\Software\JavaSoft\Java Runtime Environement\<CurrentVersion>\JavaHome */
    String keyNode = "HKLM\\Software\\JavaSoft\\Java Runtime Environment";
    List<String> output = new ArrayList<>();
    executeCommand(new String[] {"REG", "QUERY", "\"" + keyNode + "\"", 
                                 "/v", "CurrentVersion"}, 
                   output);
    Pattern pattern = Pattern.compile("\\s*CurrentVersion\\s+\\S+\\s+(.*)$");
    for (String line : output) {
        Matcher matcher = pattern.matcher(line);
        if (matcher.find()) {
            keyNode += "\\" + matcher.group(1);
            List<String> output2 = new ArrayList<>();
            executeCommand(
                    new String[] {"REG", "QUERY", "\"" + keyNode + "\"", 
                                  "/v", "JavaHome"}, 
                    output2);
            Pattern pattern2 
                    = Pattern.compile("\\s*JavaHome\\s+\\S+\\s+(.*)$");
            for (String line2 : output2) {
                Matcher matcher2 = pattern2.matcher(line2);
                if (matcher2.find()) {
                    pathToJavaw = Paths.get(matcher2.group(1), "bin", 
                                            "javaw.exe");
                    break;
                }
            }
            break;
        }
    }
    try {
        if (Files.exists(pathToJavaw)) {
            return pathToJavaw.toString();
        }
    } catch (Exception ignored) {}

    /* Check in 'C:\Windows\System32' */
    pathToJavaw = Paths.get("C:\\Windows\\System32\\javaw.exe");
    try {
        if (Files.exists(pathToJavaw)) {
            return pathToJavaw.toString();
        }
    } catch (Exception ignored) {}

    /* Check in 'C:\Program Files\Java\jre*' */
    pathToJavaw = null;
    temp = Paths.get("C:\\Program Files\\Java");
    if (Files.exists(temp)) {
        try (DirectoryStream<Path> dirStream 
                = Files.newDirectoryStream(temp, "jre*")) {
            for (Path path : dirStream) {
                temp = Paths.get(path.toString(), "bin", "javaw.exe");
                if (Files.exists(temp)) {
                    pathToJavaw = temp;
                    // Don't "break", in order to find the latest JRE version
                }                    
            }
            if (pathToJavaw != null) {
                return pathToJavaw.toString();
            }
        } catch (Exception ignored) {}
    }

    /* Check in 'C:\Program Files (x86)\Java\jre*' */
    pathToJavaw = null;
    temp = Paths.get("C:\\Program Files (x86)\\Java");
    if (Files.exists(temp)) {
        try (DirectoryStream<Path> dirStream 
                = Files.newDirectoryStream(temp, "jre*")) {
            for (Path path : dirStream) {
                temp = Paths.get(path.toString(), "bin", "javaw.exe");
                if (Files.exists(temp)) {
                    pathToJavaw = temp;
                    // Don't "break", in order to find the latest JRE version
                }                    
            }
            if (pathToJavaw != null) {
                return pathToJavaw.toString();
            }
        } catch (Exception ignored) {}
    }

    /* Check in 'C:\Program Files\Java\jdk*' */
    pathToJavaw = null;
    temp = Paths.get("C:\\Program Files\\Java");
    if (Files.exists(temp)) {
        try (DirectoryStream<Path> dirStream 
                = Files.newDirectoryStream(temp, "jdk*")) {
            for (Path path : dirStream) {
                temp = Paths.get(path.toString(), "jre", "bin", "javaw.exe");
                if (Files.exists(temp)) {
                    pathToJavaw = temp;
                    // Don't "break", in order to find the latest JDK version
                }                    
            }
            if (pathToJavaw != null) {
                return pathToJavaw.toString();
            }
        } catch (Exception ignored) {}
    }

    /* Check in 'C:\Program Files (x86)\Java\jdk*' */
    pathToJavaw = null;
    temp = Paths.get("C:\\Program Files (x86)\\Java");
    if (Files.exists(temp)) {
        try (DirectoryStream<Path> dirStream 
                = Files.newDirectoryStream(temp, "jdk*")) {
            for (Path path : dirStream) {
                temp = Paths.get(path.toString(), "jre", "bin", "javaw.exe");
                if (Files.exists(temp)) {
                    pathToJavaw = temp;
                    // Don't "break", in order to find the latest JDK version
                }                    
            }
            if (pathToJavaw != null) {
                return pathToJavaw.toString();
            }
        } catch (Exception ignored) {}
    }

    return "javaw.exe";   // Let's just hope it is in the path :)
}
gkalpak
  • 47,844
  • 8
  • 105
  • 118
  • I suck at RegEx so I was looking for an easy way out. I thouhght Reimus' answer would be an easy way out by using `ProcessBuilder` – An SO User Jul 12 '13 at 09:57
  • @LittleChild : Like I said, my suggestion is an alternative (for when the Path search fails) - the PATH might be set-up correctly in your PC, but this might not be the case for some of your users. – gkalpak Jul 12 '13 at 10:20
  • Liek Reimus said, if the user has JRE installed, the path thing wont fail. If he does nto have JRE installed, well any java program wont run :p – An SO User Jul 12 '13 at 10:44
  • Reimus didn't say what you said he said. He described what should happen (with latest versions) - and it is what normaly does happen. But you can't rely on the default or expected behaviour, because it might fail you :) Also, note that if you are checking from a Java app, then your Java app is running, which means Java is indeed installed. So, if you are so sure that once installed it adds itself to the path, you can as well use "javaw.exe" (you don't need to find the exact path to the executable, since Windows will look in the PATH and find it for you :) – gkalpak Jul 12 '13 at 10:57
  • With JRE 1.8.0_111, the PATH contains `c:\ProgramData\Oracle\Java\javapath`, which contains .symlink pointers for java.exe, javaw.exe and javaws.exe, all with absolute paths to the real files in `Program Files\Java\jre1.8.0_111\bin` – stevek_mcc Nov 02 '16 at 17:34
5

Try this

for %i in (javaw.exe) do @echo. %~$PATH:i
Reimeus
  • 158,255
  • 15
  • 216
  • 276
3

To find "javaw.exe" in windows I would use (using batch)

for /f tokens^=2^ delims^=^" %%i in ('reg query HKEY_CLASSES_ROOT\jarfile\shell\open\command /ve') do set JAVAW_PATH=%%i

It should work in Windows XP and Seven, for JRE 1.6 and 1.7. Should catch the latest installed version.

Federico Destefanis
  • 968
  • 1
  • 16
  • 27
2

It worked to me:

    String javaHome = System.getProperty("java.home");
    File f = new File(javaHome);
    f = new File(f, "bin");
    f = new File(f, "javaw.exe"); //or f = new File(f, "javaws.exe"); //work too
    System.out.println(f + "    exists: " + f.exists());
Lini
  • 141
  • 2
  • 4
-1

Open a cmd shell,

cd \\
dir javaw.exe /s
Sᴀᴍ Onᴇᴌᴀ
  • 8,218
  • 8
  • 36
  • 58
David
  • 31
  • 2