Dynamic Class Loading Example
In this example we shall show you Java Dynamic Class Loading, Dynamic Java Class loading is an important mechanism which provides the Java platform with the ability to install software components at run-time where you can load your classes in a lazy loading manner which means that classes are loaded on demand and at the last moment possible.
Dynamic Java Class loading is mainly using the Java Reflection
. Java Reflection
provides ability to examine or modify the runtime behavior of applications running in the JVM. Also, it is used to determine methods and attributes that will be used in a certain class at runtime.
So, If you target a Plug-in Architectures which offer flexibility for both the programmer and the user where extra functionality can be added to a program without the program having to be changed. Java Dynamic Java Class loading with Java Reflection
are the mechanisms to achieve this approach.
1. ClassLoader:
A class loader is an object that is responsible for loading classes. The class ClassLoader
is an abstract class. a class loader generates the data which constitutes a definition for the class using a class binary name which is constituted of package name and class name like java.lang.String
. Every Class object contains a reference to the ClassLoader
which defined it.
2. ClassLoader working mechanism:
The ClassLoader
class mechanism works based on a delegation model to search for classes and resources. Each instance of ClassLoader
has an associated parent class loader. When requested to find a class or resource, the below steps are followed:
- A
ClassLoader
instance checks if the class was already loaded. - If not loaded, it delegate the search for the class or resource to its parent class loader before attempting to find the class or resource itself.
- If parent class loader cannot load class, it attempt to load the class or resource by itself.
Tip
- The virtual machine’s built-in class loader, called the “bootstrap class loader”, does not itself have a parent but may serve as the parent of a
ClassLoader
instance. - We can create a new class loader using the specified parent class loader for delegation using
ClassLoader(ClassLoader parent)
constructor.
3. Dynamic Class Loading:
Applications implement subclasses of ClassLoader
in order to extend the manner in which the Java virtual machine dynamically loads classes.
When a class is loaded, all classes it references are loaded too. This class loading pattern happens recursively, until all classes needed are loaded. This may not be all classes in the application. Unreferenced classes are not loaded until the time they are referenced.
Tip
Normally, the Java virtual machine loads classes from the local file system in a platform-dependent manner.
However, some classes may originate from other sources, such as the network. Take a look on java.net.URLClassLoader Example and java.net.JarURLConnection Example.
4. Example:
Loading a class dynamically is easy. All you need to do is to obtain a ClassLoader
and call its loadClass()
method. Here is our example:
4.1. Create a simple class:
We create a class MyClass.java
to be loaded, contains sayHello()
method which print a statement Hello world from the loaded class !!!
on the console.
MyClass.java:
package com.jcg; /** * @author ashraf * */ public class MyClass { public void sayHello() { System.out.println("Hello world from the loaded class !!!"); } }
4.2. Create a custom ClassLoader:
We implement a subclass JavaClassLoader.java
of ClassLoader
in order to extend the manner in which the JVM dynamically loads classes. Also, we create a method invokeClassMethod(String classBinName, String methodName)
which takes the class binary name as a first argument and the target method name to be invoked.
JavaClassLoader.java:
package com.jcg; import java.lang.reflect.Constructor; import java.lang.reflect.Method; /** * @author ashraf * */ public class JavaClassLoader extends ClassLoader { public void invokeClassMethod(String classBinName, String methodName){ try { // Create a new JavaClassLoader ClassLoader classLoader = this.getClass().getClassLoader(); // Load the target class using its binary name Class loadedMyClass = classLoader.loadClass(classBinName); System.out.println("Loaded class name: " + loadedMyClass.getName()); // Create a new instance from the loaded class Constructor constructor = loadedMyClass.getConstructor(); Object myClassObject = constructor.newInstance(); // Getting the target method from the loaded class and invoke it using its name Method method = loadedMyClass.getMethod(methodName); System.out.println("Invoked method name: " + method.getName()); method.invoke(myClassObject); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } }
4.3. Running the example:
We create ClassLoaderTest.java
where we create a new instance of JavaClassLoader.java
then we call invokeClassMethod(String classBinName, String methodName)
given the com.jcg.MyClass
as a binary class name and sayHello
as a method to be invoked.
ClassLoaderTest.java:
package com.jcg; /** * @author ashraf * */ public class ClassLoaderTest extends JavaClassLoader { public static void main(String[] args) { JavaClassLoader javaClassLoader = new JavaClassLoader(); javaClassLoader.invokeClassMethod("com.jcg.MyClass", "sayHello"); } }
Output:
We can see the loaded class name, the invoked method name and the result after invoking this method.
Loaded class name: com.jcg.MyClass Invoked method name: sayHello Hello world from the loaded class !!!
5. Download the Source Code of this example:
This was an example of Java Dynamic Class Loading.
You can download the full source code of this example here: DynamicClassLoadingExampleCode.zip
// Create a new JavaClassLoader
ClassLoader classLoader = this.getClass().getClassLoader();
Thanks for this helpful article. I made use of it, and then came to a point where it was significant for me that I have a unique ClassLoader. I don’t think the above code creates anything. I think it just returns the existing ClassLoader for ‘this’, which I believe is a generally shared ClassLoader across all similarly scoped objects.
Thank you so much!