Jersey client 2.x or 1.x in our connectors?

Today I had a huge dilemma – should I use Jersey Client 2.x or 1.x in my connector? I need jersey client libraries in order to consume RESTful services from PayPal. I’ve spent couple of minutes wondering and calling different people. I couldn’t get a very clear answer. So I realized that I have to go under the hood if I want to give technical arguments for my choice. Note: sometimes even educated choices are wrong (smile)

Ok! API and implementation wise 2.x is definitely the better choice. I won’t argue why – anyone can google it. And yeah – if I ask my little daughter – version 2 or 1 – she would immediately recommend 2, simply because 2 is more than 1. Which makes lots of sense. Yet I chose 1.19. I’ll try to explain my arguments in this post.

JCP means Java Community Process. The JCP uses the so called Java Specification Requests (JSRs) on which interest groups work and vote. There are two JSRs I want to address:

  • JSR 311: JAX-RS: The JavaTM API for RESTful Web Services
  • JSR 339: JAX-RS 2.0: The Java API for RESTful Web Services

Okay, but what is JAX-RS? Wikipedia teaches: “JAX-RS: Java API for RESTful Web Services (JAX-RS) is a Java programming language API that provides support in creating web services according to the Representational State Transfer (REST) architectural pattern.”

I will risk to get criticized and I will dare to compare it with JDBC. We have an API (JAX-RS) and an implementation (Jersey). We have an API (JDBC) and an implementation (MySQL driver). Jersey 1.x is an implementation of JAX-RS 1 and Jersey 2.x is an implementation of JAX-RS 2. What is missing at JAX-RS 1 is the definition of Client API. E.g. there is no interface javax.ws.rs.client.Client. In other words there does not exist JAX-RS 1 compliant client implementation.

I cannot just add a dependency to jersey 2.x like this:

[code language=”groovy”] compile: org.glassfish.jersey.core:jersey-client
[/code]

That’s because I would need the interfaces in JAX-RS 2 to use it! Here is an example:

[code language=”java”] compile: org.glassfish.jersey.core:jersey-client
[/code]

In this example the interface Client belongs to the package javax.ws.rs.client and this package is of course not part of the jersey reference implementation in the same way in which ResultSet is not part of the MySQL JDBC driver. Okay, you may ask – why do not add this dependency to your build. It should be easy. Here we go:

[code language=”groovy”] ‘javax.ws.rs:javax.ws.rs-api:2.0.1’
[/code]

Unfortunately our core software uses JAX-RS 1. This is defined by the following dependency that you may have seen: compile ‘javax.ws.rs:jsr311-api’

If I have both dependencies in the same installation I’ll end up with two jars with some identical by name and package classes in my class-path (JAX-RS 1 and 2 interfaces contain some identical classes). And this is a situation that I really want to avoid.

That’s why I intend to stick with 1.x until we finally have the guts to migrate to JAX-RS 2.0. I may be wrong but at least I’ll be safe for the time being. I’ll follow your connectors too (smile).

Jersey client 2.x or 1.x in our connectors?