After 2 days of debugging and trying I have no other idea than asking you for a solution.
I want to use CDI (on JEE6) in a Tomcat WebApp with only simple plain old java objects (yet). As far as I know it is simply possible to inject POJO java classes into other POJO Java classes?!
Here are my example classes
The application-scoped (singleton) class "ToBeInjected":
import javax.enterprise.context.ApplicationScoped;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ApplicationScoped
public class ToBeInjected {
private final Logger log = LoggerFactory.getLogger(ToBeInjected.class);
public ExampleBean() {
log.info("ToBeInjected init");
}
public void sayHello() {
log.info("Hello from ToBeInjected!");
}
}
The class "InjectingExample" that injects the above class:
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class InjectingExample {
private final Logger log = LoggerFactory.getLogger(InjectingExample.class);
@Inject
private ExampleBean bean;
public InjectionExample() {
log.info("InjectingExample init");
}
public void sayHello() {
log.info("InjectingExample tries to say hello ...");
bean.sayHello();
}
}
Finally there is the ContextListener which created a instance of InjectingExample and calls sayHello():
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.btc.dtv.gw.core.common.log.LogMarker;
public class ApplicationContextListener implements ServletContextListener {
private final Logger log = LoggerFactory.getLogger(ApplicationContextListener.class);
@Override
public void contextInitialized(ServletContextEvent arg0) {
log.info(">>>>> Startup >>>>>");
try {
InjectionExample example = new InjectionExample();
example.sayHello(); // uses internally the injected singleton class
}
catch(Exception ex) {
log.error("Error (nothing injected?)", ex);
}
log.info(">>>>> Startup DONE >>>>>");
}
}
I am using Tomcat 6 with the following WEB-INF/web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<listener>
<listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
</listener>
<listener>
<listener-class>com.btc.dtv.gw.ApplicationContextListener</listener-class>
</listener>
<resource-env-ref>
<description>Object factory for the CDI Bean Manager</description>
<resource-env-ref-name>BeanManager</resource-env-ref-name>
<resource-env-ref-type>javax.enterprise.inject.spi.BeanManager</resource-env-ref-type>
</resource-env-ref>
</web-app>
And the META-INF/context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="BeanManager"
auth="Container"
type="javax.enterprise.inject.spi.BeanManager"
factory="org.jboss.weld.resources.ManagerObjectFactory" />
<!-- Uncomment to enable injection into Servlets, Servlet Listeners and Filters in Tomcat -->
<Listener className="org.jboss.weld.environment.tomcat.WeldLifecycleListener" />
</Context>
Finally I copied "weld-tomcat-support-1.0.1-Final.jar" to ${CATALINA_HOME}/libs.
Deploying and running the webapp in Tomcat throws a NullPointerException because the member "bean" in class InjectingExample is null (not injected).
As far as I understood, this should work. Am I wrong?
Thanx for your attention until here. Hopefully I have mentioned everything which is import for you to help me. Otherweise tell me what you need.
Finally the logfile output in cataling.log:
12:05:17.716 [http-8080-1] INFO LOCALIZED org.jboss.weld.Version - WELD-000900 1.0.1 (Final) [@]
12:05:17.763 [http-8080-1] INFO LOCALIZED org.jboss.weld.Bootstrap - WELD-000101 Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously. [@]
12:05:17.888 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000103 Enabled alternatives for Manager
Enabled alternatives: [] []
Registered contexts: [interface javax.enterprise.context.ConversationScoped, interface javax.enterprise.context.ApplicationScoped, interface javax.inject.Singleton, interface javax.enterprise.context.SessionScoped, interface javax.enterprise.context.Dependent, interface javax.enterprise.context.RequestScoped]
Registered beans: 1
Specialized beans: 0
: [] [] [@]
12:05:17.888 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000104 Enabled decorator types for Manager
Enabled alternatives: [] []
Registered contexts: [interface javax.enterprise.context.ConversationScoped, interface javax.enterprise.context.ApplicationScoped, interface javax.inject.Singleton, interface javax.enterprise.context.SessionScoped, interface javax.enterprise.context.Dependent, interface javax.enterprise.context.RequestScoped]
Registered beans: 1
Specialized beans: 0
: [] [@]
12:05:17.888 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000105 Enabled interceptor types for Manager
Enabled alternatives: [] []
Registered contexts: [interface javax.enterprise.context.ConversationScoped, interface javax.enterprise.context.ApplicationScoped, interface javax.inject.Singleton, interface javax.enterprise.context.SessionScoped, interface javax.enterprise.context.Dependent, interface javax.enterprise.context.RequestScoped]
Registered beans: 1
Specialized beans: 0
: [] [@]
12:05:17.888 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000103 Enabled alternatives for Manager
Enabled alternatives: [] []
Registered contexts: [interface javax.enterprise.context.ConversationScoped, interface javax.enterprise.context.ApplicationScoped, interface javax.inject.Singleton, interface javax.enterprise.context.SessionScoped, interface javax.enterprise.context.Dependent, interface javax.enterprise.context.RequestScoped]
Registered beans: 1
Specialized beans: 0
: [] [] [@]
12:05:17.888 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000104 Enabled decorator types for Manager
Enabled alternatives: [] []
Registered contexts: [interface javax.enterprise.context.ConversationScoped, interface javax.enterprise.context.ApplicationScoped, interface javax.inject.Singleton, interface javax.enterprise.context.SessionScoped, interface javax.enterprise.context.Dependent, interface javax.enterprise.context.RequestScoped]
Registered beans: 1
Specialized beans: 0
: [] [@]
12:05:17.888 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000105 Enabled interceptor types for Manager
Enabled alternatives: [] []
Registered contexts: [interface javax.enterprise.context.ConversationScoped, interface javax.enterprise.context.ApplicationScoped, interface javax.inject.Singleton, interface javax.enterprise.context.SessionScoped, interface javax.enterprise.context.Dependent, interface javax.enterprise.context.RequestScoped]
Registered beans: 1
Specialized beans: 0
: [] [@]
12:05:18.013 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Reflection - WELD-000602 interface javax.enterprise.inject.Default is not declared @Target(TYPE, METHOD) or @Target(TYPE) [@]
12:05:18.013 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Reflection - WELD-000601 interface javax.inject.Named is missing @Target [@]
12:05:18.013 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Reflection - WELD-000602 interface javax.enterprise.context.RequestScoped is not declared @Target(TYPE, METHOD) or @Target(TYPE) [@]
12:05:18.013 [http-8080-1] WARN org.jboss.interceptor.model.InterceptionTypeRegistry - Class 'javax.ejb.PostActivate' not found, interception based on it is not enabled [@]
12:05:18.013 [http-8080-1] WARN org.jboss.interceptor.model.InterceptionTypeRegistry - Class 'javax.ejb.PrePassivate' not found, interception based on it is not enabled [@]
12:05:18.029 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-weld-ManagedBean-class org.jboss.weld.conversation.ConversationImpl [@]
12:05:18.029 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000106 Bean: Built-in implicit javax.event.Event bean [@]
12:05:18.029 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Reflection - WELD-000602 interface javax.enterprise.context.SessionScoped is not declared @Target(TYPE, METHOD) or @Target(TYPE) [@]
12:05:18.029 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-weld-ManagedBean-class org.jboss.weld.conversation.ServletConversationManager [@]
12:05:18.044 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-weld-ProducerMethod-org.jboss.weld.conversation.ServletConversationManager.method getConversationIdName() [@]
12:05:18.044 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-weld-ManagedBean-class org.jboss.weld.conversation.NumericConversationIdGenerator [@]
12:05:18.044 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000106 Bean: Built-in implicit javax.inject.Instance bean [@]
12:05:18.044 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-weld-NewManagedBean-class org.jboss.weld.conversation.ConversationImpl [@]
12:05:18.044 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000106 Bean: Built-in javax.inject.manager.InjectionPoint bean [@]
12:05:18.044 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-weld-ProducerMethod-org.jboss.weld.conversation.ServletConversationManager.method getConversationTimeoutInMilliseconds() [@]
12:05:18.044 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-weld-NewManagedBean-class org.jboss.weld.conversation.ServletConversationManager [@]
12:05:18.044 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-weld-ProducerMethod-org.jboss.weld.conversation.ServletConversationManager.method getConversationConcurrentAccessTimeout() [@]
12:05:18.044 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-weld-NewManagedBean-class org.jboss.weld.conversation.NumericConversationIdGenerator [@]
12:05:18.044 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Reflection - WELD-000602 interface javax.enterprise.inject.Produces is not declared @Target(TYPE, METHOD) or @Target(TYPE) [@]
12:05:18.044 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-weld-ManagedBean-class org.jboss.weld.servlet.HttpSessionManager [@]
12:05:18.044 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-weld-NewManagedBean-class org.jboss.weld.servlet.HttpSessionManager [@]
12:05:18.044 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-weld-ProducerMethod-org.jboss.weld.servlet.HttpSessionManager.method getSession() [@]
12:05:18.044 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Reflection - WELD-000602 interface javax.enterprise.context.ApplicationScoped is not declared @Target(TYPE, METHOD) or @Target(TYPE) [@]
12:05:18.091 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-flat-ManagedBean-class com.bsp.app.ToBeInjected [@]
12:05:18.091 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000106 Bean: Built-in javax.inject.manager.InjectionPoint bean [@]
12:05:18.091 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-flat-NewManagedBean-class com.bsp.app.services.products.impl.ProductServiceImpl [@]
12:05:18.091 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-flat-NewManagedBean-class com.bsp.app.ToBeInjected [@]
12:05:18.091 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000106 Bean: Built-in implicit javax.inject.Instance bean [@]
12:05:18.091 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-flat-ManagedBean-class com.bsp.app.services.products.impl.ProductServiceImpl [@]
12:05:18.091 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-flat-NewManagedBean-class com.bsp.app.services.products.ProductServiceModule [@]
12:05:18.091 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-flat-NewManagedBean-class com.bsp.app.InjectingExample [@]
12:05:18.091 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-flat-ManagedBean-class com.bsp.app.services.products.ProductServiceModule [@]
12:05:18.091 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000106 Bean: Built-in implicit javax.event.Event bean [@]
12:05:18.091 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000106 Bean: org.jboss.weld.bean-flat-ManagedBean-class com.bsp.app.InjectingExample [@]
12:05:18.091 [http-8080-1] DEBUG LOCALIZED org.jboss.weld.Bootstrap - WELD-000100 Weld initialized. Validating beans [@]
12:05:18.200 [http-8080-1] INFO TEC com.bsp.app.ApplicationContextListener - >>>>> Startup >>>>> [@]
12:05:18.200 [http-8080-1] INFO com.bsp.app.InjectingExample - InjectionExample init [@]
12:05:18.200 [http-8080-1] INFO com.bsp.app.InjectingExample - InjectionExample tries to say hello ... [@]
12:05:18.200 [http-8080-1] ERROR com.bsp.app.ApplicationContextListener - Error (injection failed?) [@]
java.lang.NullPointerException
at com.bsp.app.InjectingExample.sayHello(InjectingExample.java:21) [InjectingExample.class:na]
at com.bsp.app.ApplicationContextListener.contextInitialized(ApplicationContextListener.java:20) [ApplicationContextListener.class:na]
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4135) [catalina.jar:6.0.29]
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4630) [catalina.jar:6.0.29]
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791) [catalina.jar:6.0.29]
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771) [catalina.jar:6.0.29]
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:546) [catalina.jar:6.0.29]
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:905) [catalina.jar:6.0.29]
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:525) [catalina.jar:6.0.29]
at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1359) [catalina.jar:6.0.29]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [na:1.6.0_18]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [na:1.6.0_18]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [na:1.6.0_18]
at java.lang.reflect.Method.invoke(Method.java:597) [na:1.6.0_18]
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:297) [tomcat-coyote.jar:6.0.29]
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:836) [na:1.6.0_18]
at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:761) [na:1.6.0_18]
at org.apache.catalina.manager.ManagerServlet.check(ManagerServlet.java:1500) [catalina.jar:6.0.29]
at org.apache.catalina.manager.ManagerServlet.deploy(ManagerServlet.java:670) [catalina.jar:6.0.29]
at org.apache.catalina.manager.ManagerServlet.doPut(ManagerServlet.java:435) [catalina.jar:6.0.29]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:640) [servlet-api.jar:na]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) [servlet-api.jar:na]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) [catalina.jar:6.0.29]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [catalina.jar:6.0.29]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) [catalina.jar:6.0.29]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) [catalina.jar:6.0.29]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:563) [catalina.jar:6.0.29]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) [catalina.jar:6.0.29]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [catalina.jar:6.0.29]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [catalina.jar:6.0.29]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298) [catalina.jar:6.0.29]
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857) [tomcat-coyote.jar:6.0.29]
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588) [tomcat-coyote.jar:6.0.29]
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) [tomcat-coyote.jar:6.0.29]
at java.lang.Thread.run(Thread.java:619) [na:1.6.0_18]
12:05:18.200 [http-8080-1] INFO TEC com.bsp.app.ApplicationContextListener - >>>>> Startup DONE >>>>> [@]
I had a quick look at your Weld setup on Tomcat and it looks ok (just in case, see 18.3.1. Tomcat for details if required).
However, I have some questions/remarks:
Is your archive CDI enabled? In other words, do you have a beans.xml
file (for a web application, the beans.xml
file can be in either the WEB-INF
directory or in the WEB-INF/classes/META-INF
directory)? See Why is beans.xml required in CDI?
You're not supposed to instantiate beans yourself (like in new InjectionExample()
) if you want your beans to be managed by CDI. Use @Inject
.
I did not really pay attention to the fact that you were trying to inject something in a ContextListener
, I was too much focused on the use of the new
operator. That being said, while the Weld documentation states that the CDI specification requires the container to provide injection into non-contextual resources for all Java EE component classes, I'm totally sure of what this covers, especially when using Tomcat.
Personally, I would try to get CDI working with a Servlet first (or maybe use a full blown Java EE 6 server to avoid any limitation).