我有一点奇怪的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
答案 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类,它会抱怨),但测试现在正确启动,没有任何错误。够好了。