users@jersey.java.net

Re: [Jersey] Reuse of Spring's Autowired

From: Martin Grotzke <martin.grotzke_at_freiheit.com>
Date: Wed, 27 Aug 2008 18:27:48 +0200

On Wed, 2008-08-27 at 16:02 +0200, Paul Sandoz wrote:
> Martin Grotzke wrote:
> > On Wed, 2008-08-27 at 14:52 +0200, Paul Sandoz wrote:
> >> Martin Grotzke wrote:
> >>>> We can supply an implementation of an InjectableProvider that reuses
> >>>> the Autowired annotation. That implementation can be equivalent to
> >>>> that of our own @Inject annotation. So for Spring 2.5.x users they do
> >>>> not require a Jersey specific annotation.
> >>> Hmm, I'm somehow confused. Spring 2.5 users already can use the Spring
> >>> annotations and don't have to use our @Inject. Spring does the whole job
> >>> based on the spring 2.5 annotations. Though, I don't want to depend on
> >>> the spring 2.5 annotations but still support spring 2.0.
> >>>
> >> On fields yes, but not for constructors and methods that Jersey is
> >> responsible for invoking. It would only require supporting on 2.5.x.
> > @Autowired is used by spring at bean creation time. So if you have a
> > spring bean that has annotated some method with @Autowired spring would
> > try to invoke this method when it creates the object. If there's any
> > method argument that spring cannot supply:
> >
> > "By default, the autowiring will fail whenever zero candidate beans are
> > available; the default behavior is to treat annotated methods,
> > constructors, and fields as indicating required dependencies. This
> > behavior can be changed as demonstrated below." [1]
> >
> > I'd prefer not to redefine the semantics of @Autowired in the context of
> > jersey, as this might force users to change their software when the
> > start using jersey.
> >
> > Or do you have restrictions in mind, when jersey should use spring's
> > @Autowired annotation? Perhaps you might give an example how this should
> > be used?
> >
>
> I incorrectly thought @Autowired could be a replacement @Inject,
> especially for annotated parameters on resource class constructors and
> methods e.g. think of a resource method that requires a reference to a
> spring bean.
>
> But from what you describe it does not do what i expected it might i.e.
> @Autowired is not meant to be used on constructor/method parameters.
Yes for constructors, there you can use @Autowired. For method
parameters spring tries to invoke this method with beans pulled from its
own beanfactory - so yes/no for method parameters :)

Though, it would be nice to support injection of spring beans via
@Inject in method parameters.


>
>
> >> can be set to declare a default ResourceProvider when one is not
> >> declared on a resource class. Thus the SpringServlet can set this
> >> property (if not already set) and the SpringServlet ResourceProvider
> >> implementation can look at the @Component annotation and choose to defer
> >> to the singleton or per-request ResourceProvider implementations.
> > Ok. I'll do a basic implementation (depending on spring 2.5) and send
> > you a diff.
> >
>
> OK!

Here it is. It's codified what I thought how it should work, and after
having a look at ResourceProviderFactory.createProvider.

Unfortunately it does not work, when running the
SpringScopedResourceTest (or any other spring test) I get this
exception:

Aug 27, 2008 6:09:14 PM com.sun.jersey.api.core.PackagesResourceConfig init
INFO: Provider classes found:
[INFO] SpringServlet - -The spring Component annotation is present, we're using spring >= 2.5
[ERROR] SpringResourceProvider - -Could not initialize resource provider for resource class com.sun.jersey.impl.wadl.WadlResource
java.lang.NullPointerException
        at com.sun.jersey.spi.resource.ResourceConstructor.getConstructor(ResourceConstructor.java:78)
        at com.sun.jersey.impl.resource.PerRequestProvider.init(PerRequestProvider.java:79)
        at com.sun.jersey.spi.spring.container.servlet.SpringResourceProvider.init(SpringResourceProvider.java:156)
        at com.sun.jersey.spi.resource.ResourceProviderFactory.createProvider(ResourceProviderFactory.java:132)
        at com.sun.jersey.impl.model.ResourceClass.init(ResourceClass.java:182)
        at com.sun.jersey.impl.application.WebApplicationImpl.getResourceClass(WebApplicationImpl.java:258)
        at com.sun.jersey.impl.application.WebApplicationImpl.createWadlResource(WebApplicationImpl.java:866)
        at com.sun.jersey.impl.application.WebApplicationImpl.processRootResources(WebApplicationImpl.java:848)
        at com.sun.jersey.impl.application.WebApplicationImpl.initiate(WebApplicationImpl.java:675)
        at com.sun.jersey.spi.spring.container.servlet.SpringServlet.initiate(SpringServlet.java:169)

I think it's random that it complains when creating the WadlResource,
before the exception was thrown when creating the SpringScopedResource.

Do you have any idea what might be the reason?

Cheers,
Martin



> Paul.