users@jersey.java.net

[Jersey] Re: Why is JSR 330 not enough?

From: cowwoc <cowwoc_at_bbs.darktech.org>
Date: Tue, 29 Oct 2013 17:49:01 -0400

     That's what I thought.

     I'll go out on a limb and say that section 3.1.2 should be removed
from the JAX-RS spec. I don't understand why JAX-RS should care about
this implementation detail. Users of HK2 might care how it does
injection, but that's for HK2 to mandate, not JAX-RS. It just needs to
provide the building blocks for constructing JAX-RS types, such as
UriInfo, and let the DI integrators connect those to their implementation.

Gili

On 29/10/2013 5:31 PM, Joseph Mocker wrote:
> Hi,
> While I don't know if this is done, it appears that Autowired
> processing at least in Spring is handled
> by AutowiredAnnotationBeanPostProcessor. I'm guessing, if one so
> desired, they could augment or write a replacement to how this works
> to handle the guidelines required by section 3.1.2. Spring's
> constructor rules are already pretty close, but not exactly to the
> wording of 3.1.2
>
> "The constructor with the greatest number of dependencies that can
> be satisfied by matching beans in the Spring container will be
> chosen. If none of the candidates can be satisfied, then a default
> constructor (if present) will be used."
>
>
> Alas, my quick scan of the RESTEasy source, it doesn't appear there is
> any code to specifically deal with 3.1.2 rules.
>
> ---joe
>
> Velti <http://www.velti.com> *Joseph Mocker *| Senior Software
> Architect
> *t* +1.415.315.4314 *m* +1.650.566.7033
> *e* jmocker@velti.com @VeltiMobile <http://twitter.com/VeltiMobile>
>
> The leading global technology provider of
> mobile marketing and advertising solutions
>
>
>
> On Oct 29, 2013, at 12:40 PM, cowwoc <cowwoc_at_bbs.darktech.org
> <mailto:cowwoc_at_bbs.darktech.org>> wrote:
>
>>
>> I just noticed that RESTEasy 3.0.4 support JAX-RS 2.0, Guice and
>> Spring.
>>
>> Take a look at
>> http://docs.jboss.org/resteasy/docs/3.0.4.Final/userguide/html_single/index.html#Guice1
>>
>> Section 46.1 shows them mixing @Inject with @RequestScoped.
>> Section 46.2 shows them exposing JAX-RS types to Guice using
>> "JaxrsModule".
>>
>> Any idea how they are able to do this? I fairly certain they
>> ignore the rules you quoted in section 3.1.2 (choosing the
>> constructor with the most parameters).
>>
>> Gili
>>
>> On 29/10/2013 2:40 PM, cowwoc wrote:
>>> Cameron,
>>>
>>>> I would guess that for Jersey 1.0 which had a custom DI container,
>>>> the intent was to integrate with any other DI, but for Jersey 2 as
>>>> it defers responsibility to HK2 it would seem that it's HK2's
>>>> responsibility to integrate with other DI containers.
>>>
>>> I understand why Jersey chose to delegate DI integration to HK2
>>> (separation of concerns) but it turns out that was based on an
>>> incorrect assumption. It turns out that HK2 cannot share
>>> configuration/injection responsibility with 3rd-party DIs. Guice, in
>>> particular, does not support delegating injection for unknown types.
>>> This feature was requested 5 years ago but ultimately rejected due
>>> to insufficient demand and the extra complexity it would introduce:
>>> https://code.google.com/p/google-guice/issues/detail?id=49. I am
>>> trying to have it reintroduced, but I am fighting an uphill battle.
>>>
>>> At the same time, you bring up a good point:
>>>
>>>> Also, JAX-RS has some of it's own non-standard DI rules which
>>>> wouldn't be definable without customizations to injection
>>>> processing. This would also need to be defined per-container.
>>>>
>>>> For example, for resource constructors (JAX-RS 3.1.2 Constructors):
>>>>
>>>> "However, depending on the resource class lifecycle and
>>>> concurrency, per-request information may not make sense in a
>>>> constructor. If more than one public constructor is suitable then
>>>> an implementation MUST use the one with the most parameters.
>>>> Choosing amongst suitable constructors with the same number of
>>>> parameters is implementation specific, implementations SHOULD
>>>> generate a warning about such ambiguity."
>>>>
>>>> This isn't defined in JSR-330 and in JSR-299 multiple constructors
>>>> would throw an error at runtime.
>>>
>>> This is a hard requirement to meet. I am surprised that the
>>> JAX-RS spec mandates this (it seems out of scope to me). It
>>> virtually assures that no DI except HK2 would work for JAX-RS. Out
>>> of curiosity, does the Jersey-Spring plugin meet this requirement?
>>>
>>>>
>>>> At what point does JAX-RS stop and the generic definition
>>>> of DI containers begin?
>>>>
>>>>
>>>> Jersey 1.0 did a pretty good job. We should pick up where
>>>> it left off and take it to the next level. Depending on HK2
>>>> directly shifts the burden from a small number of Jersey
>>>> committers to a large number of end-users. Guice/Spring weren't
>>>> designed to for integration into 3rd-party DI frameworks. Their
>>>> design (quite reasonably) assumes the use of one DI framework
>>>> at a time. I have tried integrating Guice and HK2 for weeks now
>>>> and it doesn't look like it's technically possible.
>>>>
>>>>
>>>> Heh, HK2 wasn't designed for integration with 3rd party DI
>>>> frameworks either :)
>>>
>>> It gained that requirement the moment Jersey delegating DI
>>> integration to it. Guice/Spring are independent libraries that have
>>> nothing to do with JAX-RS. The close coupling of Jersey and HK2
>>> might be nice for Jersey but it isn't reasonable to expect the same
>>> from general DI frameworks.
>>>
>>>> Are you asking more of HK2 than you expect of Guice/Spring?
>>>
>>> Not at all. I am expecting HK2 to be one of many implementations
>>> that may be used with Jersey. I expect only one DI implementation to
>>> be active at a time.
>>>
>>>> Isn't what you really want a (C)DI abstraction layer?
>>>
>>> I am not very familiar with CDI so I can't really comment. Last
>>> time I scanned through it it looked overly complex.
>>>
>>>> I'm guessing that mixing DI containers is probably a bad idea,
>>>> hence the technical difficulties. I've not resolved this either.
>>>
>>> I agree. Which is why I'm saying we should only be using one DI
>>> implementation at a time, but allow users to decide which
>>> implementation they chose to use.
>>>
>>>
>>>> The problem is that JSR-330 doesn't define enough. It is a set of
>>>> reusable annotations, with no specification of how any system using
>>>> them should be implemented:
>>>>
>>>> http://atinject.googlecode.com/svn/trunk/javadoc/javax/inject/package-summary.html
>>>>
>>>> "*This package provides dependency injection annotations that
>>>> enable portable classes*, but it leaves external dependency
>>>> configuration up to the injector implementation."
>>>>
>>>> "Injector implementations can take many forms. An injector could
>>>> configure itself using XML, annotations, a DSL (domain-specific
>>>> language), or even plain Java code. An injector could rely on
>>>> reflection or code generation. An injector that uses compile-time
>>>> code generation may not even have its own run time representation.
>>>> Other injectors may not be able to generate code at all, neither at
>>>> compile nor run time. A "container", for some definition, can be an
>>>> injector, but this package specification aims to minimize
>>>> restrictions on injector implementations."
>>>>
>>>> I can see that it's feasible to do multiple Jersey modules with one
>>>> for each DI container, much the same as a lot of other extension
>>>> modules work.
>>>>
>>>> Either that or a new DI abstraction which had the features Jersey
>>>> requires without the bloat of CDI. I would guess that a new
>>>> abstraction which fulfills an implementation's requirements is
>>>> harder to achieve and those interested in more DI abstraction have
>>>> probably already invested in the CDI specification.
>>>
>>> I can't speak for others, but I'm simply interested in getting
>>> the same functionality I had in Jersey 1.0. I want to be able to use
>>> either: only HK2, only Guice or only Spring at a time. I also need
>>> to be able to do this outside a JavaEE container. I am running Jetty
>>> inside a simple JavaSE application and I really appreciate how light
>>> this solution feels.
>>>
>>> Another difference I wanted to point out:
>>>
>>> * I expect Jersey to speak to the DI implementation through the
>>> abstraction layer, but...
>>> * Users should speak to the DI implementation directly.
>>>
>>> The point I want to make is that users don't have to learn yet
>>> another DI framework. The only thing that's new is having to
>>> register a DI framework once at startup. Past that point they should
>>> be able to use the native HK2, Guice and Spring constructs they are
>>> used to.
>>>
>>> Gili
>>
>