Reputation: 722
I am having a bit bizaare case of NoSuchMethodError, which only occurs when I run my tests from certain IDEs. What is more, despite of having possibility of clashing interfaces on my classpath (javax.servlet api 2 and 3, but I enforce 3), I have only one implementation (MockHttpServletResponse from spring-web-test 4.0.3), so no idea how this can be even happening.
I had some clashes with transitive dependencies, but they were all sorted out after implementing conflicts resolution strategies. On build server, local build from console and while launching tests manually from Eclipse Juno on my Windows machine everything is fine.
However when I launch it form IntelliJ (or Eclipse Luna on Linux) this:
(ServletServerHttpResponse$ServletResponseHttpHeaders.getFirst(String) line: 136 )
String value = servletResponse.getHeader(headerName)
ends up in this:
java.lang.NoSuchMethodError: javax.servlet.http.HttpServletResponse.getHeader(Ljava/lang/String;)Ljava/lang/String;
I can see that HttpServletResponse interface from javax.servlet.api 2 don't have getHeader method (version 3 does), so maybe this is the problem. BUT servletResponse is instance of org.springframework.mock.web.MockHttpServletResponse from spring web 4 and it DOES have this method! And as for interfaces everything is enforced, as per output from gradle dependencies:
+--- 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 (*)
Am I doing something wrong, or is it (yet) another problem of gradle integration with IDEs (which seems to be getting worse, not better :() . I am using version 1.9
Upvotes: 1
Views: 1332
Reputation: 722
Sigh, as usual, it turned out to be that nightmarish case, where the conflicting old class version was being pulled in from another artefact (with different name). I got transitive dependency on jetty 2, which was bringing undercover servlet api version 2. Java forever.
To solve this I added jetty group to my conflict resolution rule, which looks like that now:
// 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'
}
Funny thing is that IDE is still confused (i.e. if I try to use HttpServletResponse class directly, it complains), but the tests are now launching properly, without any errors. Good enough.
Upvotes: 1