Hi Gerard,
Injection does not occur on instances returned by the application,
namely in sub-resource locators. Jersey does not manage instances
returned from sub-resource locators, it does not know what the life-
cycle is, so it cannot do postCreate/preDestroy or inject.
There are a number of things you can do:
- return the Class of the resource;
- use ResourceContext
@Path("subresource")
public ProxiedSubResource getSubResource(@Context ResourceContext
rc) {
return rc.getResource(ProxiedSubResource.class);
}
- use an IoC framework integrated with Jersey like Spring to obtain
an instance.
- inject on method parameters.
All of the above, except the last one, are currently non-standard
w.r.t. JAX-RS.
JAX-RS and Jersey are not yet EE compliant. We are working on that for
JAX-RS 1.1 which will align with Java EE 6 and then we will implement
support for injection of EE stuff on resource classes in Jersey/GF. I
view the InjectableProvider as an intermediate solution until we have
full EE 6 support in Jersey/GF.
Paul.
On Jan 7, 2009, at 11:44 AM, Gerard M. Davison wrote:
>
> Hi,
>
> I am fairly new to Jersey so apologies in advance if this is a
> stupid question. I am trying to write a simple InjectableProvider so
> that I get can @Resource injections working. My ServletContainer
> that registers this looks something like the following. (Note I
> expect there to be some glaring mistakes in the implementation here;
> but it seems to work for my little example application).
>
> public class ServletAdapter extends ServletContainer {
> @Override
> protected void configure(ServletConfig servletConfig,
> ResourceConfig rc,
> WebApplication wa) {
> super.configure(servletConfig, rc, wa);
>
>
> rc.getSingletons().add(new InjectableProvider<Resource,
> Type>() {
>
> public ComponentScope getScope() {
> return ComponentScope.Singleton;
> }
>
> public Injectable<Object>
> getInjectable(ComponentContext ic,
> Resource r,
> Type c) {
>
> final Holder value = new Holder();
>
> try {
> Context ctx = new InitialContext();
>
> // Look up a data source
> try
> {
> value.value = ctx.lookup(r.name());
> }
> catch (NamingException ex) {
>
> value.value = ctx.lookup("java:comp/env/"
> + r.name());
> }
> } catch (Exception ex) {
>
> ex.printStackTrace(); }
>
> return new Injectable<Object>() {
>
> public Object getValue() {
> return value.value;
> }
> };
> }
> });
> }
> }
>
>
> This works find when injecting resource at the root of a resource
> path but not for any sub resources. So the field in Parent is
> populated but the field in Child is not.
>
> @Path("/")
> public class Parent
> {
> @Resource(name="....")
> DataSource ds;
>
>
> @Path("/child/")
> public Child getChild()
> { ... }
> }
>
> public class Child
> {
> @Resource(name="....")
> DataSource ds;
>
> ... }
>
> My question is is this a bug or a feature? Certainly to my naive eye
> I would have expected the resource injection to happen for each
> level, certainly I can pass in the resource via constructors but
> this is going to unnecessarily complicate my code design.
> Particularly if the resource in question is only going to be used by
> one leaf in the tree.
>
> Finally is there a reason that the basic JSR-250 annotations such as
> @Resource at not supported by default?
>
> Thanks for any pointers,
>
> Gerard
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>