Hi,
I have been looking at several things that can be improved here.
* I am experiencing loading problems with both the exploded model and
archive model (.aar file).
The main problem here is that both my application and Axis distribute log4j.
Because of normal classloader delegation, my application usage of log4j causes
log4j classes to be loaded by the WebAppClassLoader, not the URLClassLoader
(classloader that loads my application). Then when log4j tries to create a
custom layout (part of my log4j extension), my custom layout class cannot be
found. I'm sure there may be other issues that could arise in the future as
well.
To get around this problem, I use the DeploymentClassLoader and extend it by
adding loadClass(). In this method I choose to find classes in my application
first, before delegating to the parent classloader (i.e., WebAppClassLoader).
It works nicely. We could make this a configurable Axis2 option (parent_first
or parent_last) for the DeploymentClassLoader. I think it is reasonable for
each web service to want to load its specific classes before delegating to the
WebAppClassLoader so I'd like to see the default behavior being parent_last.
Of course loading of certain classes should always delegate to the parent
(e.g., java.*, javax.*, org.apache.axis.*, etc...).
ArchiveFileData will need to be changed so that both exploded and archive model
use the DeploymentClassLoader in order to take advantage of this classloading
feature.
Sample code (DeploymentClassLoader):
/**
* Override class loading policy to use "PARENT_LAST" scheme so
* that application classes are loaded first before delegating
* to the parent classloader.
*/
private boolean parent_first_delegation = false; // make configurable
attribute
private String[] class_delegation_filter = {
"java",
"javax",
"org.xml.sax",
"org.w3c.dom",
"org.apache.axis",
"org.apache.xerces",
"org.apache.xalan"
};
public Class loadClass(String name) throws ClassNotFoundException
{
return loadClass(name, false);
}
protected synchronized Class loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
// check previously loaded local class cache
Class c = (Class) loadedclass.get(name);
if (c != null) {
if (resolve)
resolveClass(c);
return c;
}
// determine delegation policy for this class
boolean parent_first_delegation = this.parent_first_delegation;
if (!parent_first_delegation) {
for (int i=0; i<class_delegation_filter.length; i++) {
String filter = class_delegation_filter[i];
if (name.startsWith(filter)) {
parent_first_delegation = true;
break;
}
}
}
if (!parent_first_delegation) {
// try to find the class locally
try {
c = findClass(name);
if (resolve)
resolveClass(c);
}
catch (ClassNotFoundException e) {
}
}
// unconditional delegation
c = super.loadClass(name, resolve);
return c;
}
* Archive model does not find resources embedded with jars (lib/*.jar)
within the .aar file.
This is the problem that I reported last week. I have looked into this problem
a little. It seems like an easy fix, but I do not think it's possible to
create a URL that represents a resource in a jar which itself is contained in a
jar. The only way that I know how to deal with this problem is to
automatically explode these jars during deployment. For instance,
/services
myWebservice.aar (file)
would get exploded as
/services
myWebservice.aar (file)
myWebservice.aar (directory)
/lib
*.jar - all jars contained in myWebservice.aar (/lib)
Then I could add myWebService.aar and its dependent jars (/lib/*.jar) to the
URL classloader classpath.
The URLClassloader loader could now take care of loading classes and resources
in .aar and its dependent jars. The DeploymentClassLoader could be dumbed down
a little and not have to worry about these dependent jars anymore.
ArchiveFileData would need to be enhanced for this to happen.
What do you guys think about these issues?
Thanks.
Tony Dean
SAS Institute Inc.
919.531.6704
[EMAIL PROTECTED]
SAS... The Power to Know
http://www.sas.com