There's 10 million articles and docs out there on what Java classloaders are, and how/*why* to write your own...but they all seem to be assuming some things that I can't find a simple answer to!
I understand the job of the classloader: to read bytecode and construct an object from it. Different classloaders do this differently, etc.
But having never had to code against a class loader API in my own code, and never having to write one of my own, I'm having enormous difficulty understanding when a ClassLoader
's own code actually fires.
For instance:
public static void main(String[] args) {
Fizz fizz = new Fizz();
fuzz.buzz();
}
Here, we have a Fizz
object. Before a Fizz
can be instantiated, we need a class loader to kick in and load Fizz.class
into its cache. Where and when is this happening?!?! It's not explicitly in my code so it must implicitly be somewhere in the JRE...?
Tangential to that question, if I write my own classloader, say, WidgetClassLoader
and want to configure it to load either all my application's classes, or perhaps just my Fizz.class
, how do I "tie" this WidgetClassLoader
into my application so that it knows which classloader to use? Would my code need to explicitly call this classloader or would it be implicit like the first example? Thanks in advance!
The Java ClassLoader is a part of the Java Runtime Environment that dynamically loads Java classes into the Java Virtual Machine. The Java run time system does not need to know about files and file systems because of classloaders. Java classes aren't loaded into memory all at once, but when required by an application.
A Java Class is stored in the form of byte code in a . class file after it is compiled. The ClassLoader loads the class of the Java program into memory when it is required. The ClassLoader is hierarchical and so if there is a request to load a class, it is delegated to the parent class loader.
The Java Virtual Machine starts up by creating an initial class or interface using the bootstrap class loader (§5.3. 1) or a user-defined class loader (§5.3. 2).
Each application might use different versions of the same libraries, and must thus have a different classloader from the others in order to be able to have different versions of the same classes in a single JVM. but the web server has its own loader.it can have several classloaders.
You question isn't as trivial as you think now.
Your Fizz example: When is Fizz loaded? This is defined in the JLS (Chapter 5.4: Linking). It does not define when Fizz is loaded, but it makes guarantees about the visible behavior. For the 'when' part, if Fizz can not be found, an Exception will be thrown from the first statement that accesses Fizz (Fizz fizz = new Fizz()). I'm pretty sure it will be the new Fizz() specifically in this case because the right side of the expression is evaulated first. In case you had written it like this:
Fizz fizz = null;
fizz = new Fizz();
In this case the Fizz fizz = null would already throw the Exception because its the first access to the Fizz class.
Who loads Fizz? When a class must be loaded, the classloader that 'belongs' to the code requiring the class is used to get the class. In the Fizz example this will be the classloader that loaded the class with the main method. Of course, the classloader may choose to delegate to its parent classloader if it can not load Fizz by itself.
How do I get the JVM to use my ClassLoader? There are two ways, explicitly or implicitly. Explicitly: you can load a class through your own classloader by calling its methods. Implcitly: when you execute code (meaning methods or initializers) from a class that was already loaded from your classloader and a class reference needs to be resolved in the process, your classloader will be automatically used because it is the classloader that loaded the code in the first place.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With