How to migrate from Jersey 1 to Jersey 2 on Websphere

Hello Friends,

In this tutorial,we will see how to migrate from Jersey 1 to Jersey 2.

Here I am taking example of Jersey 1 version 1.18.3 and Jersey 2 version 2.23.2.


Jersey 1.18.3 dependencies 

                     <dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-bundle</artifactId>
<version>1.18.3</version>
</dependency>
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-spring</artifactId>
<version>1.18.3</version>
</dependency>
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-multipart</artifactId>
<version>1.18.3</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.9</version>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-xc</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.3</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
<version>1.9.3</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.18.3</version>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.1.1</version>

</dependency>

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>

Jersey 1.18.3 Web.xml configuration 

<?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 REST Service</servlet-name>
    <servlet-class>
      com.sun.jersey.spi.spring.container.servlet.SpringServlet
    </servlet-class>
    <init-param>
      <param-name>com.sun.jersey.config.property.packages</param-name>
      <param-value>com.test.rest</param-value>
    </init-param>
    <init-param>
      <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
      <param-value>true</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Jersey REST Service</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>

Jersey 2.23.2 Web.xml configuration 

<?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>

RestResourceIntializer.java

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 we would try to deploy this code with Jersey 2 Changes on Websphere(tried on 8.8.5),we 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.

How to resolve 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 ->  <ServerName> ->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

    


   In 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.



3. 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.

4. Restart Server and application should be up and running.

Thanks for reading.Please let me know,if you have any comments,feedback or query or suggestion on this post.