The World of Java — How Java CLASSPATH and JVM Arguments work

Nadin Pethiyagoda
5 min readJul 18, 2022

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.
Application Class for directory A
Application Class for directory B

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
Compile and run Application.java file inside A directory

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
Create Application.jar file

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
Setting CLASSPATH and running the Application

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,

  1. Setting the CLASSPATH empty and setting the path again in reverse order.
  2. 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.

Application class with infinite for loop

When you compile and run the program it will not terminate because of the loop.

Compile and run Application

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.

Running Application with allocated Heap sizes

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.

PID of java.exe from Task Manager

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.

jinfo tool heap size 1024mb

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.

jinfo tool heap size 512mb

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.

--

--