Things can get weird when java SE code developed with IOC
is deployed into a java EE container that implements CDI. For example - the
littleware code I work with
implements simple modules and life cycle management with guice, so when
I deploy that code in a webapp to a glassfish server I want guice's runtime to
manage littleware's dependency injection, but I might also want CDI to inject
a glassfish-managed JPA EntityManager into a servlet for me, and both guice and
CDI are scanning for the same javax.inject runtime annotations.
Fortunately - this kind of thing worked fine for me until recently, since CDI 1
as introduced in java EE 6 ignored jars that did not include a META-INF/beans.xml file.
Java Enterprise Edition 6
introduced
JSR-330 (javax.inject annotations and provider interfaces)
and JSR-299 (CDI - contexts and dependency injection) to the java-ee platform.
The javax.inject package standardized the annotations and interfaces used
by java's various inversion of control and dependency-injection systems
(guice,
spring,
dagger,
pico container, ...),
so that code written with one IOC system in mind could be more easily used
in an application that deployed to another system.
CDI
introduced an IOC implementation for java enterprise edition (EE)
technologies (servlets, JSF, EJB, JPA, ...) deployed in EE containers
like glassfish,
jboss,
weblogic,
and websphere.
I discovered CDI's behavior changed slightly in the new java EE 7 runtime
when a webapp that ran fine in glassfish version 3 (a java EE 6 container) failed to deploy
under glassfish 4 (the EE-7 reference implementation).
The errors in the glassfish-4 logs lead me to
this ticket in guava's bug database.
It turns out that CDI's new version 1.1 runtime automatically scans all jars
deployed with an enterprise application, and guava-14+ includes a couple classes with javax.inject
annotations that CDI processed in an unintended way
(littleware still uses guice's com.google.inject package annotations and interfaces, so CDI ignored those).
I eventually found one easy solution to this javax.inject - CDI 1.1 mix-up is to add
a META-INF/beans.xml CDI config file to jars that include javax.inject annotations that require
special or no handling by CDI. I added the following META-INF/beans.xml with a
bean-discover-mode attribute
set to "none" to the guava jar in
my webapp, and that solved the problem. Hopefully guava's maintainers will add a similar beans.xml file to
guava's binary distribution on maven central.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="none">
</beans>