users@jersey.java.net

[Jersey] Re: jersey-spring breaks in OSGi

From: Ryan Stewart <rds6235_at_gmail.com>
Date: Fri, 20 May 2011 20:57:33 -0500

On Fri, May 20, 2011 at 4:13 PM, Ryan Stewart <rds6235_at_gmail.com> wrote:

> I'm trying to get a proof-of-concept Jersey app running in Virgo Web Server
> (formerly Spring dm Server) using jersey-spring as the mechanism for
> creating resource and provider instances. I've got it all set up so that
> when a bundle with certain manifest entries gets activated in Virgo, a
> different bundle that is watching for such events creates an instance of
> SpringServlet and gives it the ConfigurableApplicationContext published by
> the first bundle. Then the second bundle registers the created servlet with
> an OSGi HttpService, which starts up the servlet. Everything is working
> perfectly except that I keep getting that confounded "The ResourceConfig
> instance does not contain any root resource classes" error. Before you give
> me the knee-jerk reaction, let me assure you that the resource class is
> perfectly valid. The problem is actually related to how Jersey detects root
> resource classes. In com.sun.jersey.api.core.ResourceConfig, we find this
> method, which is used at startup to find beans in a Spring context that
> qualify as root resources:
> public static boolean isRootResourceClass(Class<?> c) {
> if (c == null)
> return false;
>
> if (c.isAnnotationPresent(Path.class)) return true;
>
> for (Class i : c.getInterfaces())
> if (i.isAnnotationPresent(Path.class)) return true;
>
> return false;
> }
>
> Despite the fact that my class has the correct @Path annotation, the
> isAnnotationPresent check is returning false. It turns out that the Path
> class referenced in this method as Path.class isn't the same class as that
> which is present in c's internal Map of annotations. Presumably this is
> because the two Path classes in question were loaded in two different OSGi
> bundles. Any thoughts here? I'm just about out of them.
>

I was sitting here thinking about it, and I think a fix--maybe not the best
solution, but still a fix--might be to take that isRootResourceClass method
and make it somehow use a pluggable strategy for loading the Path class. The
default behavior can be just like it is now, but then I could write a custom
strategy that would use the correct bundle classloader to load the class,
thereby making it correctly detect the root resource classes. I expect it
wouldn't be just this one place, though. The same sort of thing would need
to be done anywhere that any annotation is used. It might be a pretty
invasive change. It has also occurred to me that this would be a common
problem to any kind of annotation-scanning that takes place in an OSGi
container. I'm not sure what to make of that...