jsr366-experts@javaee-spec.java.net

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

From: Jason Greene <jason.greene_at_redhat.com>
Date: Thu, 5 Mar 2015 15:35:53 -0600

> On Mar 4, 2015, at 6:59 PM, Bill Shannon <bill.shannon_at_oracle.com> wrote:
>
> Jason Greene wrote on 03/02/15 15:09:
>> The only code thats allowed to execute from a CDI perspective, is the
>> portable extension class, which uses the service loader mechanism. Only when
>> deployment has completed can code in the CDI component classes execute.
>
> Right, but what is a portable extension allowed to do? Can it call
> web services? EJBs? In the same app? Can it access the database?
> Do JNDI lookups? Create threads? What resources are available?
> All of this really needs to be fully specified.

Well its loaded via a service loader interface, so it can do anything that Java code can do. We don’t define a naming context on it, so you couldn’t rely on a naming context. There is no injection context either, and its not a managed bean, so you can’t access resources, or CDI beans. I don’t think we say much in any of our specs about whether or not you can create threads, other than point people at the concurrency utils executors. It also is defined as running in deployment so its implied you can’t rely on anything else your deployment might do on setup.


>
>>> The inconsistency we're trying to clarify is between Chapter 5, which says
>>> that resource definition annotations can only appear on container-managed
>>> classes, and Chapter 8, which says that all classes must be scanned for
>>> annotations that specify deployment information.
>>>
>>> As I explained, there's some spec requirements, and use cases, that can't
>>> be implemented properly unless all classes are scanned. That's why it
>>> seems to us that this is just a clarification, not a change, and not an
>>> expansion in scope.
>>
>> I guess I just don’t agree that having to scan an annotation means you have
>> to define a component. To me this seems to be a bit of a false dichotomy. We
>> can certainly improve things without making every Java class a component.
>
> We're not making every Java class a component. Why do you think we are?

Well you are talking about enabling resource injection on every class, and that effectively makes them some kind of component. I guess the closest would be a managed bean, but without the @ManagedBean.


>
>>> If, in fact, the CDI implementation is discovering all the CDI managed
>>> beans at deployment time, and communicating that information to the
>>> container so that it can discover all the resource reference and definition
>>> annotations on those classes, we may be closer than I thought. Is CDI/Weld
>>> doing that?
>>
>> Yes but only for valid injection points, so if its not a Resource producer
>> then it wouldn’t be in that particular callback. That said the EE container
>> can participate in a number of ways as part of the process. And the SPI could
>> also be extended further.
>
> So CDI managed beans that contain @DataSourceDefinition annotations
> aren't being reported to the container? How does the container find
> those annotations if it's limiting itself to only the classes supporting
> injection?

Well you just only execute them if they are on a CDI managed bean, but you do need CDI logic to tell you that. The logic could either be the CDI RI via a lifecycle callback, or it could be a duplicated simulation.

>
> And since the spec clearly says that CDI managed beans support resource
> injection, they need to support all aspects of resource injection defined
> by the platform spec, not some limited cases related to CDI producers.

My interpretation is that the CDI spec limits this to producer fields. It was also the intention because the value of full resource injection to CDI applications is very low and duplicates a subset of functionality provided by CDI (Granted it doesn’t explicitly say you can’t do it, so I certainly understand why we have differing interpretations).
 
That said, we could certainly *add* support for EE resource injection to the CDI RI, and clarify in the CDI spec that all forms of EE injection are supported. It has to be implemented by the CDI container though, since the CDI container governs CDI managed bean instantiation, and only the CDI container (or something implementing the same rules) can define what is and is not a CDI managed bean.

>
>>> If so, then we know that all the other classes don't support injection,
>>> and thus shouldn't contain any annotations specifying injection. If they
>>> did, and those annotations were ignored, that might be a gap we could live
>>> with.
>>>
>>> That leaves us with these other classes specifying resource references or
>>> definitions at the class level. Since these classes can use JNDI to look
>>> up these resources at runtime, it seems perfectly reasonable for them to be
>>> able to specify resource references or definitions. You have to scan all
>>> the classes to find all the class level annotations anyway, so discovering
>>> these class level annotations should be essentially no additional cost. It
>>> seems like this is a perfectly reasonable use case that should work, and as
>>> we saw from my earlier poll, many developers expect this to work. And it
>>> works in the RI.
>>
>> Glassfish does not appear to be defining bindings on the CDI @Resource
>> values, unless I am looking at the wrong code, or its duplicated in some
>> other place (sorry if I am wrong about this, I still haven’t had time to test
>> it) .
>
> I tested it and it seems to be working for me.
>
> Again, what started us on this path is some bugs in the way GlassFish is
> handling some of this stuff, so we know it's not perfect. But in this case
> it seems to be doing what we expect.

Yes, I just tried it and it appears to be working in some cases. If you explicitly do a module or app reference it appears to bind. It seems to ignore default names (i’m guessing everything in comp?).

Standard EE resource injection and field injection doesn’t work, since the CDI RI doesn’t do it.

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