Monday, June 08, 2009

JAX-RS Hello World

[NOTE: All of my examples will use standalone services (not housed inside a container). The integration between Jersey and the Grizzly HTTP server makes this a snap]

So, what is the simplest, smallest hello world we can implement with JAX-RS? The Jersey site provides an example and it's surprisingly small. We will start with an example almost identical to the hello world example from the Jersey documentation and grow from there.

If we ignore the package statements and imports, there are two files of about ten lines each. The first one is our main class that starts up the service and generally gets things going. Later examples will show why this is it's own class separate from the rest of a service's implementation. Here's the class in its entirety:

package net.gilstraps.server;

import com.sun.grizzly.http.SelectorThread;
import com.sun.jersey.api.container.grizzly.GrizzlyWebContainerFactory;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class Main {

public static void main(String[] args) throws IOException {
Map<String,String> initParams = new HashMap<String, String>();
initParams.put( "com.sun.jersey.config.property.packages", "net.gilstraps.server" );
SelectorThread selector = GrizzlyWebContainerFactory.create( "http://localhost:9998/", initParams );
//noinspection ResultOfMethodCallIgnored
System.in.read();
threadSelector.stopEndpoint();
System.exit(0);
}

}

The code here is pretty easy to understand, so let's look at it. These two lines are a crucial part of configuring Jersey:

Map<String,String> initParams = new HashMap<String, String>();
initParams.put( "com.sun.jersey.config.property.packages", "net.gilstraps.server" );

With these lines, we tell Jersey which java packages should be examined at runtime to find classes which implement RESTful resources. We've specified that Jersey should look at the "net.gilstraps.server" package and examine the classes in that package to find ones which have JAX-RS annotations on them. Those annotations tell a JAX-RS implementation what resources each class serves up to clients and what URI's those resources have. There are also annotations for specifying which HTTP methods match up to which Java methods. We'll look at these shortly.

The next line actually instantiates the Grizzly HTTP server, telling it the base URI for all the URL's it should support and providing it with initialization parameters:

SelectorThread selector = GrizzlyWebContainerFactory.create( "http://localhost:9998/", initParams );

The call returns us a SelectorThread which represents the control object for the HTTP server. With the string "http://localhost:9998/", we are telling the service to use port 9998 of the host named 'localhost'. Grizzly has built-in knowledge of Jersey and our inclusion of the "com.sun.jersey.config.property.packages" parameter causes Jersey to used to provide the web service.

The remaining lines provide a simple means to shut down the service gracefully. The program reads input from System.in and then shuts things down cleanly. So if you run the program on a command line you can get it to shut down without killing it:

System.in.read();
threadSelector.stopEndpoint();
System.exit(0);

So, where is our cliched "hello world" resource? There is one more class used to implement our service, also quite small. Here it is:

package net.gilstraps.server;

import javax.ws.rs.Produces;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.swing.text.html.HTML;

@Path("/helloworld")
public class HelloWorldResource {
@GET @Produces("text/plain")
public String getClichedMessage() {
return "Hello Stage 1";
}
}

This class is almost a POJO (plain old Java object). It doesn't implement a particular interface, or extend a class. It has a very simple method ('getClichedMessage') that returns a regular Java string. How can this implement a hello world web service? The key to making it a JAX-RS resource class is the annotations. Let's examine each one:

@Path

The '@Path' annotation attached to the class itself tells a JAX-RS what URI or set of URIs this class serves. In this case, we are specifying just the URI of "/helloworld". Thus, with the base URI of "http://localhost:9998" we would access this resource via the URI "http://localhost:9998/helloworld".

@GET

The @GET annotation on a method tells JAX-RS that the Java method implements HTTP's GET verb (the verb your browser uses every time you visit a web page). So JAX-RS now knows that a client doing a GET of "http://localhost:9998/helloworld" should result in the 'getClichedMessage' method being invoked.

@Produces

The @Produces annotation tells JAX-RS that the MIME type of the resource returned by 'getClichedMessage' is "text/plan", which is the MIME type for a plain text document. We've aimed for a minimal service here, so we're going for the simplest type of resource we can. It's also possible to return other kinds of entities as the result of a request, and it's even possible to use separate conversion classes to convert different kinds of Java objects into particular kinds of response entities (like a JPEG image, for example). But this service just returns a text document.

At this point, JAX-RS knows everything it needs to know to support a client doing a GET on the resource identified by the URI "http://localhost:9998/helloworld". When we compile and run our service, it doesn't output anything at first. But if we open a browser and go to the URL, we see some output from Grizzly/Jersey:

Jun 12, 2009 9:02:51 PM com.sun.jersey.api.core.PackagesResourceConfig init
INFO: Scanning for root resource and provider classes in the packages:
net.gilstraps.server
Jun 12, 2009 9:02:51 PM com.sun.jersey.api.core.PackagesResourceConfig init
INFO: Root resource classes found:
class net.gilstraps.server.HelloWorldResource
Jun 12, 2009 9:02:51 PM com.sun.jersey.api.core.PackagesResourceConfig init
INFO: Provider classes found:

From this we can see that Grizzly brings Jersey in to handle the request we made with the browser. Jersey then scans for classes which serve up REST resources. It tells us that it found our class:

Jun 12, 2009 9:02:51 PM com.sun.jersey.api.core.PackagesResourceConfig init
INFO: Root resource classes found:
class net.gilstraps.server.HelloWorldResource

Even more interesting, the browser where we made the GET request gets the string that was returned from 'getClichedMessage' as the result of it's GET request:



And that's a simple 'hello world' implemented using JAX-RS with Jersey and Grizzly.

Tuesday, June 02, 2009

Setting up Jersey for use

If you use Maven you can use it to download Jersey and keep it up to date. There are links to the POM files on the getting started page. In particular, you need the jersey-server module, and the grizzly-servlet-webserver module. If you want to use WADL with JDK 1.5 you need the jaxb-impl module. If you are not using Maven, you need only a few JARs:

grizzly-servlet-webserver.jar
jersey-server.jar
jersey-core.jar
jsr311-api.jar
asm.jar

[NOTE: these projects are under active development, so you may find newer versions of these jars available]

As with using Jersey via Maven, if you want to use WADL with JDK 1.5, you need some additional jars:

jaxb-impl.jar
jaxb-api.jar
activation.jar
stax-api.jar

We will ignore WADL for now, which limits the required jars to just the first five. But in addition to the binaries, I prefer to have the sources and javadoc available, which makes the total number of jars 15 (a binary, source, and javadoc jar for each).

Once you have the JARs, configure your classpath or your IDE to include them in your project. You're then ready to write the obligatory 'hello world' program.

Wednesday, May 27, 2009

Exploring RESTful web services with JAX-RS and Jersey.

I've been reading about RESTful web services for a while now. The best book on the subject I've found is RESTful Web Services by Leonard Richardson and Sam Ruby. I've been reading this book for what seems like forever (a function of my life and available time, not the book). I'm getting close to done and have begun using Jersey, the reference implementation of the JAX-RS specification to experiment with building RESTful web services.

I really like Jersey. A big reason for that is because Jersey makes it straightforward to stand up a standalone RESTful service. And once you've done it once, standing up additional services is easy. Deploying services without a heavyweight container makes me happy. Containers were created in the early days of Java when Java's limitations made them necessary. Since then, they have taken on a life of their own. Yet, in today's world I think the container has outlived almost all of its purpose. It's disadvantages now outweigh the few remaining benefits.

In the coming months, I plan to explore how to build, deploy, replicate, secure, and evolve industrial-class services without a container. I think I will succeed, but who knows? Maybe I'll learn a bunch due to abject failures. Either way, it should be fun.

My next post will describe how you download all the various pieces needed to stand up a Jersey-based REST service. There aren't very many, and it doesn't take long. Stay tuned.

Wednesday, November 12, 2008

Everybody Needs Cron

I was looking at one of my daily emails from javablogs.com when I saw one entitled "Nobody should need cron". This struck me as rather naive, so I went over to read Odd Thesis's entry: Nobody Should Need Cron, hoping to learn what I've been doing wrong all these years.

I posted a comment on the blog which hasn't shown up yet. I'll recreate it here.

Trying to recreate cron in Java/Ruby is asking for trouble. Any real-world application will have activities which are hard or impossible to implement in Java or Ruby. They will be OS-specific, or low-level, or be needed to monitor the very container you are trying to run them from. They often need to be extremely robust (more robust than Java apps can be) in the face of very unusual conditions on the box (huge load, almost zero memory available, etc). Cron and OS-specific tools are well-suited to these situations. Java and Ruby are not.

I'm a software engineer who has been working with Java since 1.0 beta, and I find it a great development language (I'm less experienced with Ruby but it is nice also). But they are simply inappropriate replacements for cron.


I understand the desire to stay in the productive, known world of Java or Ruby. And for periodic tasks "within" the application, some sort of cron-like facility is a nice feature. But robust software systems that are resilient and handle 'unexpected' (i.e. difficult to handle) situations without simply falling over require developers to step outside the virtual machine and deal with the OS and hardware (and databases and filesystems and other software systems) that the virtual machine depends upon. For those watchdog or maintenance activities that have to occur outside the virtual machine, cron (or it's OS-specific equivalent) are indespensible.

If you really think you can build a non-trivial system without cron, you've failed to identify or are ignoring requirements which you must satisfy to make your system robust.

Thursday, September 11, 2008

Interface Chaining

I was recently talking with my friend Mark Volkmann about an application framework he was developing. The framework, named WAX, is a very nice Java API for writing out XML. Despite it's small size, it's much nicer than any other XML writing API I've ever seen and you should go check it out.

As part of the API, Mark implementing method chaining. This allows for very compact code that is still quite easy to read. For example, you could produce this XML:

<?xml version="1.0" encoding="UTF-8"?>
<car year="2008">
<model>Prius</model>
</car>

with just this code::

WAX wax = new WAX(WAX.Version.V1_0);
wax.start("car").attr("year", 2008)
.start("model" ).text( "Prius").close();

Much of the compactness comes from the fact that each method called returns the WAX object, allowing the developer to chain method calls together.

As we were discussing the code, the topic of incorrect ordering of calls came up. For example, what happens if you try to call the attr method to create an attribute after already creating some text inside the element with the text method?

Because WAX is a streaming API, you can't 'go back' and add an attribute in the start element tag after having already 'moved on' to putting text in the body of the element. For example, what if I tried to create an attribute to the model of the car after putting text in it, like this:

WAX wax = new WAX(WAX.Version.V1_0);
wax.start("car").attr("year", 2008)
.start("model" ).text( "Prius").attr( "trim", "GT" ).close();

WAX detects this situation and throws an exception at runtime, which it should do. But I'm a fan of static type checking. I love having tools do as much checking for me as possible. So I suggested to Mark that he create a set of interfaces. Each interface would contain only the methods that make sense at the current point in the output stream. This would allow the compiler to catch invalid method invocations. Even better, modern IDEs like IDEA would flag the method invocation visually even before compilation.

For example, if we arrange for the text method to return an interface which does not have an attr method, then the compiler will catch it and the IDE will flag the error visually. For example, in IDEA, the error is flagged like this:



Now we get the compactness of runtime exceptions (which Mark really likes) and static checking (which I really like). I did some looking around and couldn't find a design pattern that really fits. A number of people suggested that this was an example of a domain-specific language (DSL). But to my thinking, something that deserves the moniker of 'language' should be more involved than simply constructing some interfaces so that static checking is applied.

But whatever you call it, I think it's a useful design pattern than can be applied in other situations to make for clean, compact, yet statically checked APIs.

Thursday, July 17, 2008

Create inbox items in OmniFocus from the dashboard

I am a very heavy user of OmniFocus. It has many ways to enter information. For example, you can use the "Quick Entry Window", which is great for creating an item with a project, context, and optional description.



But sometimes I am not in OmniFocus and don't have any text selected. This means there is nothing for OmniFocus to treat as a clipping. As a result it won't bring up the quick entry window.

So, I wrote my first Dashboard widget. It has a text area where you type the text for your item and a "Send It" button. When you click the button or hit enter in the text area, a new item is sent to your inbox.



I submittted it to Apple for inclusion in their download area for dashboard widgets download site. Until it shows up there, you can get it directly from here.

[Updated 2008-07-17 21:05]

Someone pointed out that I had forgotten that there is a separate keystroke to bring up the quick entry window without having any text selected. This eliminates much of the purpose of this widget unfortunately, unless you spend a lot of time in the dashboard anyway. At least it was a good learning exercise... :-)

Monday, May 05, 2008

Groovy Type Handling is Broken

Here's a very simple Java program snippet:

List<Integer> list = new ArrayList<Integer>();
Collection<Integer> col = list;
list.add( 2 );
list.add( 1 );
list.add( 0 );
System.out.println( list );
col.remove( 0 );

Run this and you'll get what you'd expect. Before using the col reference to remove the integer/Integer with value 0 (zero), you see:

[2, 1, 0]

Then, after calling remove on the collection, we see the integer/Integer with value zero is gone (that's the one we said to remove):

[2, 1]

Groovy says that it allows you to use types and will honor them at runtime. But it doesn't.

Take the same snippet of code and run it as a Groovy script. Remember that the Collection interface has a remove method, and that method expects you to pass it an object which it will remove from the collection. So we would expect to see the same result as in Java. But we don't. Instead, we get this:

[2, 1, 0]
[1, 0]

Groovy has removed the Integer with a value of 2! It did this because of Groovy's 'multi-methods'. Groovy looked at the real type of col, which is an ArrayList. It then found a remove method that takes an integer/Integer. That method removes the Nth item from the list. It used that method and removed the zero-th item (the one with a value of 2).

But remember, I invoked the remove. method through the Collection interface. The collection interface does not have a method taking an integer/Integer but it does have a remove method taking the object to be removed!

This is a truly awful result. It removes our ability to reason about how code will behave by looking at the types involved. In order to know how this will behave, I cannot make any use of the type information; in fact the type information is downright misleading. Even worse, as the type system evolves and new classes are introduced, new methods with entirely different signatures may get invoked.

This approach to handling types is essentially broken. The claim that Groovy honors types (even the weakened form of honoring it by doing casts at runtime) is flat out wrong.

Groovy needs to either start honoring type information, or get rid of it.

Thursday, April 24, 2008

Insidious Coupling

This will get to the topic of code coupling soon enough, but bear with me for a bit of background.

I like to use the 'fail fast' approach to my code. This means that invalid inputs cause a failure in the code as quickly as possible. Perhaps the simplest example of this in the JDK is the collections classes, whose iterators fail as soon as they detect that the underlying collection object has been modified. This allows them to avoid synchronization costs while also detecting unsafe usage.

In my own code, the most common situation where I find fast-fail code is in constructors. If an argument the constructor cannot be null (either because it will be used in the constructor, saved to a field, or both), I check that the object reference is not null. For example:

public class Foo {
// ...
public Foo( Bar b ) {
// Check that b is not null
// rest of constructor...
}
}

I started out performing this check with an if statement:

public class Foo {
// ...
public Foo( final Bar b ) {
if ( b == null ) {
throw new IllegalArgumentException( "Bar b cannot be null" );
}
// rest of constructor...
}
}

This gets us a pretty understandable stack trace:

Exception in thread "main" java.lang.IllegalArgumentException: Bar b cannot be null
at org.sandbox.Foo.(Foo.java:10)
at org.sandbox.SimpleDoesStuff.doIt(SimpleDoesStuff.java:11)
at org.sandbox.Baz.main(Baz.java:10)

But this Java code is pretty verbose, especially if you have multiple arguments to check. After that I tried creating a static method named assureNotNull which would perform the check:

public class Foo {
// ...
public Foo( final Bar b ) {
assureNotNull( b );
// rest of constructor...
}
//...
private static void assureNotNull( final Object o ) throws IllegalArgumentException {
if ( o == null ) {
throw new IllegalArgumentException( "Object cannot be null" );
}
}
}

This has the unfortunate consequence that it becomes harder to track down the nature of the problem.

Exception in thread "main" java.lang.IllegalArgumentException: Object cannot be null
at org.sandbox.Foo.assureNotNull(Foo.java:14)
at org.sandbox.Foo.(Foo.java:9)
at org.sandbox.SimpleDoesStuff.doIt(SimpleDoesStuff.java:11)
at org.sandbox.Baz.main(Baz.java:10)

The stack trace on the exception shows assureNotNull as the source of the exception, which while strictly true doesn't clearly show that the real problem was with someone passing a null Bar to the Foo constructor. This can be mitigated to some degree by taking an description as argument:

public class Foo {
// ...
public Foo( final Bar b ) {
assureNotNull( b, "Bar b cannot be null" );
// rest of constructor...
}
//...
private static void assureNotNull( final Object o, final String msg ) throws IllegalArgumentException {
if ( o == null ) {
throw new IllegalArgumentException( msg );
}
}
}

This provides a somewhat more helpful exception message but the method generating the exception is still 'off by one':

Exception in thread "main" java.lang.IllegalArgumentException: Bar b cannot be null
at org.sandbox.Foo.assureNotNull(Foo.java:14)
at org.sandbox.Foo.(Foo.java:9)
at org.sandbox.SimpleDoesStuff.doIt(SimpleDoesStuff.java:11)
at org.sandbox.Baz.main(Baz.java:10)

And even with this semi-fix to help find the cause of the problem, we're still left with recreating this method in every class. From here the logical next step is to centralize the method. We can do this with an Assertions class:

public class Assertions {
// ...
public static void assureNotNull( final Object o, final String msg ) throws IllegalArgumentException {
if ( o == null ) {
throw new IllegalArgumentException( msg );
}
}
// ...
}

Now, our Foo constructor becomes simpler:

import org.acme.Assertions;

public class Foo {
// ...
public Foo( final Bar b ) {
Assertions.assureNotNull( b, "Bar b cannot be null" );
// rest of constructor...
}
//...
}

And with Java 5's static imports, we can even simplify it further:

import static org.acme.Assertions.assureNotNull;

public class Foo {
// ...
public Foo( final Bar b ) {
assureNotNull( b, "Bar b cannot be null" );
// rest of constructor...
}
//...
}

But we still have the wrong method as the first listed in the stack trace:

Exception in thread "main" java.lang.IllegalArgumentException: Bar b cannot be null
at org.acme.Assertions.assureNotNull(Assertions.java:9)
at org.sandbox.Foo.(Foo.java:7)
at org.sandbox.SimpleDoesStuff.doIt(SimpleDoesStuff.java:11)
at org.sandbox.Baz.main(Baz.java:10)

Since all of us Java developers are big on frameworks, we might even take it to the 'next level'. Why not centralize the Assertions in some common framework? If the Assertions class were in a common framework, the thinking goes, then we'd all be able to use it everywhere. That consistency would really help us read unfamiliar code.

Ignoring the issue of getting any set of developers of size greater than one to agree on anything, especially a basic assertions framework used everywhere, we've just introduced insidious code coupling where it really doesn't belong. In our desire to achieve clarity, brevity, and avoid redundancy, we've coupled code together. If we have a common class in our framework, all the classes in the framework are now coupled to it and indirectly to each other. If we move the class to a generic framework, we externalize the coupling, making it even broader. This coupling introduces many hazards for versioning and incompatibility problems that come with the independent evolution of code.

So, what choice are we left with? Well, we could always depend upon the runtime itself to generate an exception for us. We can do this quite briefly, with less redundancy of code than the other approaches, and with zero coupling:

public class Foo {
// ...
public Foo(Bar b) {
b.getClass(); // Assure not null
}
}

This code is quite short, and generates a NullPointerException with the top element pointing to exactly the line of code where the problem occurred:

Exception in thread "main" java.lang.NullPointerException
at org.sandbox.Foo.(Foo.java:7)
at org.sandbox.SimpleDoesStuff.doIt(SimpleDoesStuff.java:11)
at org.sandbox.Baz.main(Baz.java:10)

This code also avoids nearly all redundancy, and I think after seeing it once it becomes quite clear. As a bonus, it's easy to create a macro in any modern IDE to help in generating the code.

Sometimes, the right solution to a problem is not abstracting code into a separate method/class/framework.

Friday, March 07, 2008

Something else Apple Gets Right

Eric Burke made a reference to the work Apple puts into making their applications simple but capable. He also gave Google as an example. That item produced quite a few comments and Eric followed up with more details. Again, the discussion wasn't just about Apple but the company was again an example of hard work making things simple and functional. I agree with his comments, and remembered another example of Apple's efforts toward elegant designs.

For as many years as I can remember, the Apple website has had simple URLs to get to various parts of the website. For example:

Yes, other sites do this now. But Apple was doing this many years ago, long before competitor's sites.

This seemingly simple idea makes it much easier to navigate their web site for the vast majority of people going to the site. It allows people to get more quickly to the area they want. Without this, the task becomes much more involved:
  1. Visit the home page

  2. Parse the layout

  3. Find the navigation links

  4. Find the right link - if it's not there guess where to drill down

  5. Get to where you wanted to go

Wednesday, February 13, 2008

An alternate syntax for Java closures

I'm no expert on the details of the closures proposals. I do think if we're going to put closures into the language, we need to make them complete, full-fledged closures. Generics are a mess precisely because the semantics and features were compromised for the goal of getting it into the language.

But one thing I do know about the BGGA closures proposal is that I don't like the syntax. Take the example in Weiqi Gao's recent Java Quiz:

public class Fib {
private static {int=>int} fib = { int n =>
n==0 ? 0 :
n==1 ? 1 :
fib.invoke(n-1) + fib.invoke(n-2)
};

public static void main(String[] args) {
System.out.println(fib.invoke(6));
}
}

To me, this is just hard to read. The whole "=>" thing seems like a weak attempt to create a new lexical character and is too visually similar to ==, >>, etc. I also don't like the 'invoke' syntax. I was discussing this with Weiqi the other day and came up with a syntax that I like better.

public class Fib {
private static {int # int} fib = { # int n #
n==0 ? 0 :
n==1 ? 1 :
#fib(n-1) + #fib(n-2)
};

public static void main(String[] args) {
System.out.println(#fib(6));
}
}

Note that you could also invoke fib like this:

System.out.println(#Fib.fib(6));

I wonder what other people think of this alternative?