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.





Sunday, May 5, 2013

Elected as Apache Axis2 Committer and PMC

It has been a long time, when i started to contribute to Apache Axis2 . As my first contribution to Apache Axis2, I have implemented Axis2 JDK 5 Enum support,. Here is my blog post which explain how to consume that feature. From that onwards I continued my contribution for Apache Axis2 as not only in the Axis2 core , I also contributed to Apache Sandesha2 which is an Axis2 module that provides reliable messaging capability.

I did my GSOC 2012 with Apache Axis2 in improving the JSON support of Apahce Axis2. As an outcome of this my mentor Amila Suriaarachchi  and myself could able to introduce a new approach to convert native a JSON message to XML bidirectional transformation mechanism without any data loss, and it supports namespace too.

Considering the contribution i have done so far in both coding and user mailing list, I have been elected to be an Apache Axis2 Committer and PMC. This is a great achievement for me and I am very much happy about it.


Wednesday, March 20, 2013

Fix machine hostname return null as it value

If your getting null value as your host name, check that both /etc/hosts and /etc/hostname files has the same name to the host, If not put the same name to both file as hostname, Here[1] you can find how to do that.

How to change machine name in Ubuntu 12.04 LTS

Go to the terminal
Type "sudo su" , because you need log into root mode to modify following files.
Now type "gedit /etc/hostname"
Replace new name with old name
Save and close the file

Now type "gedit /etc/hosts"
Replace your new name with old name
    eg : 127.0.1.1 <old name>    -->   127.0.1.1 <new name>
Save and close the file

Now you need to restart the machine, type "reboot" in terminal to restart via terminal.
Now you have successfully changed machine name. 

Monday, February 18, 2013

Install jar to local repo which are not available in maven repository

If you find a jar which is not in any maven repository. But you need it to build you maven project you can first install that jar to you local repo using mvn install:install-file .

e.g: java-gmail-imap.1.4.4-gm-ext-0.6.jar is not in any maven repository therefore i need to install it on my local repository, run following command in terminal

mvn install:install-file -Dfile=/path/to/java-gmail-imap.1.4.4-gm-ext-0.6.jar -DgroupId=com.google.code -DartifactId=java-gmail-imap -Dversion=1.4.4-gm-ext-0.6 -Dpackaging=jar

you will see

[INFO] --- maven-install-plugin:2.3.1:install-file (default-cli) @ org.example --- [INFO] Installing /path/to/java-gmail-imap-1.4.4-gm-ext-0.5.jar to /home/user/.m2/repository/com/google/code/java-gmail-imap/1.4.4-gm-ext-0.6/java-gmail-imap-1.4.4-gm-ext-0.6.jar [INFO] Installing /tmp/mvninstall4760815746928565678.pom to /home/user/.m2/repository/com/google/code/java-gmail-imap/1.4.4-gm-ext-0.6/java-gmail-imap-1.4.4-gm-ext-0.6.pom [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------

Now my java-gmail-imap.1.4.4-gm-ext-0.6.jar is in my local repo, and will add this as a dependency to my project

<dependency>
<groupId>com.google.code</groupId> <artifactId>java-gmail-imap</artifactId> <version>1.4.4-gm-ext-0.6</version>
</dependency>


that's all now you can build your project :)


Friday, September 28, 2012

Maven doesn't run all tests but print build success message and quit

When i am writing an end-to-end test to Apache Axis2 JSON support(End-to-end means it up a Axis2 server and deploy a service which is created on a fly, on it and test with that service and stop Axis2 server end of tests). Here i faced a problem that when i run the test using maven(mvn test) it runs isolation test(test particular functions of a class) upto my end-to-end test. it print build success message in terminal console and quit.

OOPs what happened to other isolation tests :( . then i debug the code and see are there any test failure in my end-to-end test but, believe me end-to-end test pass all tests and successfully execute @After method which is tearDown() method too. After that it return build success message and quit. How i can find a error when it says build success :) . Finally i found the solution for that. solution is add <forkMode>pertest</forkMode> to the suirefire maven test plugin. Then every things ok , it runs all test including above end-to-end.

Sample Text

Website counter

Categories