I'm trying to upgrade to Jersey 2.0 and I'm having a lot of trouble because the groupIds and artifactIds of Jersey have completely changed and I can't find a migration plan in the Jersey docs.
Here's what my pom.xml used to look like, and this compiled fine:
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.17</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.17</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server-linking</artifactId>
<version>1.17.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.17.1</version>
</dependency>
What should these be changed to? This unrelated StackOverflow question was somewhat helpful, but I'm having trouble finding things like where the @Ref
annotation moved to.
Update
- It seems that
@Ref
no longer exists or at least it's not mentioned in the documentation anymore. Now you use aUriBuilder
. - I found a very helpful section in the documentation that answers my maven issues.
- The
HTTPBasicAuthFilter
has been renamed toHttpBasicAuthFilter
. Notice the capitalization. Client client = Client.create();
has becomeClient client = ClientBuilder.newClient();
This:
String json = client .resource(getBaseUrl() + url) .accept(MediaType.APPLICATION_JSON_TYPE) .get(String.class);
has become
String json = client .target(getBaseUrl()) .path(url) .request(MediaType.APPLICATION_JSON_TYPE) .get(String.class);
You don't.
Jersey 2.0 is missing a lot of functionality from Jersey 1.0. Contrary to what the committers will tell you, some things are plain impossible to implement right now (e.g. Guice, Spring integration). Things appear to work on the surface, but once you dig in deeper you will find a lot of features are still broken.
Many of the 1.x plugins do not exist in 2.x, mainly because of the aforementioned breakage.
In light of this, I suggest a holding off on Jersey 2.x for the foreseeable future. Hopefully the committers will clean this up in the coming year.
It is pain in the neck I have to say. We are currently knee deep into migrating relatively large 3+ years old client-server project and boy do I want to bite my neck off. Hopefully we are at the end of the struggle... While there is a migration guide indeed it is not comprehensive by any means.
- UniformInterfaceException (and others) is no more.
Instead it is replaced by WebApplication exception and successors. There is not a word about that in the migration guide and this is very very important.
- JSON support
The migration guide says:
JSON Support has undergone certain changes in Jersey 2.x. The most visible difference for the developer is in the initialization and configuration.
In Jersey 1.x, the JAXB/JSON Support was implemented as a set of MessageBodyReaders and MessageWriters in the jersey-json module. Internally, there were several implementations of JSON to Object mapping ranging from Jersey's own custom solution to third party providers, such as Jackson or Jettison. The configuration of the JSON support was centralized in the JSONConfiguration and JSONJAXBContext classes.
Great. What if you have chosen the "Jersey's own custom solution" (which we did for whatever reason)? There is no alternative to that in jersey 2. I tried to produce the same JSON format using Jettison, Jackson and Moxy providers. I did not succeed. For reference, my unanswered question here: Jersey 2 JSON Jettison unwrapping root element
See the 1.x to 2.0 migration guide in the Jersey docs.
It looks like @InjectLink
is the replacement for @Ref
.
From that link, I was able to drop this into my pom.xml:
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-declarative-linking</artifactId>
<version>2.6</version>
</dependency>
and then I took an existing @Ref
and was able to drop in replace with @InjectLink
.
public Long id; // This id is referenced below in the link
@InjectLink(resource = FavoriteResource.class, method = "updateFavorites", bindings = {
@Binding(name = "listId", value = "${instance.id}")
})
public URI linkURI;
It looks like some of the JavaDocs from @Ref
are in @InjectLink
even, which would be further confirmation that it's the replacement:
/**
* ...
* @Ref(resource=SomeResource.class)
* @Ref(resource=SomeResource.class, bindings={
* @Binding(name="id" value="${instance.id}"}
* )
*/
EDIT:
Tricky stuff. I needed one more piece to make this work for me. In web.xml
,
I now have:
<servlet>
<servlet-name>jersey-servlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.mycompany.root</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>com.mycompany.root.web.filter.AuditResourceFilterFactory;com.mycompany.root.web.filter.OtherAuditResourceFilterFactory</param-value>
</init-param>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.mycompany.root.web.resource.config.CustomResourceConfig</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
and finally, CustomResourceConfig.java
looks like this
import org.glassfish.jersey.linking.DeclarativeLinkingFeature;
import org.glassfish.jersey.server.ResourceConfig;
public class CustomResourceConfig extends ResourceConfig {
public CustomResourceConfig() {
packages("org.glassfish.jersey.examples.linking");
register(DeclarativeLinkingFeature.class);
}
}
You can follow following steps for migration from Jersey 1 to Jersey 2 :
Add following dependencies in POM file : Jersey 2.23.2 dependencies
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>2.23.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring3</artifactId>
<version>2.23.2</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.23.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.23.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-entity-filtering</artifactId>
<version>2.23.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>2.23.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-common</artifactId>
<version>2.23.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.bundles.repackaged</groupId>
<artifactId>jersey-guava</artifactId>
<version>2.23.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.23.2</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.5.4</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>2.23.2</version>
</dependency>
<dependency>
<groupId>org.jvnet</groupId>
<artifactId>mimepull</artifactId>
<version>1.6</version>
</dependency>
Make Following entry in Web.xml :
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<servlet>
<servlet-name>jersey-servlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.jsg.resource.initializer.RestResourceInitializer</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping> '
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/myAppName</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
Write following code in RestResourceIntializer
package com.jsg.resource.initializer;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
public class RestResourceInitializer extends Application {
/**
* Gets the classes.
*
* @return the classes
*/
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<Class<?>>();
// Resources
classes.add(org.glassfish.jersey.jackson.JacksonFeature.class);
classes.add(org.glassfish.jersey.server.spring.scope.RequestContextFilter.class);
classes.add(org.glassfish.jersey.media.multipart.MultiPartFeature.class);
//Rest classes within Application.
classes.add(com.jsg.rest.AbcRestService.class);
classes.add(com.jsg.rest.CdeRestService.class);
return classes;
}
}
Now if you will deploy code with above changes on websphere,you will get following exception :
Caused by: java.lang.NoSuchMethodError: javax/ws/rs/core/Application.getProperties()Ljava/util/Map; at org.glassfish.jersey.server.ApplicationHandler.(ApplicationHandler.java:287) at org.glassfish.jersey.servlet.WebComponent.(WebComponent.java:311)
Reason for above exception is that,Websphere supports JAX-RS 1 implementation,however we are deploying Jersey 2 code which is Jax-rs 2 implementation.
Steps for resolving above exception:
So basically what we have to do is to force WebSphere to pick our Jersey 2 jars instead of default Jax-rs 1.We need to follow following steps for that
1) Disable in built JAX-RS by setting following JVM property to true
com.ibm.websphere.jaxrs.server.DisableIBMJAXRSEngine=true
This property can be set through admin console of WebSphere by going to Servers->All Server -> ->Server Infrastructure -> Java and Process Management ->Process Deifinition ->Additional Properties-> Java Virtual Machine ->Additional Properties-> Custom Properties
2) Create Isolated Shared Library having the Jersey 2 Jars and Spring 4 Jars Isolated shared library can be created through admin Console of Websphere by going to Environment-> Shared Libraries ->New
n the classpath box,we need to enter path of the folder on the server,where we have placed all Jersey 2 and Spring 4 Jars
/var/was/server2/jerseyLib1/spring-context-4.3.4.RELEASE.jar
/var/was/server2/jerseyLib1/spring-core-4.3.4.RELEASE.jar
/var/was/server2/jerseyLib1/spring-beans-4.3.4.RELEASE.jar
/var/was/server2/jerseyLib1/spring-aop-4.3.4.RELEASE.jar
/var/was/server2/jerseyLib1/spring-web-4.3.4.RELEASE.jar
/var/was/server2/jerseyLib1/spring-expression-4.3.4.RELEASE.jar
/var/was/server2/jerseyLib1/spring-bridge-2.5.0-b05.jar
/var/was/server2/jerseyLib1/hk2-locator-2.5.0-b05.jar
/var/was/server2/jerseyLib1/hk2-api-2.5.0-b05.jar
/var/was/server2/jerseyLib1/hk2-utils-2.5.0-b05.jar
/var/was/server2/jerseyLib/javax.inject-2.5.0-b05.jar
/var/was/server2/jerseyLib1/javax.annotation-api-1.2-b03.jar
/var/was/server2/jerseyLib1/javax.ws.rs-api-2.0.1.jar
/var/was/server2/jerseyLib1/jersey-client-2.23.2.jar
/var/was/server2/jerseyLib1/jersey-spring3-2.23.2.jar
/var/was/server2/jerseyLib1/jersey-container-servlet-core-2.23.2.jar
/var/was/server2/jerseyLib1/jersey-server-2.23.2.jar
/var/was/server2/jerseyLib1/jersey-common-2.23.2.jar
/var/was/server2/jerseyLib1/jersey-guava-2.23.2.jar
Also in class loading section ,select "use an isolated class loader for this shared library"
and then finally click on Apply and Ok and we are done with creation of isolated shared library.
Bind this isolated shared library with your application war file as follows in admin Console
a) Application -> All Applications -> Click on your application name b) Go to References -> Shared Library References -> Reference Shared Libraries ->select your application war(Not ear) and click ok. c) Select the library that we created in Step 2 in "Available" combo box on left side and put it on right side in "Selected" combo box and click ok. With this we have associated the isolated shared library with application war file.
- Restart Server and application should be up and running.
Reference with screenshots -> http://javasolutionsguide.blogspot.nl/2017/03/howtomigratefromjersey1tojersey2InWebsphere.html
来源:https://stackoverflow.com/questions/17098341/how-do-i-migrate-from-jersey-1-0-to-jersey-2-0