So I am also back to hacking to get a REST service up, with some more excuses. Anyway, once again tried Restlet as I like its minimal set of jar files and simple interface. But even if it sometimes (from my googling) seems to be advertised as well documented, it actually seems rather poorly documented. Going to the Jersey user guide and reading that really helps me understand how Jersey works. There seems to be nothing similar in Restlet, it is more spread around with few lines about all the different platforms and extensions with just little info but not quite enough on anything. JBoss RestEasy on the other hand is a huge bunch of jar files for every little task one in itself. So Jersey it is then, which seems to be nicely documented but only a “reasonable set of jars”…
So how do I get Jersey to run inside OSGI?
Just using it in the standard way expressed in the Jersey docs, results in the exception
com.sun.jersey.api.container.ContainerException: The ResourceConfig instance does not contain any root resource classes.
I guess this is due to the standard OSGI classloader issues, as also noted for example in
http://coderthoughts.blogspot.com/2008/03/using-jersey-jsr311-inside-osgi-with.html
But how do I fix it? Writing my own ResourceConfig class seems like a huge task for something this simple, and something that could easily break in future Jersey versions. So this is the code I used to get the exception
Dictionary<String, String> config = new Hashtable<String, String>(); config.put("com.sun.jersey.config.property.packages", "my.package.rest"); httpService.registerServlet("/rest", new ServletContainer(), config, null);
So now my Resource classes are in package “my.package.rest”. But it all fails, doesn’t it.
Luckily the Jersey user guide has a nice example of using Jersey inside OSGI. The trick seems to be to not use the “packages” property but rather to change the above to
Dictionary<String, String> config = new Hashtable<String, String>(); config.put("javax.ws.rs.Application", JerseyApplication.class.getName()); httpService.registerServlet("/rest", new ServletContainer(), config, null);
So the difference is using the Application class to explicitly list the Resource classes. I guess this results in using the correct classloader, probably the one that loads the Application as well. Well, at least it works 🙂
edit: the info for using Jersey with a servlet container is perhaps best given in the JavaDoc for package com.sun.jersey.spi.container.servlet, for example, at the time of this writing available at (browse your Jersey javadoc package if not):
http://jersey.java.net/nonav/apidocs/1.5/jersey/com/sun/jersey/spi/container/servlet/package-summary.html
for OSGI the jersey user guide OSGI example code (download from the link in user guide) is the best ..