Dne 19.5.2016 v 18:47 Christian Kaltepoth napsal(a):
Hey all,
I would like to bring up an issue that we ran into while preparing Ozark
(the MVC 1.0 RI) to be usable as a container module in Glassfish. We
discussed this issue on Slack and discovered that Mojarra (JSF) and
Soteria (Security) had similar issues.
MVC 1.0 defines some extension points that users and 3rd party libraries
can implement to provide additional functionality. MVC uses CDI for
looking up all implementations of these extension point interfaces.
Similar concepts are used in in JSF. Historically JSF uses factories
which users can implement and register via faces-config.xml. Now for
Java EE 8 it was decided to prefer CDI to obtain such custom extension
point implementations (ViewHandler, NavigationHandler, etc). So
basically JSF uses a similar mechanism to lookup implementations of
certain interfaces like MVC does.
As of today Ozark is basically a standard bean archive deployed together
with the application (in /WEB-INF/lib). Now we want to prepare Ozark to
be usable as a Glassfish module which is provided by the container.
As CDI doesn't discover bean archives installed as part of the container,
Well, this is not necessarily true (although it's not required by the
CDI spec). Basically, it's the responsibility of the integrator to put
together the "final deployment structure".
we wanted to basically remove beans.xml and provide an portable
extension which registers the required annotated types required for
Ozark. AFAIK Mojarra and Soteria are also doing it this way. Now as soon
as we do this, things are getting weird.
There are various ways to get a BeanManager to lookup beans provided by
the application:
* CDI.current().getBeanManager()
* @Inject BeanManager
* JNDI lookup
Now if we try to lookup beans deployed with the application (in
/WEB-INF/classes or in a library in /WEB-INF/lib) we don't get
consistent results (many thanks to Arjan Tijms for doing all the testing):
* In Glassfish we don't see application beans if we use the injected
BeanManager. Looking up the BeanManager via JNDI or using
CDI.current().getBeanManager() works fine.
* In Wildfly CDi.current() doesn't seem to find beans deployed with
the application. The injected BeanManager and the one looked up via
JNDI works fine.
So it looks like there are quite some inconsistencies between
implementations here.
_To sum it up:_ In Java EE 8 more and more specs rely heavily on CDI.
And many specs allow the user and 3rd party libraries to implement
interfaces to extend functionality. But it looks like looking up such
beans deployed with the application from a container archive isn't
working in a consistent way.
I hope my explanation of this complicated topic isn't too bad. I hope
that we can start some discussion around this.
One important note - BeanManager is NOT a "central management API" for
CDI. It has a context (or at least few methods must be called in this
context) - a module or library containing the class into which it was
injected or the Java EE component from whose JNDI environment namespace
the BM was obtained.
CDI.current().getBeanManager() is a bit problematic. Esp. from impl.
point of view.
We should definitely think about this kind of integration issues.
Some of you already
joined the discussion on Slack and the corresponding pull request,
but I
would prefer to discuss this here. :)
Christian
--
Christian Kaltepoth
Blog:
http://blog.kaltepoth.de/
Twitter:
http://twitter.com/chkal
GitHub:
https://github.com/chkal
_______________________________________________
cdi-dev mailing list
cdi-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/cdi-dev
Note that for all code provided on this list, the provider licenses the code under the
Apache License, Version 2 (
http://www.apache.org/licenses/LICENSE-2.0.html). For all other
ideas provided on this list, the provider waives all patent and other intellectual
property rights inherent in such information.
--
Martin Kouba
Software Engineer
Red Hat, Czech Republic