Description
Using Jersey for the REST layer in a project, I've got a dependency conflict when using Spring Cloud as follow:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>Brixton.M4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-security</artifactId>
<scope>runtime</scope>
</dependency>
The Spring Boot Jersey dependency org.springframework.boot:spring-boot-starter-jersey:jar:1.3.2.RELEASE is used.
The error is
java.lang.NoSuchMethodError: javax.ws.rs.core.Application.getProperties()Ljava/util/Map;
at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:331) ~[jersey-server-2.22.1.jar:na]
at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:390) ~[jersey-container-servlet-core-2.22.1.jar:na]
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:172) ~[jersey-container-servlet-core-2.22.1.jar:na]
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:364) ~[jersey-container-servlet-core-2.22.1.jar:na]
at javax.servlet.GenericServlet.init(GenericServlet.java:158) ~[tomcat-embed-core-8.0.30.jar:8.0.30]
and it comes from the fact that both
javax.ws.rs:javax.ws.rs-api:jar:2.0.1:compilejavax.ws.rs:jsr311-api:jar:1.1.1:runtimeare present in the classpath.
spring-cloud-starter-zuul includes jsr311-api.jar from its ribbon-httpclient dependency
+- com.netflix.ribbon:ribbon-httpclient:jar:2.1.0:compile
[INFO] | | | +- com.sun.jersey:jersey-client:jar:1.19:runtime
[INFO] | | | | \- com.sun.jersey:jersey-core:jar:1.19:runtime
[INFO] | | | | \- javax.ws.rs:jsr311-api:jar:1.1.1:runtime
[INFO] | | | \- com.sun.jersey.contribs:jersey-apache-client4:jar:1.19:runtime
I solved it by excluding jersey-client like this
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>Brixton.M4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
<exclusions>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-apache-client4</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-security</artifactId>
<scope>runtime</scope>
</dependency>
It works when testing Zuul manually but I'm not sure it would under all conditions.
It's heavy handed but I figure I already have a much newer jersey client org.glassfish.jersey.core:jersey-client:jar:2.22.1:compile included with Spring Boot Jersey.
Why would ribbon use older Jersey client dependency? Is there any reason it wouldn't work with the newest org.glassfish.jersey.core:jersey-client:jar:2.22.1 ??