Sunday, December 30, 2007

Delphi --- problem when using function RegisterClass

Delphi has a feature: serialize/deserialize object. It means you can save/load object at runtime.
To do this, your classes have to inherit from TPersistent and you have to register this class to system. To register a class you can you function: RegisterClass. After registering successfully, you can read or write object to the stream. But there are problems: you can not know if class is registered successfully till you call function: getclass or findclass, and you can not know why it is not succeeded. It takes me 1 day to find why it can not register. All i have to do is debug delphi system to find out the reason. And i want to share my experience when i face this problem. The reason is: the class belongs to a group. But this group is deactivated when delphi create group. So this class can not be registered. All we have to do in this case is activate group again by calling function activategroup(class belong to group). Hope i can help you to save time when solve this problem

HTML Parser -- A good html parser.

I have found many parser used in my projects. By asking google, we can find some parsers. But after try many parsers, i can tell you that HTMLPaser is the one should be considered.
Website: htmlparser.sourceforge.net
HTMLParser is a parser which can help you parser html file. It has 2 features which i like very much
1. Extracter: It can help us extract information from html file very easily with many filters.
All we have to do is call parser.parse(Filter). A filter can be an individual filter or it can be predicate which combine many filter(and , or , not, user-defined filter) to help you extract as much as possible information.
2. Visitor pattern: With visitor pattern you can do what you want with a tag when parser traverse to that tag. You can change the attribute of node, get information, ... whatever you want.
Besides, htmlparser is well-structured, so it can speed-up coding, maintain easily.

If you want to find a good html parser, why don't give it a try.
PS: You should try html parser version 2.0

Friday, December 28, 2007

Introduction to blogvertise

Today, i surf net and found an interesting website. You know i love to write blog, and share my experiences i met in my work. It is my hobby. But if i can earn money from those posts,it is really interesting. And Blogvertise is what i want to tell you. You can earn money from your blogs with your posts. The re quirement is simple. You get your email, follow their instruction to write a blog with some criteria. And wait for your money.

Hope it will help you about blogvertise.

Website: Blogvertise

Sunday, December 9, 2007

Java: How to load class dynamically (on fly)?

I face a problem of loading class dynamically in JAVA. How to do this?
After do research in internet with many site, i finally find out the way to do this.
In order to save your time on researching problem, i will show you how to do this.

To understand the framework, we have to know following knowledge:
1. Class loader and how does it work

So how does class loader work:



As shown in Figure 1, the bootstrap class loader (BS) -- Native implemented into JVM -- loads the classes from the JVM, as well as extensions to the JDK. The system class loader (CP) loads all of the classes provided by the CLASSPATH environment variable or passed using the -classpath argument to the java command. Finally we have several additional class loaders, where A1-3 are children of the CP, and B1-2 are children of A3. Every class loader (except BS) has a parent class loader, even if no parent is provided explicitly; in the latter case, the CP is automatically set as the parent.

Rule for class loader:

1. lass loaders are hierarchically organized, where each one has a parent class loader, except the bootstrap class loader (the root).

2. Class loaders should (practically: must) delegate the loading of a class to the parent, but a custom class loader can define for itself when it should do so.

3. A class is defined by its class type and the effective class loader.

4. A class is only loaded once and then cached in the class loader to ensure that the byte code cannot change.

5. Any symbolic links are loaded by the effective class loader (or one of its ancestors), if this is not already done. The JVM can defer this resolution until the class is actually used.

6. An upcast of an instance to another class fails when the class of the instance and the class of the symbolic link do not match (meaning their class loaders do not match).

But another problem is: Classes are loaded by many class loader. How can it distinguish them? JAVA do it by combine qualified name: (Class name, Package name, Class loader) --> With the same classes, but loaded by different class loader, it can not be used together. We can check it easily by using URLClassLoader and sun.misc.Launcher$AppClassLoader(class loader which load main function).

When i work with JAX-WS, i see that we can dynamically add custom handler to WS, and JAX-WS will call our handler. It make me think a lot. How can it do this?
The answer is: JAXWS has its own class loader. And the class loader will find and call our handler.

Now we will make a framework which can allow us load custom handler like JAX-WS at run time.

1. We define a interface for handler. This handler is packaged in jar file.
2. User will define class which implemented the interface handler. The implement class is packaged in other jar file.
3. Our framework will scan those jar file and load all custom handlers, and call it sequentially.

The most difficult part is load all custom handlers and call it at run time.
To solve the problem, we will make our own class loader:


public class CustomLoader extends URLClassLoader
{
static public ClassLoader MainClassLoader = null;

protected CustomLoader (URL[] urls, ClassLoader parent) {
super(urls, parent);
}

public Class loadClass(String name) throws ClassNotFoundException {
//Get system class loader
try {
if (MainClassLoader != null) {
return MainClassLoader.loadClass(name);
} else {
return super.loadClass(name);
}
} catch (ClassNotFoundException e) {
return super.loadClass(name);
}
}

protected Class findClass(String name) throws ClassNotFoundException {
Class clas = super.findClass(name);
return clas;
}
}


The variable MainClassLoader point to sun.misc.Launcher$AppClassLoader( the class loader which call our main function)

How to used this custom class loader?


void main() {
ClassLoader base = ClassLoader.getSystemClassLoader(); //get the boot trap class loader
CustomLoader loader = new CustomLoader(urls, base.getParent()); //create our class loader
loader.MainClassLoader = Thread.currentThread().getContextClassLoader(); //set the //application class loader to our class loader. We have to do this because when java //compile and link our code, it used class loader: sun.misc.Launcher$AppClassLoader.

Class handlerClass = loader.loadClass("CustomHandler");
Object handler = handlerClass.newInstance(); (1)
Handler customHandler = (Handler)handler; (2)
}


(1) --> implement class is loaded by our custom class loader.
(2) --> Handler is loaded by sun.misc.Launcher$AppClassLoader

Thank to this code:

public Class loadClass(String name) throws ClassNotFoundException {
//Get system class loader
try {
if (MainClassLoader != null) {
return MainClassLoader.loadClass(name);
} else {
return super.loadClass(name);
}
} catch (ClassNotFoundException e) {
return super.loadClass(name);
}
}

We delegate loading class to MainClassLoader first: because in linkage phase, MainClassLoader load all symbols in our source code. If we do not do this, we will violate the rule 6. If MainClassLoader does not load them, we will delegate to parent or we violate rule 2. If both do not load class, we can do it by ourselves. But in this case we do not implement this(for simple).

So with our custom class loader, (2) can be used without ClassCastException.

So i hope , you can make a framework easily with the custom class loader as i explain.

Google