The World of Java — How Java CLASSPATH and JVM Arguments work
Java is not capable of loading two different classes with the same class name. The JVM will load only one class due to the ClassLoader uses a unique class name.
There are two questions that need answers. First, if you give two different classes with the same class name which one will be executed by java? i.e. If you have an Application class in a.java and an Application class in b.java which class would be considered by JVM to execute? Second, if you give the same JVM argument (passing parameter value) E.g.: Heap size, into two different places which one will be executed?
Java CLASSPATH
This will be explained through a practical example.
- Create a new folder called “java” anywhere you prefer, I will be having the folder on the desktop.
- Inside the java folder create two folders as “a” and “b”.
- Inside each folder “a” and “b”, create a java file as “Application.java”. Then open your text-editor or IDE and create a class called Application that outputs “This is from A directory class” inside “a” folder and similarly create a class called Application that outputs “This is from B directory class” inside “b” folder.
Navigate to the “a” directory and open the terminal/cmd. Then compile and run the java program, you will see the Application.class gets created and finally the output as “This is from A directory class”.
To compile:
javac Application.java
To list the files in the directory:
Windows: dirLinux/Mac: ls
To execute:
java Application
Now we create a .jar file so that we can execute this .jar file after adding it to the classpath
To create .jar file:
jar -cvf Application.jar Application.class
Repeat the same steps for the Application.java file in “b” directory. While inside the “b” folder we set the CLASSPATH by first setting the path to Application.jar in “a” directory and then setting for Application.jar in “b” directory. Then navigate to the home directory so that you are not in “b” directory. To export CLASSPATH in:
Windows:
set CLASSPATH=C:\Users\YOURUSERNAME\Desktop\java\a\Application.jar;C:\Users\YOURUSERNAME\Desktop\java\b\Application.jar
Linux:
export CLASSPATH=/Desktop/java/a/Application.jar:/Desktop/java/b/Application.jar
Mac:
export CLASSPATH=${CLASSPATH}:~/Desktop/java/a/Application.jar:~/Desktop/java/b/Application.jar
Now change the first path to /Dekstop/java/b/Application.jar and the second path to /Desktop/java/a/Application.jar and export the CLASSPATH. If you run the application again, you will still see the output “This is from A Directory class”.
This is due to the JVM taking the first classpath .jar file to load even though they are different classes having the same name. But in theory, this is true, if we output the CLASSPATH, the path will be the same as shown in the above diagram and the modified CLASSPATH will have the Application.jar file in “b” directory first then the Application.jar file in the “a” directory second.
To correct this there are two ways,
- Setting the CLASSPATH empty and setting the path again in reverse order.
- Or by using a new terminal/cmd window.
JVM Arguments
Let's modify our Application.java inside “a” directory. Create a for loop where i=0 and i<10 and set i=1 so that it is an infinite loop.
When you compile and run the program it will not terminate because of the loop.
To obtain the process id by setting the Heap size as 512mb and 1024mb(1gb) and check which will JVM prefer.
Note: Commands in Windows, Linux, and Mac are different.
Since this is executed on Windows, To refer to the process id (PID) of the running java program, open Task Manager, and go to the Details tab. Scroll down to find the java.exe process and note down the PID of that.
In my case the PID is 12596, now open a new terminal/cmd and type jinfo PID
jinfo 12596
jinfo tool will return information about the process.
The maximum heap size can be seen as -XX:MaxHeapSize=1073741824, which is 1gb.
Now swap the heap sizes as 1024mb(1gb)then 512mb and re-run the program repeat the steps to find the PID and check the heap size it's using.
You can observe the maximum heap size can be seen as — XX:MaxHeapSize=536870912, which is 512mb.
It is clear that the CLASSPATH and Arguments are handled differently in JVM. Similar class names are added to the CLASSPATH, the JVM will consider the first path to execute. Passing arguments in JVM will always consider the last argument provided.
References
The YouTube playlist created by Krishantha Dinesh helped me in completing this article.