Sunday, January 13, 2008

MyClassLoader - Java ClassLoader Final Part

Sorry as I am not able to proceed sequentially. But now its time for implementation. I have 3 java files with me:

1. myClassLoader.java which inherits from ClassLoader and implements the minimum requirement.

2. myClassLoaderMain.java which loads the class HelloWorld, making its instance and calling one of the method of it.

3. HelloWorld.java which is simply a program with one method.

myClassLoader is not doing any of the special job but at the end I am providing you the link of some more documents which can provide you special classLoader like one good article is showing you how to load class change on fly.

myClassLoader.java

import java.io.*;
import java.util.*;
public class myClassLoader extends ClassLoader {
private Hashtable classes = new Hashtable();
public myClassLoader(){
super(myClassLoader.class.getClassLoader());
}
public Class loadClass(String className) throws ClassNotFoundException {
return findClass(className);
}

public Class findClass(String className){
Class result=null;
result = (Class)classes.get(className);
System.out.println("Class Name is : " + className);
if(result != null){
return result;
}
try{
return findSystemClass(className);
}catch(Exception e){
return null;
}
}
}

myClassLoaderMain.java

public class myClassLoaderMain {
public static void main(String [] args) throws Exception{
myClassLoader test = new myClassLoader();
Object o = (test.loadClass("HelloWorld")).newInstance();
((HelloWorld)o).mymethod();
}
}

HelloWorld.java

class HelloWorld {
public void mymethod()
{
System.out.println("Atleast print this ");
}
public static void main(String[] args)
{
System.out.println("Hello World");
}
}

Now running all together:

javac *.java
java myMainClassLoader
/* It will call mymethod of HelloWorld */

If you are keen to move further and want to make some magical class Loader please check this articles:
1. Basics of ClassLoader on JavaWorld.
2. A look at Java ClassLoader - Here they made an example of loading class at runtime.
3. Java ClassLoader wiki page.

Any comments or correction or questions are most welcome.

Inheritance and Memory Retention Issue with Finalization

Finalization is mostly used in Java to reclaim resources, native resources. Say, you are writing one program and you are using Windows Font(OS font). So, its the programmers duty to reclaim the font resource associated with any object.

If you are an application developer and uses lot of native resource then I would say stop reading this blog and read the latest Article(yes, Sep 2007) by Tony Printezis on sun site. This article is awesome and covers all the cases and its solution that can happen with Memory Retention. The simplest of that is what I am going to talk here.

Now, consider an example :

class PlayWithFont {

String someText;
String newText;

private native method getFont();
void get() { getFont(); }

// private because its a native method and always be called by any method of this class only
private native method releaseFont();
void release() { releaseFont(); }
protected void finalize() { release(); }

}

Now, here I have some text and I am taking OS font, converting that text into some fancy text and then releasing the resource of Operating Systems.
We have a class called PlayMoreWithFont which basically inherits PlayWithFont and converting some String[] text into new String[] text (just a fictitious example)

class PlayMoreWithFont {

String[] someMoreText ; // lets consider it here some big chucks of memory
String[] newMoreText;

}

PlayMoreWithFont don't have any finalize method defined, but off course its going to take one from PlayWithFont.

GC maintain a finalization queue. When a object is unreachable, object is added to the finalization queue. After that only object goes into finalized state. Now when we called :

play = new PlayMoreWithFont;
play = null;

Now instance of PlayMoreWithFont become unreachable, but reclamation of big chunks like someMoreText and newMoreText has to wait until the instance is finalized. And this is one of the major causes of memory retention. Moreover the problem is difficult to find if the class hierarchy is very deep and finalize is sitting some where very deep.

There are some good solution which we can discuss in next.

Wednesday, January 02, 2008

MyClassLoader - Java ClassLoader - Part 2

MyClassLoader will take one more entry for completion. Before writing our own custom ClassLoader, we have to devote sometime to see the methods of ClassLoader. Some of them need special attention while others we can ignore. Before starting with methods, we can see some type of ClassLoader available in jdk(openjdk) itself. AppletClassLoader, RMIClassLoader, SecureClassLoader, URLClassLoader are some of them. Remember all the custom ClassLoader need to extend ClassLoader except one :-). Any guesses ? Bootstrap Class Loader - Yes, this is responsible for loading runtime classes(rt.jar- very famous jar file in /jre/lib :-) ) . It has a native implementation and hence varies across JVM. So, when we write

java MyProgram

Bootstrap ClassLoader comes into the action first.

Alright, back to methods: we can see the whole list of methods of ClassLoader here. But we will see those of our interest:

- loadClass -> entry point for ClassLoader. In JDK 1.1 or earlier, this is the only method we need to override but after JDK 1.2 some dynamics get changed. Will discuss that later.

- defineClass -> As I mentioned in the last blog, this is one of the complex method which takes raw data and turn it into Class Object. Need not to worry, it is defined as final(so we can't change... who want to change).

- findSystemClass -> looks for the class file in local disk, if yes calls defineClass and convert the raw data into Class Object.

In JDK 1.2, new delegation model came into picture where if ClassLoader can't able to find a class, it asks (it's) parent ClassLoader to do it. JDK 1.2 came up with a new method called findClass which contains specialized code and help you when you are messed up with lot of ClassLoader. So, from JDK 1.2 and onwards, we just need to override findClass and everything will work fine, if not it will throw ClassNotFoundException. There are lot of other methods like getParent, getSystemClassLoader, but we can write our custom ClassLoader without touching these methods.

So, top skeleton looks like:

public class MyClassLoader extends ClassLoader {

public CustomClassLoader(){
//getClassLoader returns ClassLoader
super(CustomClassLoader.class.getClassLoader());
}

}

//lot of thing after this

Tuesday, January 01, 2008

MyClassLoader - Java ClassLoader

I am very new to Java and often terms like ClassLoader, Virtual Machine scares me before start. With little of courage I start reading some of the documents on ClassLoader and ahh I find it very simple. Actually with reply to some of my old blog's comment, we had made a statement that "you can have your own classLoader in java".

The good part about ClassLoader - its written in Java :-). So one can expect code to be simple and more understandable than written in C++.

ClassLoader is nothing but a part of Java Virtual Machine responsible to load classes into memory. From where ? From local hard drive(mostly), from network and in some cases from browser. Little complex yet beautiful part of it is it load classes on demand not all at once. Java has an excellent feature to write your own classLoader which extends to ClassLoader class. Here, I named it as MyClassLoader :-). But if JVM has a classLoader why to write another one ? In my case, just for fun :D but there are other uses. One I got, is to automatically verify digital signature before invoking untrusted code. Second and more important when you want to update class at runtime. So, in this case we need to create another instance of our classLoader and then we can replace the already loaded classes with new updated classes. We can see some other usages as we move on to the blog.

I start reading some code here and there of classLoader from openjdk. If you have openjdk on your system, I will better suggest to go through some of the API implementation of ClassLoader. You will get the ClassLoader.java at path \jdk\src\share\classes\java\lang\ClassLoader.java. I was surprised to see that very less changes has been made to this file after jdk 1.2 and a great enhancement is done on jdk 1.2. In the code, you can see most of the API's have written in 1.2 only.

When java got released the most exciting and eye catching feature is how it execute code on the fly from remote server. Some kind of magic ? Yes, this magic is possible because java has the ability to write a custom classloader. The magic is this - in appletviewer/browser instead of looking into local had disk for classes it looks for remote server, loads the raw data through http and turns them into classes(duty of method called defineClass in ClassLoader, we will see this in more detail) inside Virtual Machine.

I am still in the midway of many document, reading re-reading and trying to understand more of it. We will try to see some of the method(s) which we need to implement for our custom ClassLoader, MyClassLoader. Most of the methods sounds easy but some methods like defineClass which is actually converting raw data into classes may go little complex.