jsr366-experts@javaee-spec.java.net

[jsr366-experts] Re: Compatibility Problems with MR Resource Annotation Widening

From: Bill Shannon <bill.shannon_at_oracle.com>
Date: Wed, 04 Mar 2015 17:00:45 -0800

Jason T. Greene wrote on 03/03/15 16:19:
>
>
>> On Mar 3, 2015, at 5:59 PM, Bill Shannon <bill.shannon_at_oracle.com> wrote:
>>
>> Jason Greene wrote on 03/02/15 14:34:
>>>
>>>> On Feb 27, 2015, at 5:38 PM, Bill Shannon <bill.shannon_at_oracle.com>
>>>> wrote:
>>>>
>>>> Jason Greene wrote on 02/27/15 09:51:
>>>>>
>>>>>> On Feb 26, 2015, at 9:02 PM, Jason Greene
>>>>>> <jason.greene_at_redhat.com> wrote:
>>>>>>
>>>>>> So my recollection, was that this was intentional since the
>>>>>> bindings arenít useful to CDI applications, and you could always
>>>>>> reference another binding defined by a component which did support
>>>>>> it, if you needed such behavior. The deployment descriptor for CDI
>>>>>> doesnít allow you to override these bindings, and the other
>>>>>> deployment descriptor locations donít cover the full set where
>>>>>> @Resource can appear (for example ejb-jar overrides are defined on
>>>>>> ejb components and not globally). Finally, @Resource (and the other
>>>>>> EE bindings) can only appear on producer fields, which is a subset
>>>>>> of what 250 defined.
>>>>>>
>>>>>> Iíll ping Pete to see if he remembers the same, but yeah I agree
>>>>>> the combination of the specs implies that it should work, other
>>>>>> than the fact that it canít work the way the global rules are
>>>>>> defined.
>>>>>
>>>>> BTW I confirmed that this matched Petes understanding as well.
>>>>>
>>>>> There was never any interest for CDI managed beans to support:
>>>>>
>>>>> - Creation of @Resource (et al) JNDI Bindings - Usage of @Resource
>>>>> (et al) Class declarations - Usage of @Resource (et al) Method
>>>>> injection
>>>>>
>>>>> These all have no benefit to CDI applications because they are all
>>>>> superseded by other constructs. The annotations were just reused for
>>>>> the ties just to avoid creating new ones.
>>>>
>>>> Except that there's nothing anywhere in the spec that says in this
>>>> specific case you don't have to create the bindings that the spec says
>>>> you have to create. And for all the reasons described previously, we
>>>> would not want the spec to say that.
>>>
>>> My point is that even if you added in the bindings the semantics are
>>> still different. You arenít really using EE injection (in the traditional
>>> sense) when you define @Resource on a CDI bean.
>>
>> I don't know why you say that. There's nothing in the spec that says in
>> this one special case you don't have to do what you have to do in all the
>> other cases.
>
> The CDI spec states that resource injection is used on field producers, any
> other behavior is not specified, therefore it is not the same.

The behavior of resource injection in all cases is specified by the
platform spec.

CDI field producers just specify that a field contains a value that
should be used when CDI needs to produce something of that type.
How that field is initialized is completely independent of the fact
that the value of that field is used for a producer. The field might
be initialized statically, by a post construct method, or by resource
injection.

>> The reason this case is supposed to work is because the container is
>> handling it just like all the other cases, including creating a JNDI entry
>> and including allowing you to override that entry using a deployment
>> descriptor.
>>
>>> You are instead defining a CDI field producer that does a resource
>>> lookup. In fact if you just renamed "@Produces @Resource" to be
>>> ď@Produces @JNDIObject", this confusion likely would have never
>>> occurred.
>>
>> Because that would've been a different spec with different semantics. Maybe
>> that's the spec that some people wanted, but that's not the spec we have.
>
> Well again the spec we have doesn't allow it either, since everything would
> break.

I don't know what spec you're talking about because the spec we have
*does* allow it. Why do you think that breaks anything?

>>> You could add full Java EE injection to CDI managed beans, but itís a lot
>>> of spec work that would serve little purpose. The whole point of CDI is
>>> to offer a strong type-safe injection mechanism, and for that reason CDI
>>> forces you to minimize your usage of @Resource to a single location that
>>> is then @Inject-ed where needed. If we defined the rest, we would end up
>>> saying ďHey this never worked before. We made it work now, but still
>>> donít use it.Ē
>>
>> There's nothing that says you can only use resource injection in this
>> special way. It's simply a combination or two existing capabilities, with
>> no special cases needed. The Java EE container fills up the field with the
>> injected resource reference. CDI doesn't know or care how that happens.
>
> Yes it does, which is why it defines it to be on producer fields.

I guess we're reading the spec differently. I read section 3.7 of the CDI
spec to be describing how to use the existing Java EE resource injection
capabilities to make those resources available to the rest of CDI using
CDI dependency injection. I don't read it as in any way limiting the
use of Java EE resource injection for other purposes. And in fact the
Java EE platform spec clearly states that CDI managed beans can use Java EE
resource injection.

>> CDI uses the value of that field for @Produces. Java EE doesn't know or
>> care how the value of that field is used. That was the beauty of combining
>> these two existing capabilities. We defined Java EE resource injection to
>> work for CDI managed beans so that we could combine these two features
>> without either having to know about the other.
>>
>>> Iím hoping we keep the scope limited by either letting CDI have its own
>>> semantics, or we change it to define bindings consistent with EE
>>> resource injection and stop there.
>>
>> It's kind of late to back out of what we defined some time ago. We're
>> definitely not going to change the semantics of @Resource so that it works
>> differently in some cases.
>>>>> In an early CDI draft there was a complete xml description language
>>>>> in beans.xml that could be used to override/define all aspects of
>>>>> CDI managed beans (including annotations). However, that was dropped
>>>>> since portable extensions allowed third party definitions of such a
>>>>> thing.
>>>>
>>>> I only ever expected that to be able to change how @Inject worked, not
>>>> change how @Resource worked, since @Resource was defined by the
>>>> platform spec and not the CDI spec.
>>>>
>>>>> The bindings, if desired for consistency purposes, could be addressed
>>>>> by the EE spec, and the existing CDI RI looks like it already can
>>>>> support that. Class declarations could likewise be addressed, but
>>>>> would probably require some CDI RI SPI improvements. Method injection
>>>>> on the other hand probably would require CDI spec involvement.
>>>>
>>>> The platform spec clearly requires that these bindings are created,
>>>> always.
>>>>
>>>> If you extract all the annotation information from an application using
>>>> whatever technique you think is correct, turn it into the
>>>> corresponding deployment descriptor information, merge it into the
>>>> deployment descriptors, set metadata-complete, and remove all the
>>>> annotations from the application, will the behavior be the same? It
>>>> should. That was clearly our intended design when we introduced these
>>>> annotations and extended the deployment descriptors to allow injection
>>>> to be specified.
>>>
>>> If you use any element of CDI in your application (whether @Resource is
>>> done by CDI or by something else, or not used at all) then no. CDI does
>>> not define an xml format that can substitute all usage of its
>>> annotations. You could do it with a portable extension that defined one
>>> though.
>>
>> metadata-complete has no effect on CDI. But you absolutely must be able to
>> use CDI with an application that also uses metadata-complete. You'll still
>> need to use the CDI annotations, since CDI doesn't provide an XML
>> equivalent, but all of the Java EE resource references and definitions and
>> injections can be specified in the deployment descriptor instead of using
>> the corresponding annotations.
>
> Not the way the CDI spec is defined. The CDI spec explicitly states that EE
> resources are declared as annotations on a field producer.

Again, that's just an example of how to bridge Java EE resource injection
and CDI dependency injection. It's not a limitation on Java EE resource
injection. Java EE resource injection is specified in the platform spec,
not the CDI spec.

>> It's been a design goal of all of the Java EE resource annotation support
>> (but not of *all other* annotation support), that everything you can do
>> with these annotations you can also do with the deployment descriptors.
>> This lets you convert the annotations into deployment descriptor entries,
>> set metadata-complete, and then customize the resource information without
>> changing the application.
>
> Maybe but that's not how CDI was intended to work, specified in the spec, and
> actually implemented.

If there's a bug here, it's in the CDI implementation, although as far
as I can tell with some simple tests, this *is* working correctly in
the Java EE RI.