Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

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

Posted on 2004-04-19
21
Medium Priority
?
1,099 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Build and deliver software with DevOps

A digital transformation requires faster time to market, shorter software development lifecycles, and the ability to adapt rapidly to changing customer demands. DevOps provides the solution.

 
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: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering 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

After being asked a question last year, I went into one of my moods where I did some research and code just for the fun and learning of it all.  Subsequently, from this journey, I put together this article on "Range Searching Using Visual Basic.NET …
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
Viewers learn about the “for” loop and how it works in Java. By comparing it to the while loop learned before, viewers can make the transition easily. You will learn about the formatting of the for loop as we write a program that prints even numbers…
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
Suggested Courses

721 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