Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to load another class via bootstrap classloader programmatically?

I know there is a "bootstrap classloader" loading all the classes from the jre/lib (rt.jar, etc). Is it possible to get my hands on this "bootstrap classloader" in order to load an additional class from another non-java package?

I'm talking about the bootstrap classpath, which is very different than the regular classpath described on this answer: How should I load Jars dynamically at runtime?

like image 357
LatencyFighter Avatar asked Jan 28 '23 17:01

LatencyFighter


1 Answers

The bootstrap class loader is represented as null, e.g. when calling Class.getClassLoader(). This can be fed directly to Class.forName(String,boolean,ClassLoader):

If the parameter loader is null, the class is loaded through the bootstrap class loader.

So, you can try to load a class explicitly through the bootstrap loader using Class.forName(className,true,null) or resolve a class relative to another class’ context using Class.forName(className,true,context.getClassLoader()) without having to special-case the bootstrap loader.


If you want to define a runtime class as-if being loaded by the bootstrap loader, there is no standard solution. There is the method sun.misc.Unsafe.defineClass(String, byte, int, int, ClassLoader, ProtectionDomain) that allows to define a class within a particular class loader, which is a proprietary API that is likely to disappear in the future.

Starting with Java 9, there is java.lang.invoke.MethodHandles.Lookup.defineClass(byte[]), a standard method define a class within another class’ context, but it requires non-standard ways, e.g. Reflection with access override to get a Lookup object with the appropriate access right to a bootstrap loaded class, e.g. java.lang.Object. There are already existing Q&A about creating such a Lookup object for other purposes, e.g. this one. Such Reflection hacks are not guaranteed to work in future versions though.

For a Java Agent, there’s also the option to dump the class file(s) into a temporary Jar file and add it to the bootstrap class path programmatically, if it doesn’t mind that this involves I/O.

There is another catch to be aware of. When you want other bootstrap loaded classes to find your class, you have to add it before the first attempt to access that class, as the JVM’s resolver will remember the result, even if it is to fail with an error.

like image 88
Holger Avatar answered Feb 06 '23 14:02

Holger