Thursday Oct 16, 2008

Jersey samples

The samples supplied with Jersey are on the java.net maven repository as a single zip file or individually (browse from here).

All the of samples are capable of being executed from the command line or from NetBeans 6.5 beta/dev build (with the maven plug-in configured to an external maven distribution version 2.0.9 or greater). Maven makes it easy to distribute the samples without redistributing third party dependencies, such as Grizzly, GlassFish embedded, Spring, and Scala, some of which can be rather large.

Some samples have unit tests that avail of the Jersey client API. This serves a number of purposes:

  • How to use the Jersey client API;
  • How to deploy in embedded scenarios using Grizzly and GlassFish;
  • How to develop functionality tests for resources using JUnit; and
  • Limit or remove manual testing of the samples.

We plan to automate the testing of all samples and from this experience we plan to create a useful JAX-RS/Jersey testing framework that is capable of abstracting from the actual HTTP container used to deploy resource classes. The ultimate goals are to make it easier to test and to automate everything so that we can test continuously via Hudson. Potentially we can then spin stable releases as fast as Hudson slaves can test.

A sample i particularly like and i recently added is Sparklines, which was inspired by Joe Gregorio's Sparklines service and python implementation. Sparklines, "as defined by Tufte, are intense, simple, word-sized graphics".

Here is a snippet of the Sparklines resource class:

@Path("/")
@Produces("image/png")
public class SparklinesResource {
    List<Integer> data;

    @DefaultValue("20") @QueryParam("height") int imageHeight;

    Interval limits;

    EntityTag tag;

    public SparklinesResource(
            @QueryParam("d") IntegerList data,
            @DefaultValue("0,100") @QueryParam("limits") Interval limits,
            @Context Request request,
            @Context UriInfo ui) {
        if (data == null)
            throw new WebApplicationException(400);
        
        this.data = data;
        
        this.limits = limits;

        if (!limits.contains(data))
            throw new WebApplicationException(400);

        this.tag = computeEntityTag(ui.getRequestUri());
        if (request.getMethod().equals("GET")) {
            Response.ResponseBuilder rb = request.evaluatePreconditions(tag);
            if (rb != null)
                throw new WebApplicationException(rb.build());
        }
    }

Besides being a fun application with a practical use it uses a whole bunch of JAX-RS features in one Java class: query parameter with default values, application-specific classes for query parameters, parameters on fields, throwing exceptions in constructors, and preconditions where entity tags are generated from the information in the request URI.

For those wanting to move beyond 1.0 i have just added a simple Groovy sample to the 1.0.1-SNAPSHOT. It needs to be improved and I ain't that familiar with Groovy so if any one wants to contribute something more substantial to show off Groovy, JAX-RS and Jersey let me know.

And... on a tangential topic related to languages i have been taking a little look at Clojure. There is a very thought provoking presentation on line. For those of us not that familiar Lisp the syntactical "explosion" of braces of Clojure can be a bit overwhelming compared to Java at first, but, if one looks at Clojure's Java interoperation and then compares Clojure code with Java code with the following consideration, think of curly braces as just braces, then the Clojure syntax is OK and can be very conscise yet still readable, and it is often just the order of where "." and braces occur that changes. I also took a little look at the code, for what Clojure does the set Java code is rather small, often strange (as Rich Hickey says he tries to apply functional idioms to Java code), and has some very interesting implementatons of persistent (in the functional sense) data structures.

Tuesday Oct 30, 2007

Annotated Scala, Groovy, JRuby, Rhino, Jython ...

Java runtime annotations are stored in Java bytecode using attributes, as specified by the Java virtual machine specification. So one can use toolkits like the ASM toolkit for creating and reading annotations in addition to using the Java reflection API for reading annotations.

Implementations of languages that compile to Java bytecode can also leverage runtime annotations and it can make for really smooth integration between classes/objects written in the language and frameworks, such as Jersey (JAX-RS), Metro (JAX-WS, JAXB), JUnit and Spring etc. written in Java, that process annotations.

So what's the support for runtime annotations like out there for some common JVM-based language implementations?

Scala

Scala has by far the most robust support for annotations. The annotation syntax is very similar to Java. JAX-RS and Jersey specify support for runtime annotations on classes, fields, methods and method parameters. I can annotate Scala classes using JAX-RS annotations and the Jersey runtime correctly processes the thoses classes (as shown here). In fact since the integration between Java and Scala is so smooth and Scala being such a pleasurable language to code in i could not resist including in the Jersey distribution an example written in Scala.

Groovy

Groovy 1.1 supports runtime annotations and like Scala the syntax is very similar to Java. Originally i played around with Jersey and Groovy 1.1 Beta. This version supported annotations on classes, method and field but not on method parameters. Recently downloaded Groovy 1.1 RC 1 and this version supports annotations on method parameters. So i can annotate Groovy classes and support all the Jersey features as i can in Scala (Groovy 1.1 is not yet final where as Scala 2.6 is so Scala's support is considered more robust). Since Groovy requires no compile step i can script Jersey resources (more on this later in another blog).

JRuby (Ruby)

Now things start to get a little fuzzy. My understanding is Ruby does not currently support annotations but that it is very easy to do so because of Ruby's meta-programming capability, as shown here. Charles Nutter (one of the JRuby leads) says here:

"JRuby doesn't support annotations because Ruby doesn't support annotations. So what! We can extend Ruby..."

and further says "I've planted the seed here and on the JRuby dev list...let's see if it germinates.", but i don't know if that seed has taken root...

Rhino (JavaScript)

JavaScript is in a similar position to JRuby, annotations can be added to JavaScript using meta-programming techniques, as shown here.

Rhino has the ability to integrate with Java such that a JavaScript object can implement one or more Java-based interfaces or extend a Java class. However, it does not seem possible to implement a (plain old) JavaScript object and pass it over to the Java side as a (plain old) Java object. Intuitively this would seem possible given the existing support. It looks like the Rhino source code is still being worked on even though the last release (1.6R7) was over a year ago. That's good. So i took a look at the code, specifically the JavaAdaptor and ClassFileWriter classes.

Now i may not know what i am getting into here, i could be pulling on a thread connected to a really big hair ball, it appears "tricky but doable". Once that is done it is just a simple matter of mapping the annotations declared in the JavaScript to equivalent byte code... anyone up for a challenge?

Jython (Python)

Python has function decorators in Python 2.4, function annotations and class decorators implemented in the subversion repository of python 3.0 (or Python 3000, it says here that it will go final in August 2008). So perhaps Python 3000, when it is ready, would be the right place to start any Java-based annotation support.

The latest stable release of Jython is version 2.2.1 supporting Python 2.2. From the roadmap Jython 2.5 is next (no date given) and this release will target Python 2.5. It says the core developers will be:

"concentrating on making a clean 2.5, while improving the java integration"

So maybe something specific to Jython w.r.t. to annotation support could be implemented. Although the Jython roadmap looks on the right track i suspect the 2.5 release won't be happening any time soon and the 3.0 release is way over the horizon. However, the competition between language implementations is in rude health so perhaps things will zip along faster than I expect.

Friday Jun 29, 2007

Resourcegroovy

The following is a resource written in Groovy using Jersey and the 311 API:

@UriTemplate("/test")
@ProduceMime(["text/html"])
public class MyResource {

    @HttpContext UriInfo uriInfo;
    
    @HttpMethod
    def getString() {
        def writer = new StringWriter()         
        def html = new MarkupBuilder(writer)
        html.html {
            head {
                title("Groovy resource with 311 and Jersey")
            }
            body {
                h1("URI: " + uriInfo.getURI())
            }
        }
        return writer.toString()
    }

    @UriTemplate("subresource")
    @HttpMethod
    def getSubResourceString() {
        def writer = new StringWriter()         
        def html = new MarkupBuilder(writer)
        html.html {
            head {
                title("Sub-resource")
            }
            body {
                h1("URI of sub-resource: " + uriInfo.getURI())
            }
        }
        return writer.toString()
    }
}

Groovy 1-1-beta-1 supports Java annotations on classes, fields and methods, but not yet on method parameters (I could not get it to work so that the field uriInfo is an annotated method parameter instead). The above example combines 311 annotated methods with the Groovy markup builder to spit out HTML.

I wrote another Groovy class to deploy MyResource using the Light Weight HTTP server:

 public class Main {
    static void main(String[] args) {
        def handler =  ContainerFactory.createContainer(

            HttpHandler.class, 
            MyResource.class);
        def server = HttpServer.create(

            new InetSocketAddress(9998), 0);
        server.createContext("/service", handler);
        server.setExecutor(null);
        server.start();
        System.in.read();
    }
}

So just like with Scala it is possible to use Jersey with Groovy on the Java Virtual Machine.

About

sandoz

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today