users@jersey.java.net

[Jersey] Re: Custom providers in Jersey 2?

From: Marek Potociar <marek.potociar_at_oracle.com>
Date: Wed, 29 May 2013 15:18:17 +0200

On May 22, 2013, at 9:38 PM, algermissen1971 <algermissen1971_at_mac.com> wrote:

> Hi Marek,
>
> On 22.05.2013, at 18:36, Marek Potociar <marek.potociar_at_oracle.com> wrote:
>
>> On May 22, 2013, at 5:03 PM, Paulo Pires <pjpires_at_gmail.com> wrote:
>>
>>> +1
>>>
>>> On Sat, May 11, 2013 at 9:13 PM, algermissen1971 <algermissen1971_at_mac.com> wrote:
>>> Hi Jersey2 devs,
>>>
>>> can anyone help shed some light on how to implement custom providers for Jersey 2?
>>
>> Jersey 2.0 uses HK2 for injection.
>
> Yeah, I know. But it is just frustrating that the only way to get old of an object inside a JAX-RS component is by implementing some component that introduces a dependency I might otherwise not have.

The dependency is on standard JSR330/229 APIs only, unless you want to use HK2 programmatic injection binding API a-la Guice.

>
> You know, what does an @Inject inside a filter buy me when I have to say "A yes, and after downloading this JAX-RS 2.0 library I provide, please implement a binding to whatever JSR 330 implementation you use." I'd rather have the user of the library throw the JAR in and be done. As it stands, that is impossible.

You can implement the binding yourself and ask the users to use the META-INF/services approach. Here's the utility HK2 binder we use in Jersey to support the Java service provider discovery mechanism:

https://github.com/jersey/jersey/blob/master/core-common/src/main/java/org/glassfish/jersey/internal/ServiceFinderBinder.java

That way your clients do not need to use HK2 APIs. Another option is to use CDI.

>
>> So what you need to do is to provide an implementation of a HK2 Binder that defines how the injection should be satisfied - very similar to the way Guice works. See e.g.:
>>
>> https://github.com/jersey/jersey/blob/master/ext/mvc/src/main/java/org/glassfish/jersey/server/mvc/internal/MvcBinder.java
>>
>> Then you need to register your binder in your ResourceConfig as you would register a resource or any other JAX-RS/Jersey provider.
>>
>>> [...]
>
>
>>> But how do I get the service injected into the constructor of my ResourceConfig?
>>
>> :) Use @Inject on your constructor.
>
> This is what I ended up with, but since that did not work I wrote this question in the first place.
>
> I forgot what did not work, but IIRC JAX-RS requires the argument-less ctor, or?

No, it doesn't.

>
> If you say it should work, I'll try.
>
> So you say I should do the following and JAX-RS runtime will invoke that ctor? With JSR330 ctor injection also happening?
>
> @javax.ws.rs.ApplicationPath("r")
> public class ApplicationConfig extends ResourceConfig {
>
>
> @Inject
> public ApplicationConfig(MyCredentialsService s) {
>
> packages( ... bunch of packages with resource classes ...);
> this.registerInstances(new SpecialAuthFeature(s));
> }
> }
>
> Yes?

That may work as long as the MyCredentialsService is registered in CDI.

Marek

>
> Jan
>
>
>
>
>>
>> Marek
>>
>>>
>>> Jan
>>>
>>>
>>>
>>> --
>>> Paulo Pires
>>
>