*** Updated ! ***
I came over this problem when I moved an existing Java EE 7 application from WildFly 8.1.0.Final to 8.2.0.Final. The application is a pure Java EE 7 application with no external dependencies, so you would think it should run without any changes when upgrading the minor verision of a Java EE 7 compliant application server.
In my code I have a LogProducer
which enables me to inject the logger using @Inject
and this producer was annotated with the javax.inject.Singleton
. This works fine in WildFly 8.1.0.
import java.util.logging.Logger; import javax.enterprise.inject.Produces; import javax.inject.Singleton; import javax.enterprise.inject.spi.InjectionPoint; @Singleton public class LogProducer { @Produces public Logger producer(InjectionPoint ip) { return Logger.getLogger(ip.getMember().getDeclaringClass().getName()); } }
But when I started it in Wildfly 8.2.0, I got the infamous WELD-001408:
org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type Logger with qualifiers @Default
The reason for this is that Wildfly 8.2.0 builds upon Weld 2.2 (CDI 1.2), while Wildfly 8.1.0 builds upon Weld 2.1.2 (CDI 1.1). To make the producer work in WildFly 8.2.0, I had to change the annotation to javax.ejb.Singleton
.
import java.util.logging.Logger; import javax.enterprise.inject.Produces; import javax.ejb.Singleton; import javax.enterprise.inject.spi.InjectionPoint; @Singleton public class LogProducer { @Produces public Logger producer(InjectionPoint ip) { return Logger.getLogger(ip.getMember().getDeclaringClass().getName()); } }
As pointed out in the comments, using an EJB as a producer may not be the most efficient or correct way. In this case I prefer to use @ApplicationScoped
as shown below.
import java.util.logging.Logger; import javax.enterprise.inject.Produces; import javax.enterprice.context.ApplicationScoped; import javax.enterprise.inject.spi.InjectionPoint; @ApplicationScoped public class LogProducer { @Produces public Logger producer(InjectionPoint ip) { return Logger.getLogger(ip.getMember().getDeclaringClass().getName()); } }
In the current version of NetBeans (8.0.2), this will produce a warning regarding the injection point, Bug 244173.
You could also change @Singleton to @ApplicationScoped or created a @Stereotype with @Singleton in it or switch to “all” bean discovery mode.
More info in CDI 1.2 spec “bean defining annotations” section: http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#bean_defining_annotations
This is because the upgrade from CDI 1.1 to 1.2 and the correction in Bean Defining Annotation definition (correction to prevent applications using Spring, Guice or Dagger to crash in a EE server)
http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#bean_defining_annotations
Seems like your beans.xml is in “annotated” discovery mode and @Singleton (from JSR 330) left the list of bean defining annotation.
There are 2 other cleaner solution (with less side effect) than transforming your Bean to EJB :
1) Use @ApplicationScoped
2) Create a Stereotype with @Singleton and use it on the bean
The 3rd solution would be to change te discovery mode to all but it could bring other side effects.
Thanks to both of you! I have no beans.xml file, thus is in “annotated” mode. I think I will transform by using @ApplicatonScoped. It felt like a bit of an overkill to have this simple producer as an EJB 🙂