4

I would like to inject a buisiness service bean in a sub resource which is defined in a dedicated class and delivered by a sub resource locator.

Some example code:

  1. A root resource

    @RequestScoped
    @Path("service")
    public class MyResource {
    
        @Context
        ResourceContext resourceContext;
    
        // Sub resource locator
        @Path("subservice")
        public MySubResource locateToSubResource () {
            // I don't want to create it myself.
            return resourceContext.getResource(MySubResource.class);
        }
    }
    
  2. The corresponding sub resource

    @RequestScoped
    public class MySubResource {
    
        // Note that businessBean itself consists of
        // multiple ejbs that also need to be injected so that it can do its job!
        @Inject
        private BusinessBean businessBean; 
    
        @GET
        @Produces(MediaType.TEXT_PLAIN)
        public String get () {
            return businessBean.doStuff();
        }
    }
    

Jersey won't CDI let invoke the dependencies... Note that the resources are managed objects. Otherwise it wouldn't even be possible to inject a bean in a root resource (here I'm pushing my other questions' view count to get more opinions ;-))!

I tried everything I can think of but it just won't work...

Currently I'm using the libraries that are shipped with glassfish 4.

And of course, thank you in advance (almost forgot that)!

Community
  • 1
  • 1
Doe Johnson
  • 1,374
  • 13
  • 34

2 Answers2

7

Okay, I figured it out.

It is really kind of stupid. Sometimes you have to roll back completely.

There must have been something wrong with my initial attempt (typo, left out something...I cannot reproduce it, whatever).

I slightly changed the root resource from above:

@RequestScoped
@Path("service")
public class MyResource {

    @Inject MySubResource mySubResource;

    // Sub resource locator
    @Path("subservice")
    public MySubResource locateToSubResource () {
        return mySubResource;
    }
}

Yes, that's it. I must admit, that's the most intuitive solution one can imagine and if such an approach don't work one must have done something wrong... Dont't ask me what exactly was the cause.

I guess it's as always - sleep deprivation let people turn into morons.

Doe Johnson
  • 1,374
  • 13
  • 34
  • This finally did the trick for me too, but I have a question: is `@RequestScoped` really required on the root resource class? It also works for me without that, and I thought that you don't need a CDI bean to inject another one into, but it also works with JAX-RS resource classes (for example)? – Hein Blöd Feb 12 '15 at 12:11
  • Actually, it seems like one doesn't even have to use an explicit `@RequestScoped` on the sub resource either because according to [this](http://stackoverflow.com/questions/10293510/what-is-the-default-scope-of-a-named-cdi-bean/10293686#10293686) answer, the default scope should just be the same as the class that receives the injection? In fact, I can leave out that annotation too. – Hein Blöd Feb 12 '15 at 12:43
2

I solved like this.

public SubResource subResource() {
    return CDI.current().select(SubResource.class).get();
}
Jin Kwon
  • 20,295
  • 14
  • 115
  • 184
  • 2
    Hmn, maybe there are certain use cases where this is applicable/acceptable but any possible error would manifest not until actual execution *at runtime*, right? If you'd instead use the declarative `@Inject`-way the injection provider has at least an opportunity to complain eagerly *during deployment*. On the other hand your answer shows a nice-to-know programmatic alternative which makes it useful. – Doe Johnson Sep 28 '15 at 19:08