[jsr342-experts] Re: Proposal for global CDI enablement

From: Pete Muir <pmuir_at_bleepbleep.org.uk>
Date: Fri, 14 Dec 2012 13:28:07 +0000

On 13 Dec 2012, at 23:02, Bill Shannon wrote:

> Thanks for putting this together, Pete! I think this is a good compromise
> that will help the community. I have some questions and some comments...
>> Only classes with a bean defining annotation, or with an annotation,
>> or meta-annotation, present specified by @WithAnnotations are passed to
>> ProcessAnnotatedType observers (the exact semantics are defined by CDI 1.1
>> PRD for @WithAnnotations). As mentioned above, if a ProcessAnnotatedType
>> is observed for a type without a bean defining annotation, as a result
>> of having an annotation present that is specified by @WithAnnotations,
>> it may instruct the container to add discover the class as a bean.
> I'm trying to understand the impact of this on the implementation.
> If I remember correctly, portable extensions are discovered using
> java.util.ServiceLoader, is that correct?


> After discovering
> the services during CDI initialization, CDI looks for the
> @WithAnnotations annotation and notifies the extension of the
> classes it's interested in.


> That means that CDI must have at
> its disposal a list of *all* classes with any annotation the
> could ever possibly be specified with @WithAnnotations, is that
> right?

Right. This would be a container specific integration SPI, that would be defined e.g. by Weld or OWB. I suspect it would be more likely implemented as an external lookup. But like I say, nothing guaranteed.

> And even worse, for those portable extensions that don't
> use @WithAnnotations, CDI needs to have a list of all classes in
> the application, right?

In short, no. Only for archives deployed the 1.0 (beans.xml enabled) way. For the CDI 1.1 way (bean defining annotation) you must use @WithAnnotations to receive any classes that don't have a bean defining annotation on them.

> So even though CDI might define many fewer beans by default, it
> still needs to be able to find out about all classes in the application,
> and in that respect it's the same as CDI 1.0.

No, as per my previous answer. It will only need to classload classes with bean defining annotations or those added by @WithAnnotations. This can be totally done through byte-code scanning, there is no need to classload the classes.

> The reduced overhead is
> not in the class scanning or annotation discovery, its in the bean
> initialization, right?

The reduced overhead is in not requiring classloading of all classes, instead allowing annotations to be discovered by byte-code scanning. Our analysis suggests that around 80-90% of the initialization time of CDI is spent classloading. If we can restrict what gets classloaded to just that which the user explicitly specifies, this should help a lot. If you used reflection to do your scanning, then yes, this would increase overhead.

>> OPEN ISSUE: Should auto-discover be false by default for beans.xml with
>> version 1.1. This would mean that adding a beans.xml would have no impact
>> on discovery for 1.1 apps, however it is a significant change from 1.0.
> There's some potential cost to developers (in confusion) if you change the
> behavior when a beans.xml is present, but if you don't think that's a big
> issue the default should probably be the programming model you most want
> to encourage.

If we were defining this in 1.0, then I would say yes to this question.

>> OPEN ISSUE: Should only scopes for which a CDI context exists be
>> considered component defining? This could introduce some thorny edge
>> cases, but would address the JSR-330 compatibility issue better.
> How does a CDI context come to exist for a given scope?

Either there are built-in ones defined by the spec, or an extension explicitly adds one using an API.

>> OPEN ISSUE: Should we extend auto-discover in
>> beans.xml to allow complete disablement of scanning
>> e.g. auto-discover="all|bean-defining-annotations-only|none" ?
> This seems reasonable, although I would probably name it something like
> "beans=all|annotated|none".

Yes, naming is definitely still open.

>> OPEN ISSUE: How should the ProcessAnnotatedType event instruct the
>> container to discover a class as a bean? Perhaps something like
>> event.discover(clazz)?
> I don't understand this issue.

ProcessAnnotatedType may be observed for classes that don't currently have a bean defining annotation, but are picked up due to @WithAnnotations. We want to allow the extension to say "this class should be discovered as a bean". How should we do that?

>> OPEN ISSUE: Should we integrate this with the package level scanning
>> control we have proposed for CDI 1.1?
> I'm not familiar with the package level scanning control, but this sounds
> like a reasonable approach.