Jersey

From APIDesign

(Difference between revisions)
Jump to: navigation, search
Current revision (04:44, 15 March 2017) (edit) (undo)
 
(29 intermediate revisions not shown.)
Line 1: Line 1:
-
[http://jersey.dev.java.net/ Jersey], a [[wikipedia::Reference implementation (computing)|reference implementation]] of JAX-RS ([[wikipedia::Java Community Process|JSR]] 311), intended for building [[wikipedia::Representational State Transfer|RESTful]] [[wikipedia::Web service|Web service]]s. I was impressed by the framework and decided to build my project on it. Time has however come to ask whether it was a [[good]] choice. Is [[Jersey]] [[good technology]]?
+
[http://jersey.dev.java.net/ Jersey], a [[wikipedia::Reference implementation (computing)|reference implementation]] of [[JAX-RS]] ([[wikipedia::Java Community Process|JSR]] 311), intended for building [[REST]]ful [[wikipedia::Web service|Web service]]s. I was impressed by the framework and decided to build my project on it in 2009. Now it is 2012 and time has come to ask whether it was a [[good]] choice. Is [[Jersey]] a [[good technology]]?
 +
 
 +
 
 +
Now it is 2017 and [[I]] needed [[REST]] again. My obvious choice was [[Jersey]]. This time [[I]] started with version 2.3 and my [[JerseyInjection|experience]] is much better. Thus read the rest of this page as a view of a poor user who had to survive [[Big Bang]] upgrade from version 1.x to 2.x once, but otherwise is [[JerseyInjection|relatively happy]] [[Jersey]] user.
== [[REST]] is Cool! ==
== [[REST]] is Cool! ==
-
There are three parts that make a technology [[good]]. Coolness being one of them. [[REST]] has been cool for few years. [[JAX-RS]] is cool as its [[Java]] realization. [[Jersey]] is the reference implementation of [[JAX-RS]]. All of this makes it very easy to choose [[Jersey]] as your technology (not counting the fact that most of the team that develops it sits one from above my office).
+
There are three parts that make a technology [[good]]. Coolness being one of them. [[REST]] has been cool for few years. [[JAX-RS]] is cool as its [[Java]] realization. [[Jersey]] is the reference implementation of [[JAX-RS]]. All of this makes it very easy to choose [[Jersey]] as a base technology (not counting the fact that most of the team that develops it sits one floor above my office).
 +
 
 +
== [[REST]] is Flexible ==
 +
 
 +
It is easy to enhance [[Jersey]] from/to [[JSON]] convertors. As an author of a lightweight [[Java]] from/to [[JSON]] mapping I [[JSON4Jersey|donated it]] to the project. Now everyone can use the same mapping (see [[JSON4Jersey]]) on server as well as tiny [[Java]] clients.
== No web.xml ==
== No web.xml ==
-
The other part of [[good technology]] is ''time to market''. [[Jersey]] delivers acceptable results in this respect as well. As being long time [[Java]] SE guys, I especially like the fact that [[Jersey]] can run outside of any web container like [[Tomcat]] or [[Glassfish]]. I am afraid of ''web.xml'' and disgusted when I have to touch it. With [[Jersey]] I could get my server up and running without paying attentiong only to what was important to me - the methods annotated with '''@GET''' and '''@POST'''.
+
The other part of [[good technology]] is ''time to market''. [[Jersey]] delivers acceptable results in this respect as well. As being long time [[Java]] SE developer, I especially like the fact that [[Jersey]] can run outside of any web container like [[Tomcat]] or [[Glassfish]]. I am afraid of ''web.xml'' and disgusted when I have to touch it. With [[Jersey]] I could get my server up and running without paying attentiong only to what was important to me - the methods annotated with '''@GET''' and '''@POST'''.
-
[[Jersey]] also comes with a special testing framework which makes the process of testing [[REST]] application relatively easy. This is [[good]] for time to market as well, as these days people want to ensure the [[amoeba]] shape of they application with bunch of tests before they release.
+
[[Jersey]] also comes with a special testing framework which makes the process of testing [[REST]] application relatively easy. This is [[good]] for time to market as well, as these days people want to ensure the [[amoeba]] shape of their application with bunch of tests before they release.
''Time to market'' is [[good]] with [[Jersey]].
''Time to market'' is [[good]] with [[Jersey]].
Line 15: Line 22:
== No Server Side Push ==
== No Server Side Push ==
-
In 2009 I could confirm that I like the [[Jersey]] framework a lot. There was just one thing I was missing. As I am using [[Jersey]] to implement a board like game server, I'd like to notify the clients about changes made to the board as soon as they happen. I needed server side push like [[wikipedia:http://en.wikipedia.org/wiki/Comet_(programming)|Comet] computation model.
+
In 2009 I could confirm that I like the [[Jersey]] framework a lot. There was just one thing I was missing. As I am using [[Jersey]] to implement a board like game server, I'd like to notify the clients about changes made to the board as soon as they happen. I needed server side push like [[wikipedia:http://en.wikipedia.org/wiki/Comet_(programming)|Comet]] computation model.
 +
 
 +
For two years I've been chatting with the [[Jersey]] guys and got promise they will implement it. I was patient, in spite of having a feeling there are other implementations of [[JAX-RS]] out there, that already support server side push.
 +
 
 +
However, you know how it is, people are lazy and rewriting to a different implementation seemed like too much work. In spite the base [[API]] is the same (e.g. [[JAX-RS]]) the devil lays in details. All the configuration and additional [[API]]s around just convinced me to wait.
== Upgrade to 2.0 ==
== Upgrade to 2.0 ==
-
For two years I've been chating with the [[Jersey]] guys and got promise they will implement it. I was patient and the time has come. [[Jersey]] 2.0m3 was announced and it was the time to make the switch! But that has been the beggining of the nightmare!
+
I was patient and my time has come. [[Jersey]] 2.0m3 was announced with support for '''@Suspend''' and it was
 +
the time to make the switch!
 +
 
 +
I understand that '''m3''' is just a milestone and things can be improved before final '''2.0''' release is out. As such following critique may be premature. Should however the upgrading experience stay the same in '''final 2.0''', following is what I'd have to say:
 +
 
 +
After trying to migrate from ''1.6'' version to ''2.0m3'' it is hard to say much [[good]] about [[Jersey]]. As the library user I feel disappointed and betrayed.
=== The Code ===
=== The Code ===
 +
One would expect that upgrading a dependency on [[Jersey]] is as easy as going to ''pom.xml'' of my project and replacing '''1.6''' with '''2.0m3'''. You would be surprised, it is not like that at all. It is much more painful.
 +
First of all, there no version '''2.0m3''' offered in the list of available versions. OK, I thought, maybe it is because it is not yet stable version. But then I realized that the version is available, but with completely different group and artifact identifiers. Instead of ''com.sun.jersey'' one needs to use ''org.glassfish.jersey.core'' or ''org.glassfish.jersey.containers'' or ''org.glassfish.jersey.media''.
-
I've just got a little bit of time to migrate my project from [[Jersey]] 1.1 to 2.0. It is not easy at all! It is painful. For last two years, I've been waiting for support for asynchronous [[wikipedia::Representational State Transfer|REST]] communication (as I am trying to write a chess-like server). I've been waiting, waiting. The result? Complete disappointment. I've just tried to run my old code on [[Jersey]] 2.0 (without trying any new features), but it does not even compile!
+
Looks like the [[Jersey]] team will now more closely work with rest of [[Glassfish]]. Good for them. Bad for poor users like me! Renaming widely used library just because you are now part of another organization is not user friendly. Compare with [[Hudson]] or [[JNA]] which both keep their original packages in spite being part of [[Eclipse]] foundation or in the case of [[JNA]] keeping ''com.sun'' prefix, in spite no longer being maintained by anyone with relation to [[Sun]]/[[Oracle]].
-
The guys that produce [[Jersey]] as sitting a floor up from my office, for two years I've been asking them for asynchronous support and waiting (instead of switching to alternative implementations of [[wikipedia::Java Community Process|JSR]] 311 - - as [[wikipedia::Java Community Process|JSR]] 311 is one of the specifications with most implementations). What I got for being a loyal user? I got a [[Big Bang]] rewrite. Imports changed, code changed, some classes are missing, concepts are different. Well, being treated this way, I have little intention to upgrade. Why should I spend time upgrading to [[Jersey]] 2.0, when it seems as much work as switch to XYZ (which had asynchronous support for ages)?
+
However my [[Jersey]] struggle was not over. Not only I needed to change the library names. Not only I had to rename imports of packages all over the code base (like ''com.sun.jersey.api.json.JSONWithPadding'' to ''org.glassfish.jersey.media.json.JsonWithPadding''), but I had to really change the code! Concepts are different. For example instead of
 +
 
 +
<source lang="java">
 +
ResourceConfig rc = new PackagesResourceConfig("cz.xelfi.quoridor.webidor");
 +
HttpServer server = GrizzlyServerFactory.createHttpServer(baseUri, rc);
 +
</source>
 +
 
 +
I had to invent following code:
 +
 
 +
<source lang="java">
 +
ResourceConfig rc = ResourceConfig.builder().
 +
packages("cz.xelfi.quoridor.webidor").build();
 +
HttpServer server;
 +
server = GrizzlyHttpServerFactory.createHttpServer(
 +
baseURI,
 +
Application.builder(rc).build()
 +
);
 +
</source>
 +
 
 +
I am not sure if the above is the right replacement (see next section), but it is the simplest code I could find that promises to do the same as the original one. But the primary question remains: Why I need to change my code at all!?
 +
 
 +
Some people believe that when doing [[Big Bang]] rewrite, it is better to do it as big as possible. Cleaning up names of classes and changing calling flow for sake of something. I can't find anyting [[good]] on such approach. It hurts ''total cost of ownership'' and clearly shows that the library authors don't care about users of previous version of their library.
=== The Test Framework ===
=== The Test Framework ===
 +
However bad the treatment described above is, there is something even worse: upgrading the tests is even more difficult. After a bit of searching I found the group and artifact id where '''JerseyTest''' lives, but then I realized that it has been changed significantly!
 +
 +
Methods are returning different parameters (like ''configure()'') and it is not easy to find a replacement. Some methods don't even exists (for example ''resource()'') and the original return type is not even in the [[API]]! As a result my tests are full of errors and I don't have a slightest idea how to fix them.
 +
 +
In many projects tests are the glue that holds the whole project together. They contain the knowledge what the project should do. Without them the project shakes like [[amoeba]]. I no longer remember what exactly the code should do, during last two years I was doing something else (moreover I admit, I am [[clueless]]), but that is the primary reason I write tests: to let them remember instead of me!
 +
 +
If you say that I have to rewrite all my tests before I can switch to [[Jersey]] 2.0, it is like suggesting me to start from scratch!
== [[Big Bang]] ==
== [[Big Bang]] ==
-
Looks like some people really believe that [[Big Bang]] is natural part of software developement. Well, I don't. I want the [[Jersey]] team to write a compatibility bridge to guarantee I can just change the [[Jersey]] version and everything will continue to work. I am afraid I am not going to get any support like that. In such case, farewell, as I bet on [[Good|bad horse]]. Projects that don't preserve investments of their users should be damned.
+
Should the upgrade experience from [[Jersey]] 1.x to '''2.0 final''' remain the same as to ''2.0m3'', then I would have to say:
 +
 
 +
Looks like some people really believe that [[Big Bang]] is natural part of software developement. Well, I don't. I want to reuse libraries that lower ''total cost of ownership''. I am too old to rewrite my code again and again every few years.
 +
 
 +
Asking me to fix imports just because the team has joined another organization or to fix code because some concept ''polished and improved'' is only punishing me for trusting the project at all.
 +
 
 +
Breaking all the tests is even worse. It is a clear message: start from scratch! And now tell me, why should I (when starting from scratch) trust such project once again? I've already learned my lesson by betting on [[good|dead horse]]. I know the project does not care about ''total cost of ownership'' of its users.
 +
 
 +
If [[Jersey]] '''2.0 final''' continues the trend, is not it the right time to switch to competition?
 +
 
 +
== Suggestions? ==
 +
 
 +
Migration guide (as drafted [http://jersey.java.net/nonav/documentation/snapshot/migration.html here]) may mitigate some of the biggest issues. For example it explains where have all the '''WebResource'''s gone...
 +
 
 +
<comments/>
[[Category:APIDesignPatterns:Anti]]
[[Category:APIDesignPatterns:Anti]]

Current revision

Jersey, a reference implementation of JAX-RS (JSR 311), intended for building RESTful Web services. I was impressed by the framework and decided to build my project on it in 2009. Now it is 2012 and time has come to ask whether it was a good choice. Is Jersey a good technology?


Now it is 2017 and I needed REST again. My obvious choice was Jersey. This time I started with version 2.3 and my experience is much better. Thus read the rest of this page as a view of a poor user who had to survive Big Bang upgrade from version 1.x to 2.x once, but otherwise is relatively happy Jersey user.

Contents

REST is Cool!

There are three parts that make a technology good. Coolness being one of them. REST has been cool for few years. JAX-RS is cool as its Java realization. Jersey is the reference implementation of JAX-RS. All of this makes it very easy to choose Jersey as a base technology (not counting the fact that most of the team that develops it sits one floor above my office).

REST is Flexible

It is easy to enhance Jersey from/to JSON convertors. As an author of a lightweight Java from/to JSON mapping I donated it to the project. Now everyone can use the same mapping (see JSON4Jersey) on server as well as tiny Java clients.

No web.xml

The other part of good technology is time to market. Jersey delivers acceptable results in this respect as well. As being long time Java SE developer, I especially like the fact that Jersey can run outside of any web container like Tomcat or Glassfish. I am afraid of web.xml and disgusted when I have to touch it. With Jersey I could get my server up and running without paying attentiong only to what was important to me - the methods annotated with @GET and @POST.

Jersey also comes with a special testing framework which makes the process of testing REST application relatively easy. This is good for time to market as well, as these days people want to ensure the amoeba shape of their application with bunch of tests before they release.

Time to market is good with Jersey.

No Server Side Push

In 2009 I could confirm that I like the Jersey framework a lot. There was just one thing I was missing. As I am using Jersey to implement a board like game server, I'd like to notify the clients about changes made to the board as soon as they happen. I needed server side push like Comet computation model.

For two years I've been chatting with the Jersey guys and got promise they will implement it. I was patient, in spite of having a feeling there are other implementations of JAX-RS out there, that already support server side push.

However, you know how it is, people are lazy and rewriting to a different implementation seemed like too much work. In spite the base API is the same (e.g. JAX-RS) the devil lays in details. All the configuration and additional APIs around just convinced me to wait.

Upgrade to 2.0

I was patient and my time has come. Jersey 2.0m3 was announced with support for @Suspend and it was the time to make the switch!

I understand that m3 is just a milestone and things can be improved before final 2.0 release is out. As such following critique may be premature. Should however the upgrading experience stay the same in final 2.0, following is what I'd have to say:

After trying to migrate from 1.6 version to 2.0m3 it is hard to say much good about Jersey. As the library user I feel disappointed and betrayed.

The Code

One would expect that upgrading a dependency on Jersey is as easy as going to pom.xml of my project and replacing 1.6 with 2.0m3. You would be surprised, it is not like that at all. It is much more painful.

First of all, there no version 2.0m3 offered in the list of available versions. OK, I thought, maybe it is because it is not yet stable version. But then I realized that the version is available, but with completely different group and artifact identifiers. Instead of com.sun.jersey one needs to use org.glassfish.jersey.core or org.glassfish.jersey.containers or org.glassfish.jersey.media.

Looks like the Jersey team will now more closely work with rest of Glassfish. Good for them. Bad for poor users like me! Renaming widely used library just because you are now part of another organization is not user friendly. Compare with Hudson or JNA which both keep their original packages in spite being part of Eclipse foundation or in the case of JNA keeping com.sun prefix, in spite no longer being maintained by anyone with relation to Sun/Oracle.

However my Jersey struggle was not over. Not only I needed to change the library names. Not only I had to rename imports of packages all over the code base (like com.sun.jersey.api.json.JSONWithPadding to org.glassfish.jersey.media.json.JsonWithPadding), but I had to really change the code! Concepts are different. For example instead of

ResourceConfig rc = new PackagesResourceConfig("cz.xelfi.quoridor.webidor");
HttpServer server = GrizzlyServerFactory.createHttpServer(baseUri, rc);

I had to invent following code:

ResourceConfig rc = ResourceConfig.builder().
    packages("cz.xelfi.quoridor.webidor").build();
HttpServer server;
server = GrizzlyHttpServerFactory.createHttpServer(
    baseURI,
    Application.builder(rc).build()
);

I am not sure if the above is the right replacement (see next section), but it is the simplest code I could find that promises to do the same as the original one. But the primary question remains: Why I need to change my code at all!?

Some people believe that when doing Big Bang rewrite, it is better to do it as big as possible. Cleaning up names of classes and changing calling flow for sake of something. I can't find anyting good on such approach. It hurts total cost of ownership and clearly shows that the library authors don't care about users of previous version of their library.

The Test Framework

However bad the treatment described above is, there is something even worse: upgrading the tests is even more difficult. After a bit of searching I found the group and artifact id where JerseyTest lives, but then I realized that it has been changed significantly!

Methods are returning different parameters (like configure()) and it is not easy to find a replacement. Some methods don't even exists (for example resource()) and the original return type is not even in the API! As a result my tests are full of errors and I don't have a slightest idea how to fix them.

In many projects tests are the glue that holds the whole project together. They contain the knowledge what the project should do. Without them the project shakes like amoeba. I no longer remember what exactly the code should do, during last two years I was doing something else (moreover I admit, I am clueless), but that is the primary reason I write tests: to let them remember instead of me!

If you say that I have to rewrite all my tests before I can switch to Jersey 2.0, it is like suggesting me to start from scratch!

Big Bang

Should the upgrade experience from Jersey 1.x to 2.0 final remain the same as to 2.0m3, then I would have to say:

Looks like some people really believe that Big Bang is natural part of software developement. Well, I don't. I want to reuse libraries that lower total cost of ownership. I am too old to rewrite my code again and again every few years.

Asking me to fix imports just because the team has joined another organization or to fix code because some concept polished and improved is only punishing me for trusting the project at all.

Breaking all the tests is even worse. It is a clear message: start from scratch! And now tell me, why should I (when starting from scratch) trust such project once again? I've already learned my lesson by betting on dead horse. I know the project does not care about total cost of ownership of its users.

If Jersey 2.0 final continues the trend, is not it the right time to switch to competition?

Suggestions?

Migration guide (as drafted here) may mitigate some of the biggest issues. For example it explains where have all the WebResources gone...

<comments/>

Personal tools
buy