Over a million developers have joined DZone.
Silver Partner

Spring 3.1 Release and runtime exception with Logfactory

· Java Zone

The Java Zone is presented by Hazelcast.  Learn more about Hazelcast on Azure and the best practices for seamless deployment of Hazelcast on Azure Virtual Machines.

With the upgrade this morning of our applications to Spring 3.1.1-RELEASE, we obtained odd runtime exceptions :

The detailed stacktrace is : 

java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
	at org.springframework.context.support.AbstractApplicationContext.<init>(AbstractApplicationContext.java:161)
	at org.springframework.context.support.AbstractRefreshableApplicationContext.<init>(AbstractRefreshableApplicationContext.java:90)
	at org.springframework.context.support.AbstractRefreshableConfigApplicationContext.<init>(AbstractRefreshableConfigApplicationContext.java:59)
	at org.springframework.context.support.AbstractXmlApplicationContext.<init>(AbstractXmlApplicationContext.java:61)
	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:136)
	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
	at com.tocea.codewatch.platform.service.local.LocalCodewatch.init(LocalCodewatch.java:116)
	at com.tocea.codewatch.platform.service.local.LocalCodewatch.<init>(LocalCodewatch.java:50)
	at com.tocea.codewatch.platform.front.test.FakeAuditTest.setUp(FakeAuditTest.java:54)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:616)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
	at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
	... 32 more

  The suspected class is

/**
...
*/
public abstract class AbstractApplicationContext extends DefaultResourceLoader
        implements ConfigurableApplicationContext, DisposableBean {
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    /** Logger used by this class. Available to subclasses. */
    protected final Log logger = LogFactory.getLog(getClass());
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

   After inspecting the dependencies of our project with mvn dependency:dependency-list.

[INFO] \- org.springframework:spring-context:jar:3.1.1.RELEASE:compile
[INFO]    +- org.springframework:spring-aop:jar:3.1.1.RELEASE:compile
[INFO]    |  \- aopalliance:aopalliance:jar:1.0:compile
[INFO]    +- org.springframework:spring-beans:jar:3.1.1.RELEASE:compile
[INFO]    +- org.springframework:spring-core:jar:3.1.1.RELEASE:compile
[INFO]    +- org.springframework:spring-expression:jar:3.1.1.RELEASE:compile
[INFO]    \- org.springframework:spring-asm:jar:3.1.1.RELEASE:com

 Curiously, the class AbstractApplicationContext inside org.springframework:spring-context does not depend from commmons-logging of Apache.

The correction is rather simple : add the following lines to your pom.xml :

<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.1</version>
</dependency>

A reader indicated me that :

Chin Huang   :

The Spring Reference Documentation explains why Spring does NOT depend on Apache commons-logging and recommends using instead SLF4J and its jcl-over-slf4j library which adapts the commons-logging API to the SLF4J API. 

 

Answer : The main problem is that nothing is indicated by maven that this choice exist and no suggestion is made by maven. That is a flaw would be interesting to fix in a new maven plugin. In Tocea, we are going to start a project to manage this kind of problem. Stay informed!

The Java Zone is presented by Hazelcast.  Learn more about Hazelcast on Azure and the best practices for seamless deployment of Hazelcast on Azure Virtual Machines.

Topics:

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}