log4j/class loading problem

898 views
Skip to first unread message

Katarina Hallberg

unread,
Nov 6, 2008, 10:03:51 AM11/6/08
to PowerMock
Making my first unit test using powermock I have run in to some
trouble concerning class loading and log4j.

I get the following output when running my test with the
@RunWith(PowerMockRunner.class) annotation, using maven.

---
log4j:ERROR A "org.apache.log4j.xml.DOMConfigurator" object is not
assignable to a "org.apache.log4j.spi.Configurator" variable.
log4j:ERROR The class "org.apache.log4j.spi.Configurator" was loaded
by
log4j:ERROR [org.powermock.core.classloader.MockClassLoader@14a55f2]
whereas object of type
log4j:ERROR "org.apache.log4j.xml.DOMConfigurator" was loaded by
[sun.misc.Launcher$AppClassLoader@92e78c].
log4j:ERROR Could not instantiate configurator
[org.apache.log4j.xml.DOMConfigurator].
---

In the test result report the following message appears:

---
testGetNameComboModel(com.alfakl.origo.sollss.gfp.wizard.model.GFPWizardModelTest)
Time elapsed: 0.203 sec <<< ERROR!
java.lang.ExceptionInInitializerError
at
org.springframework.beans.BeanUtils.getPropertyDescriptors(BeanUtils.java:
300)
at org.springframework.beans.BeanUtils.copyProperties(BeanUtils.java:
485)
at org.springframework.beans.BeanUtils.copyProperties(BeanUtils.java:
416)
at com.alfakl.origo.sollss.gfp.domain.GFPProxy.restore(GFPProxy.java:
115)
at com.alfakl.origo.sollss.gfp.domain.GFPProxy.<init>(GFPProxy.java:
90)
at
com.alfakl.origo.sollss.gfp.wizard.model.GFPWizardModelTest.setUp(GFPWizardModelTest.java:
161)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
at java.lang.reflect.Method.invoke(Method.java:585)
at
org.junit.internal.runners.MethodRoadie.runBefores(MethodRoadie.java:
129)
at
org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:
93)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:
84)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
at
org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:
163)
at
org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:
120)
at
org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl
$1.run(PowerMockJUnit44RunnerDelegateImpl.java:113)
at
org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:
34)
at
org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:
44)
at
org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:
111)
at
org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:
87)
at
org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:
44)
at
org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:
62)
at
org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:
140)
at
org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:
127)
at org.apache.maven.surefire.Surefire.run(Surefire.java:177)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
at java.lang.reflect.Method.invoke(Method.java:585)
at
org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:
345)
at
org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:
1009)
Caused by: org.apache.commons.logging.LogConfigurationException:
org.apache.commons.logging.LogConfigurationException:
org.apache.commons.logging.LogConfigurationException: Invalid class
loader hierarchy. You have more than one version of
'org.apache.commons.logging.Log' visible, which is not allowed.
(Caused by org.apache.commons.logging.LogConfigurationException:
Invalid class loader hierarchy. You have more than one version of
'org.apache.commons.logging.Log' visible, which is not allowed.)
(Caused by org.apache.commons.logging.LogConfigurationException:
org.apache.commons.logging.LogConfigurationException: Invalid class
loader hierarchy. You have more than one version of
'org.apache.commons.logging.Log' visible, which is not allowed.
(Caused by org.apache.commons.logging.LogConfigurationException:
Invalid class loader hierarchy. You have more than one version of
'org.apache.commons.logging.Log' visible, which is not allowed.))
at
org.apache.commons.logging.impl.LogFactoryImpl.newInstance(LogFactoryImpl.java:
543)
at
org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:
235)
at
org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:
209)
at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:351)
at
org.springframework.beans.CachedIntrospectionResults.<clinit>(CachedIntrospectionResults.java:
60)
... 32 more
Caused by: org.apache.commons.logging.LogConfigurationException:
org.apache.commons.logging.LogConfigurationException: Invalid class
loader hierarchy. You have more than one version of
'org.apache.commons.logging.Log' visible, which is not allowed.
(Caused by org.apache.commons.logging.LogConfigurationException:
Invalid class loader hierarchy. You have more than one version of
'org.apache.commons.logging.Log' visible, which is not allowed.)
at
org.apache.commons.logging.impl.LogFactoryImpl.getLogConstructor(LogFactoryImpl.java:
397)
at
org.apache.commons.logging.impl.LogFactoryImpl.newInstance(LogFactoryImpl.java:
529)
... 36 more
Caused by: org.apache.commons.logging.LogConfigurationException:
Invalid class loader hierarchy. You have more than one version of
'org.apache.commons.logging.Log' visible, which is not allowed.
at
org.apache.commons.logging.impl.LogFactoryImpl.getLogConstructor(LogFactoryImpl.java:
385)
... 37 more
---

If removing the use of powermock in my test, it works fine. Adding the
@RunWith annotation causes the errors above.

Have you ever seen this problem before and can give me a hint on what
might be the problem/where to start looking?

I'm using powermock-module-junit4-0.8.5.
Please let me know if you need any more information.


/Katarina

Johan Haleby

unread,
Nov 6, 2008, 10:56:42 AM11/6/08
to powe...@googlegroups.com
Could you please attach or supply the code that you're trying to test?

Barrie Treloar

unread,
Nov 6, 2008, 6:06:38 PM11/6/08
to powe...@googlegroups.com
On Fri, Nov 7, 2008 at 1:33 AM, Katarina Hallberg
<hallberg...@gmail.com> wrote:
>
> Making my first unit test using powermock I have run in to some
> trouble concerning class loading and log4j.
>
> I get the following output when running my test with the
> @RunWith(PowerMockRunner.class) annotation, using maven.

This is probably because the class under test has not been mocked out
properly and the actual class is trying to do stuff, like log4j.

Make sure you have @PrepareForTest( { XXX })
Where XXX is a list of classes that PowerMock needs to enhance to mock
out the real implementations.

Katarina Hallberg

unread,
Nov 7, 2008, 2:18:25 AM11/7/08
to PowerMock
On 7 Nov, 00:06, "Barrie Treloar" <baerr...@gmail.com> wrote:

> This is probably because the class under test has not been mocked out
> properly and the actual class is trying to do stuff, like log4j.
>
> Make sure you have @PrepareForTest( { XXX })
> Where XXX is a list of classes that PowerMock needs to enhance to mock
> out the real implementations.


Having a deadline to meet I have been forced to focus on other (not
nearly so exciting) stuff than introducing Powermock in my
unittest. :-(

However, I think you are right Barrie, there are a lot of stuff in the
class beeing tested that has not been mocked out. Yet. Among those the
class that appears in the stacktrace (GFPProxy). I just didn't think
that would be a problem when all I have right now in my test concering
Powermock is the RunWith-annotation. (I had the PrepareForTest-
annotation and my testcases using Powermock removed to isolate the
problem.) But I guess I'll give it another try when I can find the
time and try make sure the class is totally mocked out. If I still run
into trouble I'll see if I can post the class I'm trying to test to
make it easier for you to help me.

Thank you for now, hope to be back soon!

/Katarina

Johan Haleby

unread,
Nov 7, 2008, 2:21:41 AM11/7/08
to powe...@googlegroups.com
Yes that's true, I'd still like to see the class you're trying to test (if you're not allowed to post the code perhaps you code post a proof of concept?) because I suspect that this is similar to the problem that you asked about before Barrie. I suspect that mabey we should put this into an FAQ.

Johan Haleby

unread,
Nov 7, 2008, 2:24:11 AM11/7/08
to powe...@googlegroups.com
Ok good luck with the deadline, please keep in touch if you need any more help or have any other questions or comments.

Katarina Hallberg

unread,
Nov 7, 2008, 3:33:44 AM11/7/08
to PowerMock
I'll hope to be able to post some proof-of-concept-code in the near
future.

Just so I understand it correctly - when introducing Powermock in your
test-cases, the class under test MUST be totally mocked out?

On 7 Nov, 08:24, "Johan Haleby" <johan.hal...@gmail.com> wrote:
> Ok good luck with the deadline, please keep in touch if you need any more
> help or have any other questions or comments.
>
> On Fri, Nov 7, 2008 at 8:21 AM, Johan Haleby <johan.hal...@gmail.com> wrote:
> > Yes that's true, I'd still like to see the class you're trying to test (if
> > you're not allowed to post the code perhaps you code post a proof of
> > concept?) because I suspect that this is similar to the problem that you
> > asked about before Barrie. I suspect that mabey we should put this into an
> > FAQ.
>

Johan Haleby

unread,
Nov 7, 2008, 3:48:53 AM11/7/08
to powe...@googlegroups.com
No that's usually not necessary but there are cases when some frameworks e.g. instantiate classes from a particular classloader using reflection where things can be a bit messy. I suspect log4j might be doing something like this but I need to look into it more. In those cases you either need to load the class with PowerMock's classloader (using the PrepareForTest annotation) or simply stub out the implementation. I'll try to reproduce the issue and create and example project and a FAQ entry.
Reply all
Reply to author
Forward
0 new messages