Issue
When you use third-party libraries in an OSGi bundle, you get class loading issues such as the following:
Requested factory mypackage.FooBar cannot be located. Classloader =java.net.URLClassLoader@6aa8d01c
Note: This error is just an example error message. The issue is that classes loaded by third-party libraries aren't found, even though the corresponding class is definitely imported.
Real-life example
Apache Axis2 could throw the following stacktrace for no reason:
18.02.2010 17:04:30.153 *INFO* [10.43.97.19 [1266509048609] POST /path/to/servlet HTTP/1.1]
org.apache.axis2.transport.http.HTTPSender Unable to sendViaPost to url[xy] org.apache.axis2.AxisFault:
Requested factory com.ctc.wstx.stax.WstxOutputFactory cannot be located.
Classloader =java.net.URLClassLoader@6aa8d01c
at org.apache.axis2.AxisFault.makeFault(AxisFault.java:430)
at org.apache.axis2.transport.http.AxisRequestEntity.writeRequest(AxisRequestEntity.java:96)
at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(EntityEnclosingMethod.java:499)
...
Solution
The way that third-party libraries load their classes is out of your control. In most cases it's fine, if the third-party library uses the normal classloader from the bundle. But sometimes a library, like Apache Axis2, could try to load a class like the following:
Thread.currentThread().getContextClassLoader().loadClass("mypackage.FooBar");
By default, the Thread context class loader is not aware of OSGi and thus doesn't see any of the classes imported in the bundle. That's why loading the class fails.
In your code, before the third-party code is executed, you can tell the current thread to use the class loader from the bundle. Do this temporarily for the third-party code that doesn't load some classes:
ClassLoader tccl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
try {
// execute 3rd party code
} finally {
Thread.currentThread().setContextClassLoader(tccl);
}
Applies to
CQ 5.x, AEM6.x