Tuesday, July 16, 2013

Java ClassLoader Example with URLClassLoader


Here i am going to explain how to use java URLClassLoader to load classes in runtime. First i will explain how to run the code without class loaders. Then i will explain how to run the same code using URLClassLoader.

Let's try to convert java object to JSON using google gson 3rd part library.

1. Without ClassLoaders

Main Class
package my.sample.classloading;

import com.google.gson.Gson;

public class Main {
public static void main(String[] args) {
Gson gson = new Gson();
String jsonString = gson.toJson(new Person());
System.out.println(jsonString);
 }
}

Person class
package my.sample.classloading;

public class Person {
private String name="Foo Bar";
private int age= 25;
} 

If you try to run this sample code without providing gson-<version>.jar  at runtime you will end up getting following exception.

Exception in thread "main" java.lang.NoClassDefFoundError: com/google/gson/Gson
    at my.sample.classloading.Main.main(Main.java:27)
Caused by: java.lang.ClassNotFoundException: com.google.gson.Gson
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:356) 
 
But if you add gson-<version>.jar to your classpath you will not get above exception instead you will get expected out put.

Let's see how we can handle this with class loading.

2. With ClassLoaders

Main Class
package org.wso2.carbon.classloading;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;

public class Main {
    public static void main(String[] args) throws ClassNotFoundException, MalformedURLException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {


        URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{new URL("file:///home/shameera/Desktop/gson-2.2.4.jar")});
        Class gsonClass = urlClassLoader.loadClass("com.google.gson.Gson");
        Constructor constructor = gsonClass.getConstructor();
        Object gsonObj = constructor.newInstance();
        Method method = gsonClass.getMethod("toJson",Object.class);
        Object returnObj =  method.invoke(gsonObj, new Person());
        String jsonString = (String)returnObj;
        System.out.println(jsonString);
    }
}

 With above sample it loads gson-2.2.4.jar file at runtime using Java URLClassLoader and convert a Person object to json string. As you can see there is no any import for Gson class instead we load and use it in runtime.

Install a JAR to local maven repository

When dependency jars are not available in maven central repository you have to install it to your local repository or you can provide it using system path. Using following command you can send your dependency jar to your local m2 repository.

mvn install:install-file -Dfile=<path/to/your/dependecy/jar> -DgroupId=<groupId> -DartifactId=<artifactId> -Dversion=<version> -Dpackaging=jar


Eg:Let's get google gson library as an example, This is already available in maven repository but here we are going to manually install it to our local m2 repo. Assume i have downloaded gson-2.2.4.jar to my desktop

         <dependency>
             <groupId>com.google.code.gson</groupId>
             <artifactId>gson</artifactId>
             <version>2.2.4</version>
         </dependency>

mvn install:install-file -Dfile=/home/shameera/Desktop/gson-2.2.4.jar -DgroupId=com.google.code.gson -DartifactId=gson -Dversion=2.2.4 -Dpackaging=jar

You will see similar output like below.

[INFO] Scanning for projects...
[INFO]                                                                        
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-install-plugin:2.3.1:install-file (default-cli) @ standalone-pom ---
[INFO] Installing /home/shameera/Desktop/gson-2.2.4.jar to /home/shameera/.m2/repository/com/google/code/gson/gson/2.2.4/gson-2.2.4.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------


As same as you can install your own jars to local maven repo and refer it in different project.





Sample Text

Website counter

Categories