Spring 4.0 StandaloneMockMvcBuilder java.lang.NoClassDefFoundError: javax/servlet/SessionCookieConfig 問題解決


standaloneSetup(clrr).
        build();

執行第二行 build() 時,出現下面的錯誤提示。

java.lang.NoClassDefFoundError: javax/servlet/SessionCookieConfig
    at org.springframework.test.web.servlet.setup.StandaloneMockMvcBuilder.initWebAppContext(StandaloneMockMvcBuilder.java:329)
    at org.springframework.test.web.servlet.setup.AbstractMockMvcBuilder.build(AbstractMockMvcBuilder.java:127)
    at com.tony.springTest.HomeControllerTest.testHomeP(HomeControllerTest.java:34)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.lang.ClassNotFoundException: javax.servlet.SessionCookieConfig
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    ... 25 more

 

在 debug 模式下,可以知道 standaloneSetup(clrr) 得到的是 StandaloneMockMvcBuilder 對象和 exception 中報異常的類名一致。

在 Cannot create MockHttpSession with servlet 2.x, spring 得到下面有用提示:Spring 4.0 需要得到 servlet 3.0 或以上版本的支持。

The Servlet API mocks in Spring Framework 4.0 support Servlet 3.0 and higher, as can be seen inGitHub commit deba32cad9.

追蹤上面的 github 鏈接,可以發現 SessionCookieConfig 是在升級 servlet API 到 3.0 變動中新增的。

在查詢 SessionCookieConfig 文檔,可以知道 SessionCookieConfig 是在 servlet 3.0 才引入的。

 

反觀自己項目 pom.xml ,用的是 servlet 2.5 ,可以判斷得到,是自己項目引用的 servlet 版本過低導致的,需要升級到 3.0 或以上。

        <!-- Servlet -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>

 

變動 1 如下。 

        <!-- Servlet -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>

改動后,出現了新的兩個錯誤 : 

Missing artifact javax.servlet:servlet-api:jar: 3.0.1
Description    Resource    Path    Location    Type
The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path    home.jsp    /SpringTest/src/main/webapp/WEB-INF/views    line 1    JSP Problem
The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path    reg.jsp    /SpringTest/src/main/webapp/WEB-INF/views    line 1    JSP Problem
The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path    regSucess.jsp    /SpringTest/src/main/webapp/WEB-INF/views    line 1    JSP Problem
The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path    spittles.jsp    /SpringTest/src/main/webapp/WEB-INF/views    line 1    JSP Problem
HttpServlet 找不到是很不合理的,第一個錯誤表示無法找到 3.0.1 版本的 servlet 。

項目依賴是用 maven 管理的,通過 mvn clean,嘗試解決無法找到 3.0.1 servlet artifact 問題。命令如下:
$ cd {project folder}
$ mvn clean compile

 但是出現了新的錯誤: 

[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal on project springTest: Could not resolve dependencies for project com.tony:springTest:war:1.0.0-BUILD-SNAPSHOT: Failure to find javax.servlet:servlet-api:jar:3.0.1 in https://repo.maven.apache.org/maven2/ was cached in the local repository, resolution will not be reattempted until the update interval of maven.dev.snaponglobal.com has elapsed or updates are forced -> [Help 1]

錯誤提示 maven repository 無法找到需要的 3.0.1 servlet 。在 repository URL : https://repo.maven.apache.org/ 下面一級一級找,確實沒有 servlet 3.0.1 版本的 artifiact 。那么就需要給 maven 換一個有 3.0.1 servlet 的 repository 或者 mirror 。

在網上找到一個有效的 servlet 3.0.1 : http://repo1.maven.org/maven2/javax/servlet/javax.servlet-api/。

於是在 ~/.m2/setting.xml 中將 maven 的 mirror 改為 repo1 的 。如下:

    <mirrors>
       <mirror>
          <id>maven.dev.snaponglobal.com</id>
          <name>Internal Artifactory Maven repository</name>
          <url>http://repo1.maven.org/maven2/</url>
          <mirrorOf>*</mirrorOf>
       </mirror>
    </mirrors>

修改好 mirror 后,還是提示無法解決依賴的 3.0.1 servlet : 

Downloading: http://repo1.maven.org/maven2/javax/servlet/servlet-api/3.0.1/servlet-api-3.0.1.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.511 s
[INFO] Finished at: 2016-02-09T00:40:47+08:00
[INFO] Final Memory: 11M/245M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal on project springTest: Could not resolve dependencies for project com.tony:springTest:war:1.0.0-BUILD-SNAPSHOT: Could not find artifact javax.servlet:servlet-api:jar:3.0.1 in maven.dev.snaponglobal.com (http://repo1.maven.org/maven2/) -> [Help 1]

通過仔細對比錯誤提示的 URL 和 瀏覽器的 URL ,發現路徑有點不一樣。

錯誤提示的是 /servlet/servlet-api/ ,而瀏覽器的實際路徑為 /servlet/javax.servlet-api/ ,將 pom.xml 中的 artifactId 糾正過來就好了。糾正后配置如下 : 

        <!-- Servlet -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>

重新運行 mvn clean 后,可以成功下載 3.0.1 servlet 。然后運行 Spring 的 unit test 也沒也報錯。

問題解決完畢。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM