NoSuchMethod错误仅在(某些)IDE中出现

时间:2014-12-09 17:21:01

标签: java eclipse spring intellij-idea gradle

我有一点奇怪的NoSuchMethodError案例,只有当我从某些IDE运行我的测试时才会出现这种情况。更有甚者,尽管有可能在我的类路径上冲突接口(javax.servlet api 2和3,但我强制执行3),我只有一个实现(来自spring-web-test 4.0.3的MockHttpServletResponse),所以不知道怎么会发生这种情况。

我与传递依赖关系发生了一些冲突,但在实施冲突解决策略后,它们都被整理出来了。在构建服务器上,从控制台进行本地构建,在我的Windows机器上从Eclipse Juno手动启动测试时,一切都很好。

然而,当我从IntelliJ(或Linux上的Eclipse Luna)启动它时:

(ServletServerHttpResponse $ ServletResponseHttpHeaders.getFirst(String)line:136)

String value = servletResponse.getHeader(headerName)

最终:

java.lang.NoSuchMethodError: javax.servlet.http.HttpServletResponse.getHeader(Ljava/lang/String;)Ljava/lang/String;

我可以看到来自javax.servlet.api 2的HttpServletResponse接口没有getHeader方法(版本3没有),所以这可能是问题所在。但是servletResponse是来自spring web 4的org.springframework.mock.web.MockHttpServletResponse的实例,它有这个方法!至于接口,根据gradle依赖项的输出强制执行所有内容:

 +--- javax.servlet:servlet-api:2.5 -> javax.servlet:javax.servlet-api:3.1.0
|    |    |         +--- org.mortbay.jetty:jetty:6.1.26 (*)
|    |    |         +--- org.mortbay.jetty:jetty-util:6.1.26
|    |    |         +--- com.sun.jersey:jersey-core:1.9
|    |    |         +--- com.sun.jersey:jersey-json:1.9
|    |    |         |    +--- org.codehaus.jettison:jettison:1.1
|    |    |         |    +--- com.sun.xml.bind:jaxb-impl:2.2.3-1 -> 2.2.6
|    |    |         |    +--- org.codehaus.jackson:jackson-core-asl:1.8.3 -> 1.9.13
|    |    |         |    +--- org.codehaus.jackson:jackson-mapper-asl:1.8.3 -> 1.9.13 (*)
|    |    |         |    +--- org.codehaus.jackson:jackson-jaxrs:1.8.3
|    |    |         |    |    +--- org.codehaus.jackson:jackson-core-asl:1.8.3 -> 1.9.13
|    |    |         |    |    \--- org.codehaus.jackson:jackson-mapper-asl:1.8.3 -> 1.9.13 (*)
|    |    |         |    \--- org.codehaus.jackson:jackson-xc:1.8.3
|    |    |         |         +--- org.codehaus.jackson:jackson-core-asl:1.8.3 -> 1.9.13
|    |    |         |         \--- org.codehaus.jackson:jackson-mapper-asl:1.8.3 -> 1.9.13 (*)
|    |    |         +--- com.sun.jersey:jersey-server:1.9
|    |    |         |    \--- asm:asm:3.1
|    |    |         +--- tomcat:jasper-compiler:5.5.23
|    |    |         +--- tomcat:jasper-runtime:5.5.23
|    |    |         |    +--- javax.servlet:servlet-api:2.4 -> javax.servlet:javax.servlet-api:3.1.0

+--- org.springframework:spring-web:4.0.3.RELEASE (*)

我做错了什么,或者它(还)是另一个与IDE集成的问题(这似乎越来越糟,不是更好:()。我使用的是版本1.9

1 个答案:

答案 0 :(得分:1)

像往常一样叹息,结果是那种噩梦般的情况,其中冲突的旧班级版本被另一个人工制品(不同的名字)拉进来。我得到了对jetty 2的传递依赖,它带来了秘密的servlet api版本2. Java永远。

为了解决这个问题,我将jetty组添加到我的冲突解决规则中,现在看起来像这样:

// Fix javax dependency
                if (dependency.requested.group in ["javax.servlet","org.mortbay.jetty"] && dependency.requested.name in ["servlet-api", "javax.servlet-api"]) {
                    dependency.useTarget 'javax.servlet:javax.servlet-api:3.1.0'
                }

有趣的是IDE仍然混淆(即如果我尝试直接使用HttpServletResponse类,它会抱怨),但测试现在正确启动,没有任何错误。够好了。