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

From: Jason T. Greene <jason.greene_at_redhat.com>
Date: Tue, 3 Mar 2015 19:19:02 -0500 (EST)

> 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 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.

>> 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.

> 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.

> 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.