Hi,
BTW i have fixed the JCDI bug in the trunk. If you want to verify with
GF you must set class loader delegation to false and include the 1.1.5-
SNAPSHOT jars in the war (the jars on the repo are not yet up to date
with the source in the trunk).
I agree that using ResourceContext as you describe above is a
relatively clean approach to 1) obtaining the instance when you
require; and 2) setting state additional.
What i am trying to do is unify that concept around injection.
For 1) you can now do this:
public ConnectionResource getConnectionResource(
@Inject Injectable<ConnectionResource> icr,
@PathParam("scheme") String scheme,
@PathParam("host") String host,
@PathParam("path") String path) {
ConnectionResource cr = icr.get();
...
}
For 2) you could use a factory-based pattern:
public class ConnectionResourceFactory {
public ConnectionResourceFactory(/* injected parameters */)
{ ... }
public ConnectionResource create(String scheme, String host,
String path) {
return ConnectionResource(/* injected parameters */
String scheme, String host, String path);
}
}
public ConnectionResource getConnectionResource(
@Inject ConnectionResourceFactory crf,
@PathParam("scheme") String scheme,
@PathParam("host") String host,
@PathParam("path") String path) {
ConnectionResource cr = crf.create(scheme, host, path);
...
}
It would be nice to try and support something like Guice's assisted
inject:
http://code.google.com/docreader/#p=google-guice&s=google-
guice&t=AssistedInject
but it is easier to recommend using Guice :-)
The same type of thing should be doable with 330 annotation @Inject
and Provider<T> using 299, except that JAX-RS/Jersey artifacts are not
injected into constructor parameters.
Your confusion over programatically obtaining a reference using
BeanManager is not surprising. I was equally confused. It is far from
obvious. This is the code that Jersey uses is as follows:
private Bean<?> getBean(Class<?> c) {
final Set<Bean<?>> bs = bm.getBeans(c);
if (bs.isEmpty()) {
return null;
}
try {
return bm.resolve(bs);
} catch(AmbiguousResolutionException ex) {
LOGGER.log(Level.SEVERE, null, ex);
return null;
}
}
...
BeanManager bm = ...
Class c = ...
Bean<?> b = getBean(c);
CreationalContext<?> bcc = bm.createCreationalContext(b);
Object o = c.cast(bm.getReference(b, c, bcc));
Paul.
On Nov 13, 2009, at 5:23 PM, Ian Carr wrote:
> Actually the ResourceContext seemed to make a lot of sense for the
> problem I was trying to get my head around, and I am interested that
> you say it's redundant.
>
> I am trying to replace the code I had to return a sub resource from
> a root resource, but I want injection into the sub resource
> instance. But also have parameters from the resource path I want to
> use to initialize the sub-resource
> So I had replaced code which did a 'new SubResource(parameter,...)'
> thus:
>
> @Path("/connection/{scheme}/{host}/{path}")
> public ConnectionResource getConnectionResource(@PathParam("scheme")
> String scheme, @PathParam("host") String host,
> @PathParam("path") String path) {
> // instantiate the resource allowing for DI
> ConnectionResource cres =
> _rctxt.getResource(ConnectionResource.class); <<< Uses the
> ResourceContext to replace the new
>
> cres.setConnection(_connManager.getConnect(scheme, host, path));
> <<< The stuff that would have been constructor parameters
>
> return cres;
> }
>
> This seemed to be relatively clean. I had toyed with trying to
> inject the sub resource, but that seems wrong, as the resource would
> be created whenever my root resource is used whether It's needed or
> not (I would end up creating an instance of all sub resources each
> time I wanted one of them) I also toyed with a Producer which
> injects a scheme/host/path request scoped thing that I would set in
> the method, but again that seems over engineered and wrong.
>
> I could use the BeanManager to do the equivalent of the Resource
> context, but would need to wrap up the fact that it returns a Set<>
> of object so probably end up back at a ResourceContext like producer
> object that wraps the BeanManager.
>
> How would you see a pattern like the one above working without the
> ResourceContext?
>
> Maybe I am a bad DI'r but sometimes I just wish we could make 'new'
> give me a DI'd object!
>
> Ian
>
> -----Original Message-----
> From: Paul.Sandoz_at_Sun.COM [mailto:Paul.Sandoz_at_Sun.COM]
> Sent: 13 November 2009 15:55
> To: users_at_jersey.dev.java.net
> Subject: Re: [Jersey] JCDI dependency injection with Jersey
>
>
> On Nov 13, 2009, at 4:45 PM, Ian Carr wrote:
>
>> Ah, sorry :-)
>>
>> So the ResourceContext is still the way to go then?
>>
>
> If your resource classes are 299 managed beans then i recommend you
> use the JCDI mechanism to inject the resource classes (ResourceContext
> should be redundent, BTW i am working on fixing Jersey so one can use
> Jersey's Inject instead of ResourceContext, for non 299 cases).
>
>
>> Give me a nod if there is anything I can try out to help!
>>
>
> Thanks. Keep playing and reporting any problems :-)
>
> Paul.
>
>> Many thanks
>>
>> Ian
>>
>> -----Original Message-----
>> From: Paul.Sandoz_at_Sun.COM [mailto:Paul.Sandoz_at_Sun.COM]
>> Sent: 13 November 2009 15:36
>> To: users_at_jersey.dev.java.net
>> Subject: Re: [Jersey] JCDI dependency injection with Jersey
>>
>> Hi Ian,
>>
>> I can reproduce this. It is a *nasty* bug :-(
>>
>> The problem is the injection information is initialized too early
>> before all the injection-related providers are registered.
>>
>> Paul.
>>
>> On Nov 13, 2009, at 4:03 PM, Ian Carr wrote:
>>
>>> Hi, I have been doing some investigation of the JCDI injection
>>> mechanism and Jersey.
>>> I have been using the later builds of glassfish v3 (builds 71 & 72)
>>> with some success.
>>> However a change in the behaviour in build 72 has prompted me to the
>>> following question.
>>>
>>> (I do realize that all of this is still experimental, but am
>>> interested in where it's headed)
>>>
>>> Will I be able to mix and match the injection techniques @Inject and
>>> @Context or will one supercede the other?
>>>
>>> my sample code:
>>>
>>> @Path("/")
>>> @ImplicitProduces("text/html;qs=5")
>>> @XmlRootElement
>>>
>>> @ManagedBean
>>>
>>> public class MainResource implements Serializable {
>>> private static final long serialVersionUID = 1L;
>>> private static final Logger __log =
>>> Logger.getLogger(MainResource.class.getName());
>>>
>>> @Inject
>>> private BeanManager _manager; <<< the JCDI injection manager
>>>
>>> @Inject
>>> ConnectionManager _connManager; <<< my producer object
>>>
>>> @Context
>>> ResourceContext _rctxt; <<< The jersey resource context
>>>
>>> @Context
>>> HttpContext hctxt; <<< The jersey Http context
>>>
>>> In glassfish v3 build 71 which used jersey version 1.1.3-ea, all 4
>>> objects are injected when the ManagedBean annotation was present,
>>> but (correctly!) only the two jersey objects without the managedBean
>>> annotation.
>>>
>>> But having installed build 72 (which appears to incorporate the
>>> 1.1.4 release of jersey) this morning and tried the same
>>> application.
>>> the @Inject parameters and the HttpContext are injected if the
>>> ManagedBean annotation is present but the ResourceContext is not.
>>> If I remove the annotation the HttpContext and ResourceContext
>>> (instance of
>>> com.sun.jersey.server.impl.application.WebApplicationImpl$6) are
>>> injected.
>>>
>>> I was assuming that even when using the ManagedBean resources I
>>> would still inject the jersey ResourceContext object to create sub
>>> resources as per the spring examples, and would therefore take
>>> advantage of Jersey deciding where injected objects came from.
>>> Or is the intention that I would use the JCDI bean manager to derive
>>> the sub resources? but presumably that precludes a mixed object
>>> source solution?
>>>
>>> again appologies if this is too early to be trying this stuff!
>>>
>>> Thanks for a great framework
>>>
>>> Ian
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>