ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bugzi...@apache.org
Subject DO NOT REPLY [Bug 6606] - META-BUG problems with delegating classloaders
Date Wed, 12 Jun 2002 07:32:18 GMT
DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=6606>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=6606

META-BUG problems with delegating classloaders





------- Additional Comments From jochen.wiedmann@softwareag.com  2002-06-12 07:32 -------
I have a suggestion, which fixes most of the problems. More precise,
it someone depends on the "right" behaviour of the software components
in use. But the most important software component is, of course, Ant.

First, let me explain my view of the problem: Any Java class has
an associated ClassLoader. The ClassLoader has loaded the class,
thus it is able to load other classes from the same JAR file (or
files). If two classes A and B have different ClassLoaders and B
tries to load a class from A's JAR file with Class.forName(...),
then this doesn't necessarily work.

This is exactly the problem with Ant. For example, if I load a
class MyTask with

  <taskdef name="mytask" ...><classpath>...</classpath></taskdef>

then the class MyTask has the right ClassLoader, but the Ant
classes don't. So, if for example the MyTask uses a class MyType
implementing a nested element of MyTask, then the IntrospectionHelper
will do a Class.forName("MyType"). This fails, because Class.forName
uses the ClassLoader of the IntrospectionHelper.

The proposed solution works as follows:

  - Never use Class.forName(). Replace it with a helper method
    like

      public static Class myForName(String name)
          throws ClassNotFoundException {
        try {
          return Class.forName(name);
        } catch (ClassNotFoundException e) {
          ClassLoader cl = Thread.currentThread().getContextClassLoader();
          if (cl == null) {
            throw e;
          }
          return cl.loadClass(name);
        }

  - Make sure, that the threads ContextClassLoader is right. For
    example, use a helper class ThreadContextClassLoader, which
    grabs the current ContextClassLoader and an additional
    ClassLoader and uses Class.forName(), original thread
    ContextClassLoader and the additional ClassLoader, in that
    order and enclose the perform() method with

      Task task;
      ThreadClassLoader tcl =
        new ThreadClassLoader(task.getClass().getClassLoader());
      ClassLoader cl = Thread.currentThread().getClassLoader();
      try {
        Thread.currentThread.setContextClassLoader(tcl);
        task.perform;
      } finally {
        Thread.currentThread.setContextClassLoader(cl);
      }

I offer to create a patch, if someone (Stefan?) discusses details
with me and advices me, which version to patch exactly.


Regards,

Jochen

--
To unsubscribe, e-mail:   <mailto:ant-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:ant-dev-help@jakarta.apache.org>


Mime
View raw message