users@jersey.java.net

Re: [Jersey] SubResource locators and _at_Context injection...

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Mon, 09 Mar 2009 10:53:52 +0100

On Mar 2, 2009, at 2:27 AM, Marc Hadley wrote:

> Objects returned by sub-resource locators are not injected by the
> JAX-RS runtime since their lifecycle is under the control of the
> application rather than the runtime.
>

Yes, Jersey does not know what the scope of the returned instances are
to perform injection.

If you want Jersey to inject then you need to use a Jersey specific
class ResourceContext:

   https://jersey.dev.java.net/source/browse/*checkout*/jersey/tags/jersey-1.0.2/api/jersey/com/sun/jersey/api/core/ResourceContext.html

For example,
   @Path("/")
   public class NodesResource extends BaseResource {

           @EJB private NodeRemote nodeRemote;

           @Path("/v1/nodes")
           public NodesV1Resource getNodesV1Resource(@Context
ResourceContext rc) {
                   System.out.println("uriInfo: " +
uriInfo.getMatchedURIs().toString());
                   System.out.println("uriInfo: " +
uriInfo.getMatchedResources().toString());

                   NodesV1Resource r = rc.get(NodesV1Resource.class);

                   return r;
           }
   }



With respect to the support of @EJB, JAX-RS 1.0 does not specify
injection support of EE artifacts on to root resource classes or
provider classes. JAX-RS 1.1 does so, but Jersey does not yet
implement JAX-RS 1.1 and the EE support (we are working on it).

If you need support for @EJB in the interim you have to write your own
injectable provider:

   http://blogs.sun.com/sandoz/entry/ejb_injection

Please look in the comments for updated code.

Paul.


> Marc.
>
> On Feb 27, 2009, at 4:13 PM, Rabick, Mark A (MS) wrote:
>> I've got a resource base class that injects the @Context information:
>>
>> import javax.ws.rs.core.Context;
>> import javax.ws.rs.core.HttpHeaders;
>> import javax.ws.rs.core.Request;
>> import javax.ws.rs.core.SecurityContext;
>> import javax.ws.rs.core.UriInfo;
>> import javax.ws.rs.ext.Providers;
>>
>> public class BaseResource {
>>
>> @Context
>> protected SecurityContext securityContext;
>> @Context
>> protected UriInfo uriInfo;
>> @Context
>> protected Request request;
>> @Context
>> protected HttpHeaders httpHeaders;
>> @Context
>> protected Providers providers;
>>
>> public BaseResource() {
>> super();
>> }
>>
>> }
>>
>> If I have a resource with a sub-resource locator:
>>
>> @Path("/")
>> public class NodesResource extends BaseResource {
>>
>> @EJB private NodeRemote nodeRemote;
>>
>> @Path("/v1/nodes")
>> public NodesV1Resource getNodesV1Resource() {
>> System.out.println("uriInfo: " +
>> uriInfo.getMatchedURIs().toString());
>> System.out.println("uriInfo: " +
>> uriInfo.getMatchedResources().toString());
>> return new NodesV1Resource(nodeRemote);
>> }
>> }
>>
>> The System.out-s display the expected output. The sub-resource
>> class is:
>>
>> public class NodesV1Resource extends BaseResource {
>>
>> private NodeRemote nodeRemote;
>>
>> public NodesV1Resource(NodeRemote nodeRemote) {
>> this.nodeRemote = nodeRemote;
>> }
>>
>> @GET @Path("{sk}")
>>
>> @Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})
>> public NodeV1 getNodeV1ByKey(@PathParam("sk") String sk) {
>>
>> System.out.println("uriInfo: " +
>> uriInfo.getMatchedURIs().toString());
>> System.out.println("uriInfo: " +
>> uriInfo.getMatchedResources().toString());
>>
>> Node node = nodeRemote.getBySk(sk);
>>
>> if (node == null)
>> throw new NotFoundException("Node not found
>> for sk: " + sk);
>>
>> NodeV1 nodeV1 = (new BuilderV1()).buildNodeV1(node);
>>
>> return nodeV1;
>> }
>>
>> I get NullPointerException-s on the System.out calls in
>> getNodeV1ByKey. It doesn't appear to inject the UriInfo and other
>> @Context annotated elements in the BaseResource if the method is in
>> a sub-resource. I can inject the specific @Context in the method:
>>
>> public NodeV1 getNodeV1ByKey(@Context UriInfo uriInfo,
>> @PathParam("sk") String sk) {…}
>>
>> Another point, I have to pass the EJB remote interface from the
>> NodesResource base resource in the constructor of the
>> NodesV1Resource. It doesn't inject the @EJB in a sub-resource
>> either. Is this spec behavior? Does injection (either @Context or
>> InjectableProvider) only occur on base resource classes or in
>> parameters to subresource methods?
>>
>> --mark
>> _______________________________________________
>> Mark A. Rabick
>> Software Engineer
>> Northrop Grumman - C2 Systems (MS/C2SD/IIS)
>> 3200 Samson Way
>> Bellevue, NE 68123
>> Ph: (402) 293-7091
>> Em: mark.rabick_at_ngc.com
>> Remember PFC Ross A. McGinnis...
>> http://www.army.mil/medalofhonor/McGinnis/index.html
>> ... MA2 Michael A. Monsoor, Lt. Michael P. Murphy, Cpl. Jason
>> Dunham, SFC Paul Ray Smith and the rest...
>> http://www.cmohs.org/recipients/most_recent.htm
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>