cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Sergei S. Ivanov" <sergei_iva...@mail.ru>
Subject classloader conflicts
Date Sat, 04 Nov 2000 18:42:45 GMT

----- Original Message -----
From: "Martin Klang" <mars@pingdynasty.com>
To: <xalan-dev@xml.apache.org>
Sent: Wednesday, October 25, 2000 10:51 PM
Subject: Re: question: calling java-extensions


> i've found that changing the Class.forName() call to use the context
> classloader solves this problem.
>
> eg change XSLTJavaClassEngine to do something like:
>           ClassLoader cl = Thread.currentThread().getContextClassLoader();
>           object = Class.forName (className, true, cl);
>
> now, in tomcat they have a slightly more convoluted way of getting hold
> of the context cl:
>
> Thread t=Thread.currentThread();
> java.lang.reflect.Method getCCL = t.getClass()
> .getMethod("getContextClassLoader", noParams);
> ClassLoader old=(ClassLoader)getCCL.invoke( t, noObjs );
>
> i believe this is a workaround for jdk < 1.2, i'll investigate if there's
> interest from you xalan-people.

[...]

While trying to setup Cocoon under Resin, we ran into a problem of class
loader conflicts. Some classes (e.g. DOM interfaces) were loaded by the
default system class loader and some were loaded by Resin's context class
loader. As a result we had linkage errors while running compiled XSP pages,
because Cocoon used the system class loader.

I exploited the idea from the quoted message and came up with a couple of
patches, which solve the problem for me (see also comments below):

----------------------
org.apache.cocoon.processor.xsp.language.java.XSPClassLoader:

74c74
<     Class c = findLoadedClass(name);
---
>     Class c = null;
75a76,86
>     ClassLoader cl = Thread.currentThread().getContextClassLoader();
>     if (cl != null && cl != this) {
>       try {
>         c = Class.forName(name, true, cl);
>       }
>       catch (ClassNotFoundException e) {
>       }
>     }
>     if (c == null) {
>       c = findLoadedClass(name);
>     }
84c95
<           ClassLoader cl = this.getClass().getClassLoader();
---
>           cl = this.getClass().getClassLoader();


-------------------------
org.apache.cocoon.Utils:

310a311,315
>             ClassLoader cl =
Thread.currentThread().getContextClassLoader();
>             if (cl != null) {
>                 resource =
cl.getResource(location.substring("resource://".length()));
>             }
>             if (resource == null) {
311a317
>             }
323d328
<         Object resource = null;
334,339d338
<             resource = new File(location);
<         } else if (location.startsWith("resource://")) {
<             // FIXME (SM): this should _not_ be system resource, but
rather a resource of current classloader
<             resource =
ClassLoader.getSystemResource(location.substring("resource://".length()));
<         } else {
<             resource = new URL(location);
342c341
<         return resource;
---
>         return getLocationResource(location);

-----------

Comments:
The major problem with this code is that it is JDK1.2 dependent. To degrade
gracefully, we need some reflection-based tests (see quoted message again).
On the other hand, I strongly believe that Cocoon2/Xalan2 will drop JDK1.1
support.

I would appreciate comments from Cocoon developers...
Regards,
--
Sergei S. Ivanov  sergei_ivanov@object-tools.com
Object Tools, Moscow  http://www.object-tools.com


Mime
View raw message