Unlike CDI 1.0, the CDI 1.1 specification defines two types of bean archives: explicit and implicit. The first one is de facto the good old CDI 1.0 bean archive where all types in the archive are considered, i.e. the type metadata are inspected, the container must determine whether it is a bean, validate it, etc. If you place an empty beans.xml
or CDI 1.0-specific beans.xml
you'll end up with an explicit bean archive. If you want to follow the new XSD for CDI 1.1, the bean discovery mode must be set to all:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.1" bean-discovery-mode="all"> </beans>
The other type - implicit bean archive - is much more interesting and to be honest it also brings one compatibility issue. First let's look at the differences. The specification clearly states that an implicit archive contains one or more bean classes with a bean defining annotation, or one or more session beans. So that it doesn't have to contain a beans.xml
file. However it may contain a beans.xml
file with the bean-discovery-mode of annotated
.
For implicit bean archive the container only inspects Java classes annotated with a bean defining annotation during bean discovery. Bean defining annotation is any scope type (e.g. @RequestScoped
, @Dependent
). So this is more like good old Seam2 where a component must be explicitly designated. I think this is the real benefit of implicit bean archives in CDI 1.1 - disable automatic inspection of all types present in the archive without the need of exclude filters defined in beans.xml (exlude filters are now part of the spec, previously a special feature of Weld).
And now the issue. CDI is built on top of JSR 330 and makes use of its annotations (@Inject
, @Qualifier
, ...). Unfortunately javax.inject.Scope
identifies pseudo-scopes in CDI. And so any archive (even not intended to be a CDI bean archive) which contains a class annotated with any scope annotation becomes an implicit bean archive, i.e. beans are discovered, validated, etc. This might cause problems with archives which use any other injection framework based on JSR 330 (e.g. very useful Guava - Issue 1433).
One solution is to use beans.xml with the bean-discovery-mode of "none" - this tells the container to skip the archive. However this also breaks backwards compatibility, because such an archive will be recognized in CDI 1.0.
The CDI 1.1 also states:
"For compatibility with Contexts and Dependency 1.0, products must contain an option to cause an archive to be ignored by the container when no beans.xml is present."
It seems this is the only way to handle this issue correctly. On the other hand it makes your application non-portable. If you have any idea how to fix it post a comment to CDI-377.
UPDATE: A colleague of mine (thanks Jozef!) pointed out that there is one more possibility - according to the spec an archive which contains a CDI extension and no beans.xml
file is not a bean archive either. But of course this is rather a hack solution for our problem.
See also the CDI 1.1 specification, section 12.1. Bean archives and 12.4. Bean discovery.
Comments