commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jan Luehe <Jan.Lu...@Sun.COM>
Subject Classloading regression between commons-digester-1.0 and later versions
Date Thu, 29 Sep 2005 20:57:15 GMT
This may be an old topic, but it seems a classloading regression was
introduced between commons-digester-1.0 and later versions (including
the most recent).

In commons-digester-1.0, a class was loaded as follows:

    Class clazz = null;

    // Check to see if the context class loader is set,
    // and if so, use it, as it may be set in server-side
    // environments and Class.forName() may cause issues
    ClassLoader ctxLoader =
        Thread.currentThread().getContextClassLoader();
    if (ctxLoader == null) {
        clazz = Class.forName(realClassName);
    } else {
        clazz = ctxLoader.loadClass(realClassName);
    }

that is, if a context classloader had been set, it was used
(unconditionally).

In contrast, commons-digester-1.1 (and up) loads a class as follows:

    Class clazz = digester.getClassLoader().loadClass(realClassName);

where Digester.getClassLoader() is implemented as follows:

    /**
     * Return the class loader to be used for instantiating application
objects
     * when required.  This is determined based upon the following rules:
     * <ul>
     * <li>The class loader set by <code>setClassLoader()</code>, if
any</li>
     * <li>The thread context class loader, if it exists and the
     *     <code>useContextClassLoader</code> property is set to true</li>
     * <li>The class loader used to load the Digester class itself.
     * </ul>
     */
    public ClassLoader getClassLoader() {

        if (this.classLoader != null)
            return (this.classLoader);
        if (this.useContextClassLoader) {
            ClassLoader classLoader =
                Thread.currentThread().getContextClassLoader();
            if (classLoader != null)
                return (classLoader);
        }
        return (this.getClass().getClassLoader());

    }

that is, the context classloader is used only if it exists *AND*
the "useContextClassLoader" property has been set to TRUE. Unfortunately,
"useContextClassLoader" is FALSE by default, preventing the digester to
load any classes further down in the classloading hierarchy (e.g., in
WEB-INF/lib).

Can someone explain to me the motivation for setting the
"useContextClassLoader" property to FALSE by default?

We can easily restore the commons-digester-1.0 behaviour in our own
code by setting "useContextClassLoader" to TRUE on the Digester
instances we acquire. However, this is not possible on "foreign" code
that we bundle.

It would be useful if Digester.getClassLoader() would also consider a
system property (in addition to its own "useContextClassLoader"
property) when determining whether to use the context classloader.

Any comments appreciated.


Jan




---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message