what is primordial class loader? How it is used in Java? - java

I was studying the Java architecture and in between, I found a concept of class loader and it was also referenced as a primordial class loader. I want to know that what is the function of this class loader, why we use this? I also want to know that what was the basic need so that we are using this.

In Java every class has to be loaded by some class loader.
How is the first class loaded? It has to be loaded through some class loader (which is just another class), so without some special code this would lead to infinity recursion.
The class loader that loads the first classes (java.lang.Object, java.lang.Class, java.lang.String, java.lang.ClassLoader and others) can therefore not be a 'normal' class loader.
It is this class loader that is referenced as the primordial class loader (primordial: from latin, meaning "the first", "the origin(al)")
For further study see the Java Security Aritecture and Securing Java

Primordial class loader the first class loader responsible to load class loader like "BootStrap class loader" which is part of JVM and written in native language.

Related

How can Serializable.class not be assignable from Class.class?

In org.springframework.core.SerializableTypeWrapper (version 5.2.3), there is the following code at line 112:
if (GraalDetector.inImageCode() || !Serializable.class.isAssignableFrom(Class.class)) {
// Let's skip any wrapping attempts if types are generally not serializable in
// the current runtime environment (even java.lang.Class itself, e.g. on Graal)
return providedType;
}
I'm curious about the second check (!Serializable.class.isAssignableFrom(Class.class)): is it possible for it to evaluate to true (that is, for Serialazable.class to be not assignable from Class.class)?
Here is what Class#isAssignableFrom() javadoc says:
Determines if the class or interface represented by this Class object is either the same as, or is a superclass or superinterface of, the class or interface represented by the specified Class parameter.
Looking at the code of Class, I see the following:
public final class Class<T> implements java.io.Serializable
So Serializable is a superinterface of Class and should always be assignable from Class. But the check in the Spring code suggests that sometimes it's not.
How come? In what situations can this happen and why don't they violate the Java Language Specification?
A custom class loader is a possible (if unlikely) mechanism for the expression to return false. Custom class loaders can do some crazy things, including loading their own versions of standard Java classes. Some things to know about class loaders:
Custom class loaders can be configured to load any class, even including Java standard library classes (it's discouraged of course, but still possible)
Custom class loaders will typically be configured to delegate to the system class loader for classes that they don't know how to load.
When class A has a reference to class B, the reference will be resolved using whichever class loader was used to load class A
More than one class loader can be configured to handle the same class, which can lead to multiple versions of a class getting loaded into the JVM, with the actual implementation you get depending on which class loader you ask
Suppose there is a custom class loader that, for whatever reason, is configured to load java.io.Serializable by itself, but delegates to the system class loader for loading other classes, including java.lang.Class.
Now suppose this custom class loader is used to load SerializableTypeWrapper. This means it will also be used to resolve the reference to java.io.Serializable in SerializableTypeWrapper. With the reference to java.lang.Class, the custom class loader will delegate this to the system class loader. The system class loader will be used to load java.lang.Class, but it will also be used to load the reference to java.io.Serializable from within java.lang.Class.
So now we can ask the question - is java.io.Serializable [custom] assignable from java.lang.Class [standard]? And the answer is no - java.lang.Class does implement java.io.Serializable [standard], but it does not implement java.io.Serializable [custom].

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?
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.
A somewhat roundabout way to load classes via the bootstrap class loader is to define your own class loader like so:
ClassLoader bootClassLoader = new ClassLoader(null){};
This class loader has no parent and thus the only place it will load classes from is the inherent bootstrap class loader.

How to load a modified superclass in Java?

I have a class A extends B.
I've created a CustomClassLoader extends ClassLoader to use defineClass(className, byte[], offset, length).
I've instanciate a new CustomClassLoader(Thread.currentThread().getContextClassLoader()).
So the parent of my CustomClassLoader is the ClassLoader from the current thread.
I've modified B class using ASM framework. I've write my modified class in a .class file and use a decompiler to be sure it works. And it works.
I've added modified B class to my CustomClassLoader
I've set the Thread.currentThread().setContextClassLoader() with my CustomClassLoader.
I've load A using Class.forName(String, true, the CustomClassLoader).
But the loaded B class seems to be the orginal class.
What did I wrong ?
If you need more info, a detailed topic is on my GitHub.
Java classloaders first search the parent classloader before looking in the child.
The loadClass method in ClassLoader performs these tasks, in order,
when called to load a class:
If a class has already been loaded, it returns it.
Otherwise, it delegates the search for the new class to the parent class loader.
If the parent class loader does not find the class, loadClass calls the method findClass to find and load the class.
(Understanding Extension Class Loading - Oracle)
If you want to change that order, you need to override the loadClass method as well but there are many caveats and it's not advisable unless you understand classloading very well.
The easier option is to make sure that the parent class loader cannot find the original class B.
There are several things to know:
For most things, dealing with the thread’s context class loader is obsolete, as it has no impact. It’s more like a convention; setting it has an impact if there’s some other code querying and using it. For the standard class loading process, it doesn’t have any meaning. It’s unfortunate that the documentation doesn’t mention that and make it look like a relevant thing. Perhaps, it was intended to have more meaning when it was added.
As pointed out by Erwin Bolwidt, when loading A via your custom loader, it will delegate to its parent loader, returning a class A loaded by the parent.
When resolving class references, the JVM will always use the defining loader of the referrer. So when the reference from A to B is resolved, the JVM will always use the parent loader which defined the class A
The last point implies that even if you modify your custom class loader to look up its own classes first instead of following the standard model of querying the parent first, it doesn’t solve the issue if it has no own A, as then, it still returns the parent’s A whose references will be resolved using the parent. Since you are invoking defineClass before asking for A, the lookup order doesn’t matter at all, as your custom loader has an already defined B that it returned if anyone ever asked it for B…
So you could let your custom loader also load and define A. Or you use Reflection with access override to defineClass on the system ClassLoader before it loads B. The cleanest solution is to implement the class modification logic as a Java Agent which can use the Instrumentation API to intercept and change the definition of B right at its loading time.

Using a custom class loader to load Java runtime and API classes

Why is it advisable to load the Java Runtime classes and API classes using the default system class loader in Java? What happens if we load them using our custom class loader?
One of the criterias for instanceof to be true, is that the two classes must be loaded by the same classloader. This goes for class casting too.
This would mean that instances of e.g. String created by your class loader would not be compatible with the String created by the system class loader. Are not instances of and cannot be cast to.
You probably do not want that.

Classpath of classes compiled with Javassist

As the title suggests, what is the classpath of classes compiled with Javassist?
My scenario is: Class A is compiled with Javassist. Class B is compiled with Java Compiler API and references Class A. The problem is that Class A is not visible to Class B...
Any ideas?
The "classpath" of class B does not depends on how the class is compiled (e.g. the class file is created), but how the class is loaded.
Java uses the class loader of a class to look up also all classes which are referenced by this class.
Each class loader can have a parent class loader, and normally loader.loadClass first asks its parent class loader about any classes, and in case of failure tries to load the class itself.
Thus, simply make sure the A class is visible to the class loader of class B, meaning that the class loader of A must be a parent (or parent of parent, or ...) of the class loader of class B.

Categories