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

From: Bill Shannon <bill.shannon_at_oracle.com>
Date: Wed, 18 Mar 2015 15:38:53 -0700

Jason Greene wrote on 03/17/15 11:53:
>> On Mar 16, 2015, at 3:39 PM, Bill Shannon <bill.shannon_at_oracle.com> wrote:
>> I'm finally picking up this conversation again after several days of
>> vacation and catch-up...
>> Jason T. Greene wrote on 03/05/15 22:58:
>>>> On Mar 5, 2015, at 7:28 PM, Bill Shannon <bill.shannon_at_oracle.com>
>>>> wrote:
>>>> Jason Greene wrote on 03/05/2015 04:04 PM:
>>>>> Looking into the weld history, it turns out that the CDI RI did
>>>>> subsequently add everything (method support etc) except for the
>>>>> class annotations bit.
>>>> So maybe there's only a small implementation bug?
>>>> My expectation (based on the wording in Chapter 8 of the platform spec)
>>>> was that CDI didn't need to know anything about these class level
>>>> annotations because the deployment process would scan all classes and
>>>> find them and process them at deployment time. I think that's what's
>>>> happening in the RI, so I don't think the RI needs Weld to tell it
>>>> anything about them.
>>> Well the problem is still that if you go by table 5-1, only CDI managed
>>> beans should be eligible, and to know that you need to evaluate the rules
>>> according to CDI.
>> Yes, the confusion is that 5-1 is only supposed to be telling you where
>> injection works, because obviously injection can only work on classes that
>> are managed by the container. It was not intended to be telling you where
>> resources can be defined.
> Yeah I guess see these aspects as intertwined since both the bindings and the
> injection are defined from the perspective of a component. Namespace handling
> and inheritance aside, should an @Resource declared on a field of a
> non-component class define a binding?

It would be reasonable to consider it an error, since injection could
never occur, but that's way to difficult to figure out at deployment
time (just like what's actually a managed bean and what's not) so we
decided to keep the rules simple - all the classes were to be scanned
for all these annotations. I now know that not everyone understood
that that was the intent. :-(

>>>> Would you care to summarize where we are now? :-)
>>> Yes, if you don’t mind I’ll just put it all in this email, instead of
>>> replying in piece-meal.
>>> In a nutshell, we have a big mess :) Cleary the contradictions in the
>>> various specs have lead to a mishmash of differing behavior.
>> Yup! And we'll all be better reviewers of the spec in the future, right?
>> :-)
> Hopefully :)
>>> - Some of us are doing this at a component level (JBoss, IBM, JonAS).
>>> Some everywhere (RI, Geronimo).
>>> - Resource bindings on CDI managed beans seem universally broken in ejb
>>> jars and ear/lib. On JBoss/WildFly they are not done at all. On the RI
>>> they appear ignored if they are in comp. Since the CDI spec itself, and a
>>> lot of existing code do not define a name value with resource, those
>>> resources are all in comp.
>>> - On JBoss/WildFly, Resource bindings on @ManagedBean default to
>>> java:module (based on our interpretation of MB 2.1.2 and or expectation
>>> that a defaulted @Resource should not fail).
>> Ya, that was way wrong. MB.2.1.2 says nothing about @Resource names.
> Sorry I meant MB 2.1.3: ". A Managed Bean does not have its own
> component-scoped “java:comp” namespace. For this reason, Managed Beans should
> define resources in the “java:module” namespace or above.”

Right, that was a recommendation for what applications should do, not
a requirement on implementations.

>>> The RI on the other hand stuck with a uniform interpretation of them
>>> being in comp, which is consistent with the 250 javadoc. Since comp is
>>> ignored on non-components, it also does not fail.
>>> - ejb-jar.xml only allows DD ref overrides on ejbs and interceptors, so
>>> managed beans and CDI managed beans can’t be overridden there (portably)
>> At one point we planned to address this by adding the ability to specify
>> module-level resources in the ejb-jar.xml not associated with any EJB
>> component. I don't remember why that got dropped, but maybe it's time to
>> bring it back.
>>> - metadata-complete isn’t accurate with the latest definitions to the EE
>>> spec, since not all components are described in DDs (Managed Beans, CDI,
>>> Web Sockets, JAX-RS, etc). You can’t implement an EE7 container without
>>> processing annotations.
>> metadata-complete was never intended to say that. It only ever talks about
>> how the deployment process uses metadata-complete when looking for
>> deployment information. There's lots of other uses of annotations that
>> have nothing at all to do with deployment. The spec even says explicitly
>> that other specs that also use annotations and xml descriptors might want
>> to define their own metadata-complete.
> If I have meta-data complete set to true am I supposed to get resource
> injection on the components listed above that can not be defined in XML?

If you have metadata-complete set, and the metadata (deployment descriptor)
lists a resource reference with an injection point in a CDI managed bean
(for example), then yes, injection must occur.

I expect this to work if the resource reference is in a web-app.xml or
application.xml or application-client.xml file. The ejb-jar.xml case
is more problematic due to the lack of ability to separately declare
module-wide resources.

>>> - CDI portable extensions probably need additional environment
>>> clarifications (and probably other extension mechanisms, e.g. web sockets
>>> extensions)
>>>> What do you think *should* work (even if some implementations are
>>>> broken)?
>>> I strongly feel we shouldn't break any vendor's compatibility to fix this
>>> in EE7. We should do minor stuff that gets us closer.
>> We can defer some of these changes, but if that means another 3 years of
>> inconsistent behavior, I'm worried that we'll never be able to fix it.
>>> However, even with EE8, I think that the inheritable nature of Resource
>>> annotations makes it too problematic to apply across the board to all
>>> classes. Further, I think inheritable behavior is a necessity, since the
>>> active relative context always applies to the subclass.
>>> Specifically I think:
>>> - The default namespace for binding names should be comp if there is a
>>> component namespace, otherwise module if there is a module namespace,
>>> otherwise app.
>> I think it's too late to change this, and I'm not convinced that having
>> different defaults in different cases wouldn't be more confusing.
> One other way to achieve the same thing is we could define a comp namespace
> for components that do not have one, as an alias to either module or app
> (depending on the location). This would offer similar behavior to definitions
> in a WAR.
> IMO it makes no sense for a defaulted name attribute to be a failure:
> @Resource DataSource blah;
> The above should just work whether its defined on a component in a war, or on
> a component in an ejb jar.

I understand the desire, but I'm afraid we've painted ourselves in a
corner with some of our previous decisions.

We could put all of these in the "unnamed component's namespace", but
then there might be unexpected conflicts.

We could treat each class as if it were its own component, but I'm not
sure that's implementable, at least not without a lot of additional

I'm open to suggestions for how this should work, but remember that you
have to be able to override, and thus name, the resource reference in
the deployment descriptors.