ant-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From v...@trilogy.com
Subject Re: ClassLoader: log4j 1.2 in JUnit tests
Date Fri, 18 Jan 2002 22:11:19 GMT
You could try this:

Thread.currentThread ().setContextClassLoader (getClass().getClassLoader 
());

in your code, some time before the tests are run. [a more general fix 
would be to first check that the context classloader is not already the 
same as or a child of the current loader and only do this fix when that 
condition is not true. Better yet, it should be done by execute() of 
whichever task you are using.]


>The log4j FAQ says that they're using the Java 2 "preferred method for
>loading classes" now:
>
>Thread.currentThread().getContextClassLoader().loadClass()

This statement is quite wrong. Thread context loaders were introduced to 
make standard extensions like JNDI work [in JDK 1.2.x], where that was the 
only possible solution. In general, business code should continue to use 
the current classloader (getClass().getClassLoader()).

While the current log4j approach will work in many cases, in general there 
is nothing to guarantee which of the two {current, thread context} 
classloaders is a child of the other one. If the creator of the current 
thread did not bother to set the context classloader, it will be the same 
as for the parent thread. If all threads do that, the context loaders will 
remain equal to the application loader (the one that processes 
-classpath), which would be quite wrong when you run within ANT's 
classloader [which sits on top of the application one and insulates you 
from it]. Looking through ANT 1.4 sources, the only place where the 
context loader is set is in ExecuteJava, which is used by the <java> task. 
If your task is different, you have to use my first suggestion either to 
patch the task itself or set the context loader in every testcase...

[BTW, early JNLP releases had a similar issue: see 
http://forum.java.sun.com/thread.jsp?forum=38&thread=70946 for more 
background reading]. Amazing how poorly Sun people understand each other's 
work...

Vlad.



Please respond to "Ant Users List" <ant-user@jakarta.apache.org>
To:     "Ant Users List (E-mail)" <ant-user@jakarta.apache.org>
cc: 

Subject:        ClassLoader: log4j 1.2 in JUnit tests


Hello,

I'm not sure if this is more appropriate in the log4j mailing list, but
hopefully it's relevant here.

I'm using log4j 1.2alpha6 and my JUnit tests, when run via Ant 1.4.1, are
failing to log correctly. I've figured out that the default class loader
that Ant is using is different from the one log4j is using when 
configuring
appenders from a properties file.

The log4j FAQ says that they're using the Java 2 "preferred method for
loading classes" now:

Thread.currentThread().getContextClassLoader().loadClass()

Unfortunately, the context class loader for the current thread is not the
Ant class loader but rather the built-in JRE class loader. What I'm 
getting
is:

log4j:ERROR: A "foo.mumble.MyAppender" object is not assignable
to a "org.apache.log4j.Appender" variable.

Sure enough, from looking at the code, the older log4j 1.1.3 just uses
Class.forName() to load the classes, which works, but the newer one uses 
the
syntax above, which doesn't.

Has anyone had this problem? Is there a way around this? Thanks so much in
advance,

Dave H

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





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


Mime
View raw message