[jsr366-experts] Resource Injection Strategy (Was: Compatibility ... )

From: Jason Greene <jason.greene_at_redhat.com>
Date: Fri, 20 Mar 2015 13:34:03 -0500

> On Mar 16, 2015, at 3:39 PM, Bill Shannon <bill.shannon_at_oracle.com> wrote:
>> - Resource annotations should only create bindings on component classes (and
>> their supertypes). This avoids optional or disabled code from creating
>> bindings.
>> - Either the existing all classes scanning mode in beans.xml, or applying a
>> component annotation can be used to expand this to almost everything.
> I'm really torn on the two above. My original goal was that deployment
> did *NOT* need to run any application code. Running CDI bootstrapping
> during deployment really messes that up. I should be able to deploy an
> application without starting it, and not have to create any class loaders
> or initialize any containers for the application.
> The disadvantage of this approach is that the deployment process doesn't
> have access to all the information that CDI collects, and so can't tell
> which beans are actually usable. Again, our original plan was to expose
> some of these capabilities in the deployment descriptors. We probably
> need it there anyway for lots of cases that don't involve CDI.
> So, while I see the attraction of using the results of the CDI bootstrap
> at deployment time, I think it's simpler if we don't have to do that.
> I need feedback from the expert group on what the right approach is here.

I went through the thread again, and reexamined all of the various arguments. I think what this comes down to is whether or note we view resource injection and CDI as integrated or an orthogonal common facility. The former has the benefit in that you get things declared in one place with some consistency. Following my previous example, if you veto a bean then not getting the resource bindings it defines feels intuitive. However, thinking it over again I am not sure such benefits will be fully realized by users, since the whole advantage of using CDI is that you have injection facilities available, and there is really no need to define JNDI bindings. The latter has the benefit in that you can have a consistent independent behavior with and without the presence of CDI.

While I stated a preference for the integrated approach, I would be ok with just keeping them independent and thereby expanding the set of available classes for it, provided that:

A) We provide an exclusion facility for EE resource injection (i.e. class name globing and perhaps jar exclusions)

B) We come up with a graceful way to handle non-component classes that have comp names.

There are two forms of B) that we need to care about.

1) Defaulted names (e.g. @Resource DataSource blah, @Resurce(name=“foo”) DataSource foo) which should just work

2) Usage of explicit comp names on a non-component class, which was previously allowed by many if not all implementations in one way or another, and was typically used as a (potentially optional) base class that when combined with a component subclass creates a valid binding.

I had originally suggested addressing (B) by just having the class location determine the default scope. For example, if a non-component class is in an ejb-jar, then it would create bindings in the module namespace. However, the addition of processing non-component classes means that this could very well be a new source of conflicts, in particular with case (2) when used on an ejb-jar, since component namespaces are fully independent.

I am proposing that we instead do three things to address (B) (assuming we decide to go the all-classes route):

X) Treat all comp bindings on non-component classes which are not in a war as valid but unbound. This addresses (1) and (2) fully, allowing a great deal of past code, including snippets in the CDI specification itself to work unchanged. The RI already seems to be doing some form of this.

Y) Enhance the relevant deployment descriptors to support redefining the binding, perhaps by reusing injection-target-class for class bindings. I think this fits the original intentions you highlighted in past emails.

The one case this does not address is what happens when a non-war non-component lookup class specifies comp in its lookup attribute. However, (Y) and (A) could be used to correct such occurrences.

Jason T. Greene
WildFly Lead / JBoss EAP Platform Architect
JBoss, a division of Red Hat