jsr366-experts@javaee-spec.java.net

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

From: Jason Greene <jason.greene_at_redhat.com>
Date: Fri, 20 Mar 2015 15:29:50 -0500

> On Mar 20, 2015, at 2:04 PM, Bill Shannon <bill.shannon_at_oracle.com> wrote:
>
> Jason Greene wrote on 03/20/15 11:34:
>
>> 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)
>
> Do we need a general exclusion facility, or should we tie this to some sort
> of deployment profile/stage facility that describes when to use which
> resources?

I was thinking a general static resource-injection specific exclusion facility.

Perhaps:

     <exclude-injection-target>
       <class>org.foo.Base</class>
     <exclude-injection-target>
     <exclude-injection-target>
       <class-pattern>org.foo.*</class-pattern>
     <exclude-injection-target>
    
The notion could be expanded to a profile facility, in particular if you defined profiles as being just being an outer wrapper of most deployment descriptor items.

>
>> 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 definition is poorly worded. I should have said “Classes that do not have a JNDI component namespace may have a name attribute that declares a comp/env value (either directly or indirectly via defaults), but such values do not have a reachable JNDI binding"

>> 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.
>
> What do you mean by "unbound”?

I mean that name is not reachable from JNDI, yet the injection portion still functions. So as an example if I have a CDI bean (or managed bean) in an ejb-jar, or ear/lib

@Resource DataSource foo;

The “foo” field will contain the platform default data source, and no error will be produced.

If the underlying class does not have a lifecycle managed by the container (not a Java EE component), then these references wouldn’t effectively do anything, because the binding would not be reachable. However, if another class which had a component naming environment subclassed them, then they would start to do something.


>
>> 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.
>
> Is this more than letting you specify resource references in an ejb-jar
> file at the module level?

It’s basically the same, it's just that it would allow you to reference comp as well as module. This would allow you to consistently override this new unreachable/unbound binding for classes which receive injection.

It could look something like this:

<class-based-injection>
   <class-name>org.foo.MyCDIBean</class-name>
   <resource-ref>
      <res-ref-name>org.foo.Bean/foo</res-ref-name>
      <lookup-name>java:global/env/SomeOtherDS</lookup-name>
   </resource-ref>
</class-based-injection>
  

>
>> 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.
>
> I'm not sure exactly what your example is, but it sounds like this should
> be an error case. Is that your proposal, and that the deployer can correct
> the error by overriding the mapping?

Yes thats correct. If you assume that a common base class which was previously ignored by an implementation had:


@Resource(name=“NewName”)

and

@Resource(name=“OldName”, lookup=“java:comp/env/NewName”)

This would fail, but could be remapped or excluded by the deployer.

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