1

I am experimenting with spring, maven, and eclipse but stumbling on a weird issue.

I am running Eclipse Helios SR1 with the STS (Spring tools suite) plugin which includes the Maven plugin also.

What i want to achieve is a spring mvc webapp which uses an application context loaded from a local application context xml file, but also from other application contexts in jar files dependencies included in WEB-INF/lib.

What i'd ultimately like to do is have my persistence layer separated in its own jar file but containing its own spring context files with persistence specific configuration (e.g a jpa entityManagerFactory for example).

So to experiment with loading resources from jar dependencies, i created a simple maven project from eclipse, which defines an applicationContext.xml file in src/main/resources Inside, i define a bean

<bean id="mybean" class="org.test.MyClass" />

and create the class in the org.test package

I run mvn->install from eclipse, which generates me a jar file containing my class and the applicationContext.xml file:

 testproj.jar
|_META-INF
|_org
    |_test
         |_MyClass.class
|_applicationContext.xml

I then create a spring mvc project from the Spring template projects provided by STS. I have configured an instance of Tomcat 7.0.8 , and also an instance of springSource tc Server within eclipse. Deploying the newly created project on both servers works without problem.

I then add my previous project as a maven dependency of the mvc project. the jar file is correctly added in the Maven Dependencies of the project.

In the web.xml that is generated, i now want to load the applicationContext.xml from the jar file as well as the existing one generated for the project. My web.xml now looks like this:

org.springframework.web.context.ContextLoaderListener

<!-- Processes application requests -->
<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath*:applicationContext.xml,
            /WEB-INF/spring/appServlet/servlet-context.xml
        </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>appServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

Also, in my servlet-context.xml, i have the following:

<context:component-scan base-package="org.test" />
<context:component-scan base-package="org.remy.mvc" />

to load classes from the jar spring context (org.test) and to load controllers from the mvc app context.

I also change one of my controllers in org.remy.mvc to autowire MyClass to verify that loading the context has worked as intended.

public class MyController {

@Autowired
    private MyClass myClass;

    public void setMyClass(MyClass myClass) {
        this.myClass = myClass;
    }

    public MyClass getMyClass() {
        return myClass;
    }

[...] 
}

Now this is the weird bit:

If i deploy the spring mvc web on my tomcat instance inside eclipse (run on server...) I get the following error :

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping#0': Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/test/MyClass
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:442)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:458)
    at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:339)
    at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:306)
    at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:127)
    at javax.servlet.GenericServlet.init(GenericServlet.java:160)
    at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1133)
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1087)
    at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:996)
    at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4834)
    at org.apache.catalina.core.StandardContext$3.call(StandardContext.java:5155)
    at org.apache.catalina.core.StandardContext$3.call(StandardContext.java:5150)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
    at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.NoClassDefFoundError: org/test/MyClass
    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2427)
    at java.lang.Class.getDeclaredMethods(Class.java:1791)
    at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:446)
    at org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping.determineUrlsForHandlerMethods(DefaultAnnotationHandlerMapping.java:172)
    at org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping.determineUrlsForHandler(DefaultAnnotationHandlerMapping.java:118)
    at org.springframework.web.servlet.handler.AbstractDetectingUrlHandlerMapping.detectHandlers(AbstractDetectingUrlHandlerMapping.java:79)
    at org.springframework.web.servlet.handler.AbstractDetectingUrlHandlerMapping.initApplicationContext(AbstractDetectingUrlHandlerMapping.java:58)
    at org.springframework.context.support.ApplicationObjectSupport.initApplicationContext(ApplicationObjectSupport.java:119)
    at org.springframework.web.context.support.WebApplicationObjectSupport.initApplicationContext(WebApplicationObjectSupport.java:72)
    at org.springframework.context.support.ApplicationObjectSupport.setApplicationContext(ApplicationObjectSupport.java:73)
    at org.springframework.context.support.ApplicationContextAwareProcessor.invokeAwareInterfaces(ApplicationContextAwareProcessor.java:106)
    at org.springframework.context.support.ApplicationContextAwareProcessor.postProcessBeforeInitialization(ApplicationContextAwareProcessor.java:85)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:394)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1413)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    ... 25 more
20-Feb-2011 10:54:53 org.apache.catalina.core.ApplicationContext log
SEVERE: StandardWrapper.Throwable
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping#0': Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/test/MyClass

If i build the war file (using maven "install" goal), and then deploy that war file in the webapps directory of a standalone tomcat server (7.0.8 as well) it WORKS :-(

What am i missing ?

Thanks for the help.

Remy J
  • 41
  • 1
  • 1
  • 4
  • If you inspect your produced jar, does `org.test.MyClass` exist there? – Johan Sjöberg Feb 20 '11 at 11:55
  • yes... and the jar is also present in the war file WEB-INF/lib. Eclipse does not report any errors either. The only thing i can think of is that somehow the classloader of tomcat behaves differently when loaded within eclipse than when running standalone. But i am not sure what to do if that's the case – Remy J Feb 20 '11 at 12:06
  • 1
    possible duplicate of [ClassNotFoundException DispatcherServlet when launching Tomcat (Maven dependencies not copied to wtpwebapps)](http://stackoverflow.com/questions/4777026/classnotfoundexception-dispatcherservlet-when-launching-tomcat-maven-dependenci) – artbristol May 09 '12 at 07:17

2 Answers2

3

Thanks to all of you who tried to answer my question. I think i found the solution to my own problem (after much frustration)

This has already been answered in

ClassNotFoundException DispatcherServlet when launching Tomcat (Maven dependencies not copied to wtpwebapps)

Community
  • 1
  • 1
Remy J
  • 41
  • 1
  • 1
  • 4
1

Sounds like a spring.jar is being picked up from inside Tomcat which is the wrong classloader as it cannot see your classes.

How did you install said Tomcat inside Eclipse?

Thorbjørn Ravn Andersen
  • 73,784
  • 33
  • 194
  • 347
  • I have downloaded Tomcat from the apache website as a zip, and then pointed eclipse to it in Preferences->Server->Runtime Environments->Add... then selected apache Tomcat 7.0 in the list and pointed to the directory where i unzipped it. – Remy J Feb 20 '11 at 15:48