简体   繁体   中英

Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: javax/servlet/ServletContext

I am trying to setup the Junit test with the MockMVC.

From this link - "either must not use the Servlet API or you need to provide it on the classpath".

I added the following to pom.xml but didn't work. any idea?

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>

here is the trace

org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.test.context.web.WebDelegatingSmartContextLoader]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: javax/servlet/ServletContext
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:163)
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:105)
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:130)
    at org.springframework.test.context.ContextLoaderUtils.resolveContextLoader(ContextLoaderUtils.java:118)
    at org.springframework.test.context.ContextLoaderUtils.buildMergedContextConfiguration(ContextLoaderUtils.java:594)
    at org.springframework.test.context.ContextLoaderUtils.buildMergedContextConfiguration(ContextLoaderUtils.java:560)
    at org.springframework.test.context.TestContext.<init>(TestContext.java:99)
    at org.springframework.test.context.TestContextManager.<init>(TestContextManager.java:117)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTestContextManager(SpringJUnit4ClassRunner.java:119)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.<init>(SpringJUnit4ClassRunner.java:108)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:31)
    at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:24)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
    at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
    at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:24)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)
Caused by: java.lang.NoClassDefFoundError: javax/servlet/ServletContext
    at org.springframework.test.context.web.WebDelegatingSmartContextLoader.<init>(WebDelegatingSmartContextLoader.java:36)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:148)
    ... 22 more
Caused by: java.lang.ClassNotFoundException: javax.servlet.ServletContext
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 28 more`enter code here`

Ok, Updated based on the comments, so I changed the scope to compile then it seems pass the issue of class not found!

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>compile</scope>
    </dependency>

It is a common issue. As Aniket Thakur said, the container will provide all Java servlet classes at runtime. But during the tests you need a jar to provide them.

The dependency you added to your pom is only the API : it declares everything but contains no implementation. So it will not help. Anyway, you declare it as "provided" which says to maven "don't worry, I know it will be on classpath".

You have to add a dependency that bring the implementation of all Java EE classes in test scope. In my projects I use glassfish even if I later use tomcat as a servlet container, but I once found the dependency googling for the same problem :

<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.servlet</artifactId>
    <version>3.0</version>
    <scope>test</scope>
</dependency>

It should solve your NoClassDefFoundError problem.

Class is not found at runtime but is available at compile time. You need to add the corresponding jar so that it can be found at runtime. I generally use Ivy and in Eclipse I do

Project -> Properties ->Deployment Assembly -> Add -> java Build Path Enteries -> Ivy -> Finish

There must be something similar for Maven as well.

Also you need javax.servlet-api only during compile time as the container you are using to run the server will provide the actual APIs at runtime.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM