Imagine a bacon-wrapped Ferrari. Still not better than our free technical reports.
See all our reports

Easy JAX-RS with Jersey and JRebel

jaxteller

In a previous blog post, my colleague Simon Maple (voted the most handsome of Java Champions) provided an excellent walkthrough creating REST services with Pivotal’s Spring Boot. He also introduced JRebel which lets you view code changes instantly, really he’s quite a guy!

FOLLOW ALONG WITH JREBEL NOW

Jersey is the reference implementation of JAX-RS, the RESTful web service spec for Java, there are maven archetypes which make great examples. For this blog post, we’ll use the jersey-quickstart-webapp archetype from the catalog. You should be familiar with the typical maven project layout, and we’re left with a very simple RESTful web service that can be packaged as a war file and deployed with an app server, like tomcat or wildfly.

Our starting point MyResource.class contains a simple GET that returns plain text and specifies a PATH for the URI.

@Path("/myresource")
public class MyResource {
  @GET 
  @Produces("text/plain")
  public String getIt() {
    return "Hi there!";
  }
}

In our web.xml we specify the servlet mapping

<servlet-mapping>
  <servlet-name>Jersey Web Application</servlet-name>
  <url-pattern>/webresources/*</url-pattern>
</servlet-mapping>

First, let’s make sure we have JRebel installed in our IDE. JRebel is readily available in the plugin directory or marketplace for all three of the major IDEs: Eclipse, IntelliJ, and NetBeans. Simply install it, restart your IDE, and enable JRebel for your application server (usually just a checkbox is required).

You can verify that JRebel is running when you see the banner in the appserver console:

JRebel:  #####################################
JRebel:  
JRebel:  JRebel Agent 6.0.2 (201412191331)
JRebel:  (c) Copyright ZeroTurnaround AS, Estonia, Tartu.

And you can verify that JRebel is configured for your application by “monitoring” messages in the console as well:

JRebel: Directory '/path/to/workspace/jerseyblogpost/target/classes' will be monitored for changes.

Let’s do something simple like a normal text change, especially helpful for those typos that don’t cause compilation errors, but would definitely make a spell checker raise its eyebrows. If we notice the welcome message returned by the REST call:
jersey_post_1

Let’s fix that quick type from “theare” to “there”, just change the code and hit save. Then you can verify the new code was picked up by JRebel and reloaded into the JVM by looking at the text returned by the call and also the reload messages in the console:

JRebel: Reloading class 'com.zeroturnaround.jerseyblogpost.MyResource'.
JRebel-Jersey: Reloading Jersey configuration

jersey_post_2

So that was pretty cool, we were able to change the content of a REST endpoint, let’s add a new one too. Let’s create a new @Path mapping /newpath:

@GET
@Path("/newpath")
@Produces("text/plain")
public String getNewPath(){
  return "This is a new path!";
}

On a real application though, we may want to take some input and do something with it, so let’s use the JAX-RS QueryParam annotation and take in a name for a custom greeting and feed that into a new NameProcessor class.

Here’s the new method using the QueryParam annotation

@GET
@Path("/namepath")
@Produces("text/plain")
public String getTest(@QueryParam("name") String name){
  if (name != null) {
    return "Hey " + NameProcessor.processName(name);
  }
  return "Hey name";
}

and here’s the NameProcessor class’s processName method

public static String processName(String name) {
  return name.toUpperCase();
}

Remember, we won’t have to rebuild or redeploy and can just hit save and hit the URL in your browser. If we go to localhost:8080/jerseyblogpost/webresources/myresource/namepath?name=Adam
we see that everything works as expected:
jersey_post_3

and in the console we see:

JRebel: Reloading class 'com.zeroturnaround.jerseyblogpost.MyResource'.
JRebel-Jersey: Reloading Jersey configuration

To recap, we started a new project using a maven archetype for jersey, installed JRebel into our IDE, fixed a quick typo, added new paths, and even added a new class to process our input from the web and didn’t have to rebuild our entire app or even restart it thanks to JRebel.

If you have any questions you can find me on twitter at @akoblentz or leave a comment below!


SET UP JREBEL IN THE NEXT 10 MIN!

 

  • I know this is a pretty old post, but right now with Glassfish 4.1, I’m running some resources (it’s a maven web project) with its Jersey implementation, and it doesn’t reload method signature changes.

    To check that, I created a request filter @Provider that prints the requested method generic name, so for example, If I initially create a doGet() method annotated with @GET, in the filter I print the method generic name and shows “public void user.resources.UserResource.doGet()”

    If I change the method from doGet() to someGet(), I get a 500 error when calling the REST service, and the filter prints “public void user.resources.UserResource.doGet()” instead it should print “public void user.resources.UserResource.someGet()”

    So it means that JRebel does reload the class and methods, but doesn’t reload Jersey’s resource registry, so it’s of no use reloading a class if the JAX-RS annotations are not reloaded as well.

  • arhan

    Might be related to the version of Jersey in use. JRebel plugin for Jersey should force the framework to reload the annotations as well. If you could send the details about your environment along with the log file from the session, our engineers will definitely take a closer look why it didn’t work for you.

  • Ok I’m using Netbeans 8.0.2 on Mac OS X Yosemite latest and JRebel plugin 6.2.4, jdk8u60, the latest Glassfish 4.1 that you can download today on glassfish.org, it’s the full profile version tgz file, this Glassfish release contains Jersey version 2.10.4.
    My Glassfish installation also has XRebel setted up version 2.2.0, today 2.2.1 was released so I’ll probably update it right now.

    Where should I send you the logs to? I could even do a quick video showing you what’s going on

  • arhan
  • Anderson Vaz

    I’m facing the exactly same issue. My environment is closely like yours. Whenever I change a method signature, jrebel do reload the class but jersey still look for the older version. Do you managed to solve this problem?

  • Anderson Vaz

    I’m facing the exactly same issue. My environment is closely like yours. Whenever I change a method signature, jrebel do reload the class but jersey still look for the older version. Do you managed to solve this problem??

  • arhan

    Did you ask from support?

  • Anderson Vaz

    Nope. I’m using jrebel social, support applies to it?

  • arhan

    You report an issue, if it is a bug – it will be fixed. Simple :)

  • Anderson Vaz

    I will send an e-mail to them.
    Thanks!