Solved

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

Posted on 2004-04-19
21
1,093 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
Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

 
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 125 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 125 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

Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
JList custom Cell Renderer refresh 15 57
session migration servlets 2 39
Unhandled exception type Exception 18 31
Selenium docs api java index 3 19
Java contains several comparison operators (e.g., <, <=, >, >=, ==, !=) that allow you to compare primitive values. However, these operators cannot be used to compare the contents of objects. Interface Comparable is used to allow objects of a cl…
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.

831 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