Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Spring 3.1 Release and runtime exception with Logfactory

DZone's Guide to

Spring 3.1 Release and runtime exception with Logfactory

· Java Zone
Free Resource

Learn how to troubleshoot and diagnose some of the most common performance issues in Java today. Brought to you in partnership with AppDynamics.

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!

Understand the needs and benefits around implementing the right monitoring solution for a growing containerized market. Brought to you in partnership with AppDynamics.

Topics:

Opinions expressed by DZone contributors are their own.

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

{{ parent.tldr }}

{{ parent.urlSource.name }}