logging-log4j-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Gary Clayburg <gclay...@attbi.com>
Subject Problem with Junit swing TestRunner and log4j 1.2.7
Date Fri, 10 Jan 2003 12:23:19 GMT
I'm running into a problem with log4j configuration when running junit 
tests from the junit.swingui.TestRunner class.
Here is the error message I get to the console:

log4j:ERROR A "org.apache.log4j.ConsoleAppender" object is not 
assignable to a "org.apache.log4j.Appender" variable.
log4j:ERROR The class "org.apache.log4j.Appender" was loaded by
log4j:ERROR [junit.runner.TestCaseClassLoader@a9255c] whereas object of 
type
log4j:ERROR "org.apache.log4j.ConsoleAppender" was loaded by 
[sun.misc.Launcher$AppClassLoader@12f6684].
log4j:ERROR Could not instantiate appender named "A1".
log4j:ERROR A "org.apache.log4j.ConsoleAppender" object is not 
assignable to a "org.apache.log4j.Appender" variable.
log4j:ERROR The class "org.apache.log4j.Appender" was loaded by
log4j:ERROR [junit.runner.TestCaseClassLoader@a9255c] whereas object of 
type
log4j:ERROR "org.apache.log4j.ConsoleAppender" was loaded by 
[sun.misc.Launcher$AppClassLoader@12f6684].
log4j:ERROR Could not instantiate appender named "A1".
log4j:WARN No appenders could be found for logger (TestOmaha).
log4j:WARN Please initialize the log4j system properly.

These errors go away completely  if I specify -Dlog4j.ignoreTCL on the 
command line like this:

java -Dlog4j.ignoreTCL junit.swingui.TestRunner

This, of course, causes log4j to use Class.forName() to load 
org.apache.log4j.ConsoleAppender.

The junit swing test runner has a default option to reload classes 
everytime you click the "run" button.  This is a good thing so you can 
avoid restarting the gui.  The problem with log4j though, is that this 
is causing log4j to load the classes "org.apache.log4j.Appender" and 
"org.apache.log4j.ConsoleAppender" with different classloaders as seen 
in the error message.  The Appender class seems to be loaded as a 
regular java class (probably via new), but the ConsoleAppender is being 
loaded by this special Thread Context Classloader.  This Appender class 
is being loaded via this special junit class loader, 
"junit.runner.TestCaseClassLoader@a9255c".  ConsoleAppender needs to be 
loaded by either the same classloader used to load the Appender class or 
a child of that classloader.  It appears that log4j is using attempting 
to use a  parent of the classloader used to load Appender here.

What is the motivation is for using this Thread Context Classloader by 
default anyway?  

I haven't worked much with this Thread Context Classloader much, but 
accourding to the docs, getContextClassLoader() will return the the 
ClassLoader context of the parent Thread if setContextClassLoader() is 
not used.  In fact, you can see this behavior by clicking the "run" 
button with the junit swing TestRunner.  The Appender class is always 
loaded from a NEW classloader, but the ConsoleAppender class is always 
attempted to be loaded by the SAME classloader each time - i.e. the 
ConsoleAppender is being loaded by this one Thread Context Classloader 
that knows nothing about new classloaders being created by junit.

Does this make sense to anyone?



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


Mime
View raw message