users@jersey.java.net

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

From: cowwoc <cowwoc_at_bbs.darktech.org>
Date: Wed, 30 Oct 2013 13:42:19 -0400

On 30/10/2013 12:19 PM, Cameron Jones wrote:
> I don't have experience with Guice so i can't comment on the
> particulars, but my experience with DI containers suggests that they
> all want to be the "one container to rule them all" so none have made
> any attempts to integrate.

     Agreed.

> If you consider that for a DI container to do what it is supposed to
> do, it needs access to the entire set of classes for a single pass,
> then is it any wonder that containers don;t provide this functionality?
>
> It would introduce additional complexity to construction and the
> potential for runtime errors which they go to extremes to avoid.

     Sorry. I didn't understand this point.

> 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?
>
>
> This predates HK2 as was from JAX-RS 1.0. When you consider that when
> it was developed there was no DI other than XML Spring and annotations
> were a new feature for JDK5 then this requirement can probably be seen
> as a relic with established ground which has since been superseded by
> the establishment of alternate conventions in CDI. Much the same as
> @Context wouldn't exist if @Inject were available at the time.
>
> Given that JAX-RS chose to retain it for v2 and Jersey is the RI for
> JAX-RS, the likelihood of this being repealed or willfully disregarded
> is unlikely.

     It seems to me that, except for HK2, no one is bothering to
implement this requirement. Not now, nor back in Jersey 1.0. It should
be removed because there is no practical need for it, nor is it
providing any practical benefit because no one is following it (hence it
doesn't improve portability).

> HK2 doesn't really do anything special compared to other DI
> containers, it's just a JSR-330 container.
>
> I'm sure it's feasible for any DI container to be configured for the
> JAX-RS model, but such non-trivial configuration would require a
> codebase for the task.

     I don't think you can implement the above requirement for
constructors for Guice no matter how much code you threw at it. Guice
has its own rules for constructor resolution (as does Spring) and there
are no facilities for altering these. And again, I fully agree with
them... because this kind of thing should be out of scope for JAX-RS.

>>
>> 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.
>
>
> Likewise, I think its wrong to blame HK2's - it's just comparable to a
> Guice/Spring DI container.

     I'm not so much blaming HK2 so much as Jersey :) I think the Jersey
committers made a reasonable assumption that DI integration can be
delegated to HK2, but then failed to validated this assumption before
shipping 2.0. What makes this worse is that I explicitly warned them of
this risk before the 2.0 release (asking them to delay the release until
adding Guice/Spring support) but they ignored me.

     I want to point your attention to
http://lcsd05.cs.tamu.edu/slides/keynote.pdf slide 10. Specifically:

  * Write multiple plug-ins before release
      o If you write one, it probably won't support another
      o If you write two, it will support more with difficulty
      o If you write three, it will work fine

     We should have released fuctional HK2, Guice and Spring modules
before the 2.0 release to validate the design. Now that 2.0 is out the
door, it might be more painful, but we should strive to complete this
work and alter the design until all 3 can be accommodated.

     I also want to point your attention to
https://java.net/jira/browse/JERSEY/#selectedTab=com.atlassian.jira.plugin.system.project%3Apopularissues-panel.
Notice what the most requested feature is (by a large margin, I might add).

> The problem is that there has been a feature regression within Jersey
> between v1 and v2.

     That's a big part of it. I managed to hack my way past HK2 by
creating a Guice module for UriInfo and other built-in types but then I
got stuck on https://java.net/jira/browse/JERSEY-2172 and there is no
workaround. I encourage you to vote for this issue :)

> Sure, the furthest i got is in trying similar integration with SE CDI.
> I probably got about as far as you have but had to stop to get on with
> some other work.

     I haven't seen a single successful DI integration with Jersey
except for HK2. Even the integrated Spring module isn't as functional as
it seems. To me this is a "code smell" that indicates a
design/architecture-level problem.

Gili