【问题标题】:Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: javax/servlet/ServletContext构造函数抛出异常;嵌套异常是 java.lang.NoClassDefFoundError: javax/servlet/ServletContext
【发布时间】:2014-06-24 18:24:02
【问题描述】:

我正在尝试使用 MockMVC 设置 Junit 测试。

来自link - “要么不能使用 Servlet API,要么你需要在类路径中提供它”。

我在 pom.xml 中添加了以下内容,但没有用。有什么想法吗?

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

这是痕迹

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`

好的,基于cmets更新,所以我改变了编译范围,然后似乎通过了找不到类的问题!

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

【问题讨论】:

  • 检查是否正在下载 servlet 依赖项。尝试使用mvn dependency:copy-dependencies -Dclassifer=directory 将所有依赖项下载到一个单独的文件夹中,看看它们是否都成功了

标签: java spring junit


【解决方案1】:

这是一个常见的问题。正如 Aniket Thakur 所说,容器将在运行时提供所有 Java servlet 类。但在测试期间,您需要一个罐子来提供它们。

您添加到 pom 的依赖项只是 API:它声明了所有内容,但不包含任何实现。所以它不会有帮助。无论如何,您将其声明为“已提供”,这对 maven 说“别担心,我知道它会在类路径上”。

您必须添加一个依赖项,使所有 Java EE 类的实现都在 test 范围内。在我的项目中,即使我后来使用 tomcat 作为 servlet 容器,我也使用 glassfish,但我曾经发现依赖谷歌搜索同样的问题:

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

它应该可以解决您的NoClassDefFoundError 问题。

【讨论】:

  • 或者您可以将&lt;bean class="org.springframework.mock.web.MockServletContext"/&gt;添加到测试配置文件中。
【解决方案2】:

在运行时找不到类,但在编译时可用。您需要添加相应的jar,以便在运行时可以找到它。我通常使用 Ivy,在 Eclipse 中使用

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

Maven 也必须有类似的东西。

您还需要 javax.servlet-api 仅在编译期间,因为您用于运行服务器的容器将在运行时提供实际的 API。

【讨论】:

    猜你喜欢
    • 2017-11-07
    • 1970-01-01
    • 2016-12-23
    • 1970-01-01
    • 2013-05-31
    • 1970-01-01
    • 2013-05-09
    • 2016-02-09
    • 1970-01-01
    相关资源
    最近更新 更多