Loader.java in util package of kernel can not find the class in extremely
environment
-------------------------------------------------------------------------------------
Key: AXIS2-3157
URL: https://issues.apache.org/jira/browse/AXIS2-3157
Project: Axis 2.0 (Axis2)
Issue Type: Bug
Components: kernel
Affects Versions: 1.1.1
Environment: Develop a client of axis2 webservice as a component in a
specific software platform.
Reporter: scott
When I develop a client of web service, I get a error as belowing:
at
org.apache.axis2.engine.AxisConfiguration.engageModule(AxisConfiguration.java:356)
at org.apache.axis2.deployment.DeploymentEngine.engageModules
(DeploymentEngine.java:664)
at
org.apache.axis2.deployment.FileSystemConfigurator.engageGlobalModules(FileSystemConfigurator.java:124)
at
org.apache.axis2.context.ConfigurationContextFactory.createConfigurationContext(ConfigurationContextFactory.java:71)
at
org.apache.axis2.context.ConfigurationContextFactory.createConfigurationContextFromFileSystem(ConfigurationContextFactory.java:180)
I track the code and find the reason is the class is not loaded successfully,
and I found that the Loader.java class is not powerful to deal with some
extremely environment, so I change the approach of load class and it works.
The original code is belowing:
org.apache.axis2.util.Loader.java
/**
* Loads the specified classloader and then falls back to the loadClass.
*
* @param loader
* @param clazz
* @return Returns Class.
* @throws ClassNotFoundException
*/
static public Class loadClass(ClassLoader loader, String clazz) throws
ClassNotFoundException {
try {
if(loader != null) {
Class c = loader.loadClass(clazz);
if (c != null)
return c;
}
} catch (Throwable e) {
log.debug(e);
}
return loadClass(clazz);
}
/**
* If running under JDK 1.2, loads the specified class using the
* <code>Thread</code> <code>contextClassLoader</code> . If that
* fails, try Class.forname.
* <p/>
*
* @param clazz
* @return Returns Class.
* @throws ClassNotFoundException
*/
static public Class loadClass(String clazz) throws ClassNotFoundException {
try {
ClassLoader tcl = getTCL();
if(tcl != null) {
Class c = tcl.loadClass(clazz);
if (c != null)
return c;
}
} catch (Throwable e) {
log.debug(e);
}
// we reached here because tcl was null or because of a
// security exception, or because clazz could not be loaded...
// In any case we now try one more time
return Class.forName(clazz);
}
After change:
static public Class loadClass(ClassLoader loader, String clazz) throws
ClassNotFoundException {
try {
Class c = ClassLoaderUtils.loadClass(clazz,
org.apache.axis2.AxisFault.class);
if (c != null)
return c;
} catch (Throwable e) {
log.warn(e);
throw new ClassNotFoundException();
}
return loadClass(clazz);
}
static public Class loadClass(String clazz) throws ClassNotFoundException {
try {
Class c = ClassLoaderUtils.loadClass(clazz,
org.apache.axis2.AxisFault.class);
if (c != null)
return c;
} catch (Throwable e) {
log.warn(e);
throw new ClassNotFoundException();
}
// we reached here because tcl was null or because of a
// security exception, or because clazz could not be loaded...
// In any case we now try one more time
return Class.forName(clazz);
}
public class ClassLoaderUtils {
/**
* Load a given resource.
* <p/>
* This method will try to load the resource using the following methods
(in order):
* <ul>
* <li>From [EMAIL PROTECTED] Thread#getContextClassLoader()
Thread.currentThread().getContextClassLoader()}
* <li>From [EMAIL PROTECTED] Class#getClassLoader()
ClassLoaderUtil.class.getClassLoader()}
* <li>From the [EMAIL PROTECTED] Class#getClassLoader()
callingClass.getClassLoader() }
* </ul>
*
* @param resourceName The name of the resource to load
* @param callingClass The Class object of the calling object
*/
public static URL getResource(String resourceName, Class callingClass) {
URL url = null;
url =
Thread.currentThread().getContextClassLoader().getResource(resourceName);
if (url == null) {
url =
ClassLoaderUtils.class.getClassLoader().getResource(resourceName);
}
if (url == null) {
url = callingClass.getClassLoader().getResource(resourceName);
}
return url;
}
/**
* This is a convenience method to load a resource as a stream.
* <p/>
* The algorithm used to find the resource is given in getResource()
*
* @param resourceName The name of the resource to load
* @param callingClass The Class object of the calling object
*/
public static InputStream getResourceAsStream(String resourceName, Class
callingClass) {
URL url = getResource(resourceName, callingClass);
try {
return (url != null) ? url.openStream() : null;
} catch (IOException e) {
return null;
}
}
/**
* Load a class with a given name.
* <p/>
* It will try to load the class in the following order:
* <ul>
* <li>From [EMAIL PROTECTED] Thread#getContextClassLoader()
Thread.currentThread().getContextClassLoader()}
* <li>Using the basic [EMAIL PROTECTED] Class#forName(java.lang.String) }
* <li>From [EMAIL PROTECTED] Class#getClassLoader()
ClassLoaderUtil.class.getClassLoader()}
* <li>From the [EMAIL PROTECTED] Class#getClassLoader()
callingClass.getClassLoader() }
* </ul>
*
* @param className The name of the class to load
* @param callingClass The Class object of the calling object
* @throws ClassNotFoundException If the class cannot be found anywhere.
*/
public static Class loadClass(String className, Class callingClass) throws
ClassNotFoundException {
try {
return
Thread.currentThread().getContextClassLoader().loadClass(className);
} catch (ClassNotFoundException e) {
try {
return Class.forName(className);
} catch (ClassNotFoundException ex) {
try {
return
ClassLoaderUtils.class.getClassLoader().loadClass(className);
} catch (ClassNotFoundException exc) {
return callingClass.getClassLoader().loadClass(className);
}
}
}
}
/**
* Prints the current classloader hierarchy - useful for debugging.
*/
public static void printClassLoader() {
System.out.println("ClassLoaderUtils.printClassLoader");
printClassLoader(Thread.currentThread().getContextClassLoader());
}
/**
* Prints the classloader hierarchy from a given classloader - useful for
debugging.
*/
public static void printClassLoader(ClassLoader cl) {
System.out.println("ClassLoaderUtils.printClassLoader(cl = " + cl +
")");
if (cl != null) {
printClassLoader(cl.getParent());
}
}
}
Additionally, I have found that if the target class not be loaded successfully,
there is no way to throw ClassNotFoundException, I think it's not proper and it
will give the developer wrong message of Exception.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]