Saturday, January 31, 2009

Against the viral Commons-Logging

Years ago I wrote a blog post about how to make your application Commons-Logging (JCL) free by using SLF4J.

However, there is still a problem if you're writing a Maven2 based application: even if you're using SLF4J, you will probably end up with a viral JCL jar in your classpath!
That's because JCL is still used by a lot of projects, and Maven places it in your classpath as a transitive dependency.

Fortunately enough, there's still a way to completely, and easily, get rid of it thanks to the jcl-over-slf4j module, and a little Maven trick.

Here's the receipt:


  1. Add the following SLF4J dependencies:

    • slf4j-api

    • logback-classic (or your SLF4J implementation of choice).

    • jcl-over-slf4j




  2. Configure the JCL dependency with scope provided.


So here's how your Maven dependencies should look like:

By doing so, JCL will not be included in your classpath (because Maven considers it to be externally provided), while under the hood will be implemented by SLF4J thanks to the jcl-over-slf4j module.

That's all, folks.
Now you have one, and only one, safe logging library!

Saturday, January 24, 2009

Real Terracotta @ Rome JavaDay 2009

I'm just back from the Rome JavaDay 2009, and here is the presentation I gave: Real Terracotta - Real-world scalability patterns with Terracotta.



I hope you enjoyed it!
I'd be very glad to hear your feedback, so feel free to comment on with any question/thought you may have!

Thursday, January 22, 2009

Follow me on Twitter

Just subscribed to Twitter: http://twitter.com/sbtourist

Feel free to follow me, hoping to tweet interesting stuff at an higher rate than my blogging one ;)

Friday, January 09, 2009

JAX-RS: A proposal for resource URI identification and resolution

In my latest two posts I talked about the problem of clearly defining and resolving the URI of a REST resource in JAX-RS, and then described a possible solution.

I discussed this topic in the Resteasy dev mailing list (here is the thread), and Solomon Duskis suggested to identify resources with a unique logical name rather than with a class name, in order to support multiple REST resources in the same JAX-RS resource, and have less syntax burden.

Building on that suggestion, I've enhanced my proposal and I have to say I'm very happy with it now: as always, feedback is very welcome.

Resource URI identification.

The URI identifying a particular resource is defined by the ResourceUriFor annotation which must be applied to the JAX-RS resource method annotated with the path expression of the URI.
Here it is:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Inherited
public @interface ResourceUriFor {

public String resource();

public String[] subResources() default {};

public Class locator() default Void.class;
}

The resource argument is the only mandatory one: it defines the logical name of the resource, wich must be unique among all resources.
The subResources argument, optional, defines the logical names of all sub-resources eventually returned by the identified resource, which in this case would act as a locator.
The locator argument, optional, defines the class of the eventual resource locator for the identified resource, which in this case would actually be a sub-resource.

Resource URI resolution.

Resolving a resource URI identified by the above defined annotation is a simple method call:


public interface ResourceResolver {

public URI resolveResourceUriFor(
Class resourceClass,
String resourceName,
String uriBase,
Object... uriParameters);

}


The resourceClass parameter is the class of the JAX-RS resource containing the ResourceUriFor annotation.
The resourceName is the logical name of the resource whose URI has to be resolved.
The uriBase is the base path.
The uriParameters are the objects to use for eventually filling the URI template values.

Resource URI resolution algorithm.

1) Start from resourceClass.
2) Lookup a method annotated with a ResourceUriFor annotation whose logical name is resourceName.
3a) If the ResourceUriFor annotation has no locator, we already have all the elements for resolving the URI.
3b) If the ResourceUriFor annotation has a locator class, go to 4.
4) Go to locator class.
5) Lookup a method annotated with a ResourceUriFor annotation whose subResources contains resourceName of the resource in 2, and go back to 3a.

Monday, January 05, 2009

JAX-RS and HATEOAS : A Proposal

This is a follow-up to my latest post: JAX-RS and HATEOAS, AKA "JAX-RS should provide a way to identify and resolve resource URLs".

I'd like to outline a possible solution, but first, let me recap the problem with a simple example.

The Problem.

JAX-RS let you define web resources out of simple POJOs by properly placing simple, meaningful, annotations.
Let's say we have a Library resource, containing Book resources.

@Path("/")
public class BookResource {

@GET
@Path("/library/book-{id}")
public Response getBook(@PathParam("id") id) {
// ...
}
}


@Path("/")
public class LibraryResource {

@GET
@Path("/library")
public Response getLibrary() {
// ...
List<Book> books = getBooks();
for (Book book : books) {
String id = book.getId();
// Now I have the book id:
// how can I obtain the URL of the resource corresponding to that book?
}
// ...
}
}

So we have two kind of resources, and a relation between the two: from LibraryResource to BookResource.
If you're still wondering why the LibraryResource needs to know the URLs of the BookResources, the answer is Hypermedia As The Engine Of Application State: that is, in a REST application the only way to access the books in the library is to go through the LibraryResource and follow the published book links towards the proper BookResource.
The true question is: how can LibraryResource obtain the BookResource URLs?

The Proposal.

My proposal involves two new annotations and a new utility method.

The ResourceUri annotation must be placed on the web resource method defining the path to use for accessing the resource itself.
It has two arguments: resource (mandatory), defining the class of the identified resource, and locator (optional), eventually defining the resource locator for the resource itself.

The LocatorUri annotation must be placed on the web resource method defining the path for accessing a sub-resource: so, it identifies a sub-resource locator method.
It has two arguments: resources (mandatory), defining the classes of the sub-resources located by the locator method, and locator (optional), eventually defining another locator up in the chain.

Finally, the UriInfo#getResourceUri(Class resourceClass, Object... uriParameters) should resolve the resource URI of the given resource class by inspecting the annotations above.

So, we could rewrite the example above in the following way:

@Path("/")
public class BookResource {

@ResourceUri(resource=BookResource.class)
@GET
@Path("/library/book-{id}")
public Response getBook(@PathParam("id") id) {
// ...
}
}


@Path("/")
public class LibraryResource {

@GET
@Path("/library")
public Response getLibrary(@Context UriInfo uriInfo) {
// ...
List<Book> books = getBooks();
for (Book book : books) {
String id = book.getId();
URI bookUri = uriInfo.getResourceUri(BookResource.class, id);
// ...
}
// ...
}
}


So, with a bunch of annotations and a simple method call, we are now able to clearly say what is the URI that identifies a web resource, and how to resolve it.

What do you think?

Sunday, January 04, 2009

JAX-RS and HATEOAS

This post should have been named something like: "JAX-RS should provide a way to identify and resolve resource URLs".
However, it was too long, so I opted for some buzzy acronyms: let me explain them.

JAX-RS is the official Java API for building Restful Web Services: also known as JSR-311, it went final a few months ago, and is, IMHO, a very good specification, providing an easy and effective way for building REST-oriented web services.
http://www.blogger.com/img/blank.gif

HATEOAS is something more complicated: it would deserve a whole post by its own, but I will try to explain it in a few paragraphs.
First, HATEOAS ishttp://www.blogger.com/img/blank.gif an acronym for: Hypermedia As The Engine Of Application State.
Wow ... you may wonder what does it meahttp://www.blogger.com/img/blank.gifn, so ...
Everyone knows about REST, but too bad, not everyone knows that it's an architectural style, rather than an implementation thing.
More specifically, REST is a way for creating distributed (web) architectures based on some basic principles, and HATEOAS is one of the most important, and often misled/ignored.
HATEOAS could also be named hypermedia-based navigation. It means that a REST application should provide at most one fixed URL: all application URLs, with related resources, should be "dynamically" discovered, and navigated, starting from that fixed URL, thanks to the use of hypermedia links throughout all resources.

That said, the concept of resource URL acquires great relevance: every resource must have its own URL, and that URL must be known by other resources in order to publish it and make the resource accessible.

Now, let's go to my point.
JAX-RS does a very good job at defining resource URLs, but lacks of a way for identifying, as a first class concept, what is the actual URL of a given resource, and hence for resolving it.
Let me give a simple example.
Take a look at the following JAX-RS compliant web resource implementation:

@Path("/resources")
private static class JAXRSResource {

@GET
@Path("/resource")
public String getResource() {
// ...
}

@POST
@Path("/")
public void postResource(String resource) {
// ...
}
}

It defines how to GET and POST the resource, with related paths, but how does it define what really is the URL to use for identifying the resource? And how could another resource refer to it?
For answering the first question, you have to browse all methods, and guess the correct one by looking at the http method annotation (GET), plus its path values.
For answering the second question, you have to hard-code it in the referring resource, or write something like (using JAX-RS APIs) UriBuilder.fromResource(JAXRSResource.class).path(JAXRSResource.class, "getResource").build(): both obscure and error-prone.

So here is my point: again, JAX-RS should provide a way for clearly identifying a resource URL, and easily resolving it.

What do you think?

Saturday, January 03, 2009

Best of 2008

Here is my personal list, just for fun ...

Best of Music
  • The Decemberists - Always the Bridesmaid
  • Shearwater - Rook
  • Okkervil River - The Stand Ins
Best of Movies/TV
  • Zohan (Movie)
  • The Dark Knight (Movie)
  • Dexter (TV)
Best of Tech/Non-Tech Reading
  • Clean Code, Martin (Tech)
  • The Road, McCarthy (Non-Tech)
  • InfoQ.com (Tech)

Now, let the 2009 begin ...