easy solution for class visibility checks?
by Mark Struberg
Hi folks!
I just had an idea which is so simple that I just cannot believe it!
So please review and ping me if I missed something.
This topic is related to CDI-18 (BDA dropping) and CDI-129 (@EnterpriseApplicationScoped)
What is the problem with CDI-1.0?
Well, CDI-1.0 says nothing about class visibility, but instead tries to solve all those issues by introducing the BeanDefinitionArchive (BDA). This in turn creates more harm than good.
An example of such a broken use case would be that it is currently allowed to have a public class @Singleton MyService {} residing in shared EAR jar being @Specialized by a public class @Singleton MySpecializedService extends MyService {} residing in WEB-INF/classes of one single webapp.
Obviously (with a JSR-316 conform 'sane' classloader hierarchy set up) this will not work. Because MySpecializedService is not visible from the EAR nor the other webapps (because of the ClassLoader isolation).
In CDI-18 I proposed to add the following rules:
> The container must ensure that for any
> * @Specializes @NScoped class Y extends X and
> * @Alternative @NScoped class Y implements X
> class Y is accessible by all classes which can access X in the same @NScoped context.
The problem now is: how does a custom 3rd party scope determine those rules?
Because the issue is not only valid for @EnterpriseApplicationScoped. Just imagine to add a @SystemScoped which is a singleton-per-JVM (residing in the System or extension ClassLoader), or a @ClusterScoped, ...
Today I realized that the *only* relevant thing is actually if the context maintaining the scope of 'class Y' (see definition above) can see the class Y.
It is just not valid to write a @EnterpriseApplicationScoped public class MyService if the EnterpriseApplicationScopedContext cannot see MyService.
The easiest solution would be to add a method to Context which checks the visibility at startup:
boolean isVisible(Class beanClass) or
boolean isVisible(String className) (need to think about which one works better, esp with different scenarios)
Of course since #addContext is only in AfterBeanDiscovery, we need to do this in some 'verifyDeployment' phase after the bean scanning.
wdyt?
Is the intention clear? Or should I bring more samples about how that would work?
Is there any flaw in there which I have overlooked?
LieGrue,
strub
12 years, 12 months