What Is Java_Home? How Does the Jvm Find the Javac Path Stored in Java_Home

What is JAVA_HOME? How does the JVM find the javac path stored in JAVA_HOME?

JVM does not find java.exe. It doesn't even call it. java.exe is called by the operating system (Windows in this case).

JAVA_HOME is just a convention, usually used by Tomcat, other Java EE app servers and build tools such as Gradle to find where Java lives.

The important thing from your point of view is that the Java /bin directory be on your PATH so Windows can find the .exe tools that ship with the JDK: javac.exe, java.exe, jar.exe, etc.

Difference between java.home and JAVA_HOME

As you stated, JAVA_HOME points to the JDK installation path given by the Environment Variable(%JAVA_HOME%).

But java.home points to the JRE installation path, now it returns the JRE that was used to run the application, please remember that you can have multiple versions of JRE and JDK on the same server/computer

And you can run an application specifying what jre or jdk you want to use.

So, for example, if you have on your Environment path:

%JAVA_HOME% = C:\Program Files\Java\jdk1.6.0_24

But if you ran the application using an specific jre:

"C:\Program Files (x86)\Java\jre1.8.0_73\bin\java" -jar TheJavaFile.jar

Inside the application on run-time, you will get on java.home a different version of the JAVA_HOME

This may explain why on some cases you get different versions for both variable and system property.

Also, please notice that the paths may be quite different, since JRE is a different product than JDK, then they are installed in different locations, because they are independent

Now, regarding what's the difference from one JDK vs JRE, this diagram explains it pretty clear:

Sample Image

JDK is a superset of JRE, and contains everything that is in JRE, plus
tools such as the compilers and debuggers necessary for developing
applets and applications. JRE provides the libraries, the Java Virtual
Machine (JVM), and other components to run applets and applications
written in the Java programming language.

How do I find where JDK is installed on my windows machine?

If you are using Linux/Unix/Mac OS X:

Try this:

$ which java

Should output the exact location.

After that, you can set JAVA_HOME environment variable yourself.

In my computer (Mac OS X - Snow Leopard):

$ which java
/usr/bin/java
$ ls -l /usr/bin/java
lrwxr-xr-x 1 root wheel 74 Nov 7 07:59 /usr/bin/java -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java

If you are using Windows:

c:\> for %i in (java.exe) do @echo.   %~$PATH:i

Should JAVA_HOME point to JDK or JRE?

If you're doing any sort of development, or building with Maven or Ant, you need to point to the JDK (Java Development Kit) where utilities such as javac (the Java Compiler) reside. Otherwise, you can point to the JRE (Java Runtime Environment).

The JDK contains everything the JRE has and more. If you're just executing Java programs, you can point to either the JRE or the JDK.

JAVA_HOME should point to a JDK not a JRE

Control Panel -> System and Security -> System -> Advanced system settings -> Advanced -> Environment Variables -> New System Variable

Sample Image

Finding JDK path and storing it as a string in Java

You may be able to find the JDK path by looking to see where javac is installed.
Assuming that "javac" is within the environment paths of the system then you can retrieve the path by passing "where javac" to code such as the following

public static String getCommandOutput(String command)  {
String output = null; //the string to return

Process process = null;
BufferedReader reader = null;
InputStreamReader streamReader = null;
InputStream stream = null;

try {
process = Runtime.getRuntime().exec(command);

//Get stream of the console running the command
stream = process.getInputStream();
streamReader = new InputStreamReader(stream);
reader = new BufferedReader(streamReader);

String currentLine = null; //store current line of output from the cmd
StringBuilder commandOutput = new StringBuilder(); //build up the output from cmd
while ((currentLine = reader.readLine()) != null) {
commandOutput.append(currentLine);
}

int returnCode = process.waitFor();
if (returnCode == 0) {
output = commandOutput.toString();
}

} catch (IOException e) {
System.err.println("Cannot retrieve output of command");
System.err.println(e);
output = null;
} catch (InterruptedException e) {
System.err.println("Cannot retrieve output of command");
System.err.println(e);
} finally {
//Close all inputs / readers

if (stream != null) {
try {
stream.close();
} catch (IOException e) {
System.err.println("Cannot close stream input! " + e);
}
}
if (streamReader != null) {
try {
streamReader.close();
} catch (IOException e) {
System.err.println("Cannot close stream input reader! " + e);
}
}
if (reader != null) {
try {
streamReader.close();
} catch (IOException e) {
System.err.println("Cannot close stream input reader! " + e);
}
}
}
//Return the output from the command - may be null if an error occured
return output;
}

The string returned will be the exact location of javac so you may need extra processing to get the directory that javac resides in. You will need to distinguish between Windows and other OS

public static void main(String[] args) {

//"where" on Windows and "whereis" on Linux/Mac
if (System.getProperty("os.name").contains("win") || System.getProperty("os.name").contains("Win")) {
String path = getCommandOutput("where javac");
if (path == null || path.isEmpty()) {
System.err.println("There may have been an error processing the command or ");
System.out.println("JAVAC may not set up to be used from the command line");
System.out.println("Unable to determine the location of the JDK using the command line");
} else {
//Response will be the path including "javac.exe" so need to
//Get the two directories above that
File javacFile = new File(path);
File jdkInstallationDir = javacFile.getParentFile().getParentFile();
System.out.println("jdk in use at command line is: " + jdkInstallationDir.getPath());
}//else: path can be found
} else {
String response = getCommandOutput("whereis javac");
if (response == null) {
System.err.println("There may have been an error processing the command or ");
System.out.println("JAVAC may not set up to be used from the command line");
System.out.println("Unable to determine the location of the JDK using the command line");
} else {
//The response will be "javac: /usr ... "
//so parse from the "/" - if no "/" then there was an error with the command
int pathStartIndex = response.indexOf('/');
if (pathStartIndex == -1) {
System.err.println("There may have been an error processing the command or ");
System.out.println("JAVAC may not set up to be used from the command line");
System.out.println("Unable to determine the location of the JDK using the command line");
} else {
//Else get the directory that is two above the javac.exe file
String path = response.substring(pathStartIndex, response.length());
File javacFile = new File(path);
File jdkInstallationDir = javacFile.getParentFile().getParentFile();
System.out.println("jdk in use at command line is: " + jdkInstallationDir.getPath());
}//else: path found
}//else: response wasn't null
}//else: OS is not windows
}//end main method

Note: if the method returns null / error it doesn't mean that javac doesn't exist - it will most likely be that javac isn't within the PATH environment variable on windows and so cannot be found using this method. This isn't likely on Unix as Unix usually adds the jdk/bin directory to the PATH automatically.
Also, this will return the javac version currently in use at command line, not necessarily the latest version installed. so if e.g. 7u12 and 7u13 are installed but command prompt is set to use 7u12 then that's the path that will be returned.

Only tested on multiple Windows machines but works fine on them.

Hope this is helpful.



Related Topics



Leave a reply



Submit