Enhancing Java's Core: Modifying/Adding Bootstrap Classes via Xbootclasspath and patch-module

Enhancing Java's Core: Modifying/Adding Bootstrap Classes via Xbootclasspath and patch-module

ยท

3 min read

You can actually write the following code without the compiler going crazy!

import java.util.VeejayTreeMap;

The arguments that you pass to the JVM have significant meaning. You can literally add your own classes as part of the core java library and run it in your Java application.

Let's understand JVM further by understanding how it finds classes, compiles them and how we can modify it to our advantage. I didn't realize just how significant those Java flags can be until recently when I had to add classes to java.net package to monitor the network at the protocol layer.

Manipulating this can also enable you to override JDK classes! We will explore how to achieve this.

Note: You can find all the references for this blog at the end for further knowledge.

How the JVM finds classes

The java command initiates the JVM and it starts to look for three classes in the following order:

  • Bootstrap classes - Classes that comprise the Java platform (such as the rt.jar as of Java 8 which was split into modules on and after Java 9). We are going to manipulate this. The path to such core class files is obtained by Java by default. It can be overridden using the below-mentioned flags.

  • Extension classes - Classes that use the Java Extension mechanism. These are bundled as .jar files located in the extensions directory (usually under $JAVA_HOME/lib/ext)

  • User classes - These are the classes that we want to run. Identified by using the -classpath option on the command line or the CLASSPATH environment variable

Simple enough. Where does this leave us? To achieve our goal, all we have to do is add our jar file to the bootstrap class path. This is where -Xbootclasspath (for Java 8) or --patch-module (for Java 11) comes in.

Manipulating JVM to our advantage

Adding our jar file to the -Xbootclasspath/a flag informs the JVM to append our jar files to the bootstrap classes. There is another flag -Xbootclasspath/p which prepends whatever jar files path we give it. That's the sauce. Add these flags and add/modify fundamental classes of Java to your heart's extent.

But wait, won't the classes with the same names conflict during runtime? How can there be more than one java.util.Map ?

Java overcomes this problem using a very simple solution. It searches the classpath list and returns the class that it first finds. So, when you prepend and override the core Java class, the JVM will return the first class (which you overrode) during runtime.

There is no -Xbootclasspath/p in Java 11. This is because Java 9 introduced the concept of modules which has provided stronger encapsulation and separation of concern. You can read more about the move to modules in the references below. Instead, in 11, you can use the --patch-module flag and mention the path of your classes to achieve the same effect.

Remember

These classes are not loaded with the stringent checks that the JVM uses for the user-defined classes. Hence, it is always better to use these classes with caution and understanding.

Let me know your thoughts on this!

Until next time ๐Ÿ‘‹ :)

References

ย