Wednesday, May 20, 2009

Axis2 child first class loading

With axis2 it is possible to deploy services as service archive files and modules as module archive files. Both these two types of archives can contain .class or .jar files within it. Axis2 creates a separate class loader to load these class and jar files within the archive file.
By default Axis2 uses parent first class loading. This means jvm search for a particular class in parent before search it at the current class loader. As a result of this user could not use a different version of a jar file within their archives.
I recently added the child first class loading support (this is only available with main trunk) so that users can use different versions of class files at their services.

How to enable it?
This can be globally enable by setting the 'EnableChildFirstClassLoading' parameter to true at the axis2.xml file. Further the behavior of the services or modules can be set adding the same parameter to services.xml and module.xml.

How it works?
Axis2 uses a custom class loader called DeploymentClassLoader which is extended from the java URLClassloader. URLClassloader uses a parent first approach. LoadClass method of the java classloader class looks like this,

protected synchronized Class loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
// First, check if the class has already been loaded
Class c = findLoadedClass(name);
if (c == null) {
try {
if (parent != null) {
c = parent.loadClass(name, false);
} else {
c = findBootstrapClass0(name);
}
} catch (ClassNotFoundException e) {
// If still not found, then invoke findClass in order
// to find the class.
c = findClass(name);
}
}
if (resolve) {
resolveClass(c);
}
return c;
}

it first checks the parent class loader to check the class and child class loader after that. We can revise this order simply overriding this method at the DeploymentClassLoader like this,
protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
Class c = null;
if (!isChildFirstClassLoading) {
c = super.loadClass(name, resolve);
} else {
c = findLoadedClass(name);
if (c == null) {
try {
c = findClass(name);
} catch (Exception e) {
c = super.loadClass(name, resolve);
}
}
}
return c;
}

Here the isChildFirstClassLoading is set according to the parameters uses set above.

3 comments:

Anonymous said...

Which Axis2 Version contains this Configurationparameter?

jhonathan said...



Thank you for the info. It sounds pretty user friendly. I guess I’ll pick one up for fun. thank u.


Mobile Application Development and Testing Training

Vishal said...

HI , we are using axis2 1.5.1 implementation for webservices .Currently we are facing issue when concurrent number of requests are increased between two products communicating using webservice. We have already implemented this solution i.e.

ConfigurationContext context = this._webService._getServiceClient().getServiceContext().getConfigurationContext();
MultiThreadedHttpConnectionManager multiThreadedHttpConnectionManager = new MultiThreadedHttpConnectionManager();
HttpConnectionManagerParams params = new HttpConnectionManagerParams();
params.setDefaultMaxConnectionsPerHost(50);
multiThreadedHttpConnectionManager.setParams(params);
HttpClient httpClient = new HttpClient(multiThreadedHttpConnectionManager);
context.setProperty(HTTPConstants.REUSE_HTTP_CLIENT, true);
context.setProperty(HTTPConstants.CACHED_HTTP_CLIENT, httpClient);


What is If increase setDefaultMaxConnectionsPerHost to 100 ? will it solve the problem ? Or is there any other way ?