Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Commons-logging+jUnit - Bizzarre problem - may be JVM bug?

Posted on 2004-04-19
21
Medium Priority
?
1,101 Views
Last Modified: 2011-04-14
This is really odd.

I have some jUnit test cases.  When i run them under the JBuilder TestRunner and the text TestRunner, everything is fine.  When I run them under the Swing TestRunner, they blow up because the logger interface casting check fails.

We are using the common-logging interface and log4j.

The exact method that is failing is org.apache.commons.logging.impl.LogFactoryImpl.getLogConstructor().

The exact point of failure is this snip:

            if (!Log.class.isAssignableFrom(logClass)) {
                throw new LogConfigurationException
                    ("Class " + logClassName + " does not implement Log");
            }

logClass is org.apache.commons.logging.impl.Log4JLogger.

I have confirmed both by code review and by visually checking the instance in the debugger (during a cycle where the test fails) that logClass implements the org.apache.commons.logging.Log interface.

I have confirmed that I am using exactly the same class path for all three test runners.

I have ensured that I only have one version of Log4J and commons-logging on my box.

I get the same results with JRE 1.4.1, and 1.4.2.
0
Comment
Question by:swift99
  • 10
  • 9
  • 2
21 Comments
 
LVL 86

Expert Comment

by:CEHJ
ID: 10861735
>>they blow up because the logger interface casting check fails

What exactly is the error that shows?
0
 
LVL 6

Author Comment

by:swift99
ID: 10861766
The exact error is:

org.apache.commons.logging.LogConfigurationException: Class org.apache.commons.logging.impl.Log4JLogger does not implement Log.

I have traced into the commons-logging package and comfirmed that it is executing the snip of code identified in the original message.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 10861791
>>does not implement Log.

Make sure you pass the fully-qualified (inc package) class name into the method
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 6

Author Comment

by:swift99
ID: 10861832
If this were the problem, then wouldn't the text and JBuilder test runners display the same behavior?

I have confirmed visually that the logClass is <org.apache.commons.logging.impl.Log4JLogger> both when the test succeeds and when it fails.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 10861840
i.e.

if (!Log.class.isAssignableFrom(Class.forName("org.apache.commons.logging.Log"))) {
}
0
 
LVL 86

Assisted Solution

by:CEHJ
CEHJ earned 500 total points
ID: 10861852
>>If this were the problem

Could be down to different class loading behaviour. Give the above a try - it can't do any harm - and we can go from there
0
 
LVL 6

Author Comment

by:swift99
ID: 10861864
This code is part of the apache commons-logging package.  While modification is technically feasible, it should not be necessary.  This package, and its initialization code, is used without alteration by thousands of java apps around the world.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 10861907
>>This code is part of the apache commons-logging package

Do you mean it's their source!? If so then you need to do


Class classToTest = Class.forName("org.apache.commons.logging.Log");

and then pass it to their code

The trouble is, there are so many logging implementations around, if you are not very careful with packages and f.q. names you can get conflicts.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 10862005
If you pass -verbose

java -verbose YourMainClass

you should see where your classes are being loaded from in each case
0
 
LVL 6

Author Comment

by:swift99
ID: 10862320
Here's something odd from the verbose printout - see the last three lines.

It appears that two versions of Log are being loaded (!?)

[Loaded org.apache.commons.logging.LogFactory]
[Loaded org.apache.commons.logging.LogConfigurationException]
[Loaded java.io.UnsupportedEncodingException from D:\DevTools\JBuilder9\jdk1.4\jre\lib\rt.jar]
[Loaded java.lang.SecurityException from D:\DevTools\JBuilder9\jdk1.4\jre\lib\rt.jar]
[Loaded org.apache.commons.logging.LogFactory$1]
[Loaded org.apache.commons.logging.LogFactory$3]
[Loaded org.apache.commons.logging.LogFactory$2]
[Loaded org.apache.commons.logging.impl.LogFactoryImpl]
[Loaded org.apache.commons.logging.impl.LogFactoryImpl$1]
[Loaded org.apache.log4j.spi.AppenderAttachable]
[Loaded org.apache.log4j.Category]
[Loaded org.apache.log4j.Logger]
[Loaded org.apache.commons.logging.Log]
[Loaded org.apache.commons.logging.impl.Log4JLogger]
[Loaded org.apache.commons.logging.Log]

0
 
LVL 86

Expert Comment

by:CEHJ
ID: 10862345
What about the 'from' bit though?
0
 
LVL 6

Author Comment

by:swift99
ID: 10862494
Now THAT was   interesting ... Under text TestRunner, the JDK14 logger class is used - not the Log4J class.

I think that explains what is different, but not _why_ it is different.  Thanks for the ammo for more research.
0
 
LVL 6

Author Comment

by:swift99
ID: 10862501
There was no "from" bit for the logging packages.  What you see is what I got.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 10862548
>>Now THAT was   interesting ...

This is precisely the sort of thing i was talking about. Double check the classpath being used in each case
0
 
LVL 6

Author Comment

by:swift99
ID: 10862575
The class path is identical.  The batch file was copied and the junit.textui.TestRunner was changed to junit.swingui.TestRunner.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 10862592
>>The class path is identical.  

I thought in one case JBuilder was being used? It constructs its own classpath
0
 
LVL 6

Author Comment

by:swift99
ID: 10862747
Yes ... it is the ultimate origin of all other classpaths.
0
 
LVL 92

Accepted Solution

by:
objects earned 500 total points
ID: 10864559
Your problem is probably caused by multiple versions of a library being available to the class loader.
0
 
LVL 6

Author Comment

by:swift99
ID: 10868911
Well ... we were all on the right track.

The jUnit swing TestRunner, under some circumstances, loads the classes twice.  Turning off the "Reload classes every run" checkbox on the TestRunner resolved the problem.  The existence of this checkbox suggests that others have had this problem.

Thanks!
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 10868933
8-)
0
 
LVL 92

Expert Comment

by:objects
ID: 10873144
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Java had always been an easily readable and understandable language.  Some relatively recent changes in the language seem to be changing this pretty fast, and anyone that had not seen any Java code for the last 5 years will possibly have issues unde…
In this post we will learn different types of Android Layout and some basics of an Android App.
Viewers learn how to read error messages and identify possible mistakes that could cause hours of frustration. Coding is as much about debugging your code as it is about writing it. Define Error Message: Line Numbers: Type of Error: Break Down…
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:
Suggested Courses

885 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question