[英]Unable to inject bean with cdi : NullPointerException
好的,所以我是CDI的新手,目前在注入bean时遇到问题。 以下是模块的详细信息:
ResourceController.java
//imports
@Path("/resource")
public class ResourceController {
@GET
@Path("/print/{message}")
public void printMessage(@PathParam("message") String message){
MessagePrinter bean = new MessagePrinter();
bean.print(message);
}
}
MessagePrinter.java
//imports
public class MessagePrinter {
@Inject
private InjectedBean bean;
public void print(String message) {
bean.print(message);
}
}
InjectedBean.java
public interface InjectedBean {
public void print(String message);
}
InjectedBeanImp.java
public class InjectedBeanImp implements InjectedBean {
public InjectedBeanImp() {
// TODO Auto-generated constructor stub
}
@Override
public void print(String message) {
System.out.println(message);
}
}
这里的问题是,每当我访问资源ResourceController.java
,都会在MessagePrinter.java
类中得到NullPointerException
,这意味着InjectedBean.java
失败。
这是stacktrace:
java.lang.NullPointerException
at com.bean.MessagePrinter.print(MessagePrinter.java:14)
at com.resource.ResourceController.printMessage(ResourceController.java:19)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$VoidOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:143)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.tomee.webservices.CXFJAXRSFilter.doFilter(CXFJAXRSFilter.java:83)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.openejb.server.httpd.EEFilter.doFilter(EEFilter.java:65)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:108)
at org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:44)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.tomee.catalina.OpenEJBSecurityListener$RequestCapturer.invoke(OpenEJBSecurityListener.java:97)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:784)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:802)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1410)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskTh
在你们中任何人将其标记为重复问题之前,我对许多线程进行了很多研究以寻求解决方案,并消除了一些可能的错误,例如:
1)从Tomcat切换到Tomee,以排除服务器问题的可能性
2)我在WEB-INF
文件夹中明确维护了空beans.xml
(默认情况下不可用)
但我仍然遇到相同的问题,找不到其他解决方案。 我做错了什么?
更新1
这是beans.xml
内容
<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"
version="1.2" bean-discovery-mode="annotated">
<!-- some content -->
</beans>
正如可以看到的, bean-discovery-mode
被“注释”了,因为在注释之一中正确提到了它:)
所以我注释了必需的bean,如下所示:
ResourceController.java
//imports
@Path("/resource")
@ApplicationScoped
public class ResourceController {
@Inject
private IMessagePrinter bean;
@GET
@Path("/print/{message}")
public void printMessage(@PathParam("message") String message){
bean.print(message);
}
}
MessagePrinter.java
//imports
@ApplicationScoped
public class MessagePrinter implements IMessagePrinter {
@Inject
private InjectedBean bean;
public void print(String message) {
bean.print(message);
}
}
另外,我现在已经将MessagePrinter.java
的接口(即IMessagePrinter.java
注入到ResourceController.java
而不是创建实例,但是现在我得到了以下异常:
SEVERE: Servlet.service() for servlet [Jersey RESTful Application] in context with path [/TestEJB] threw exception [A MultiException has 3 exceptions. They are:
1. org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=IMessagePrinter,parent=ResourceController,qualifiers={},position=-1,optional=false,self=false,unqualified=null,29372562)
2. java.lang.IllegalArgumentException: While attempting to resolve the dependencies of com.resource.ResourceController errors were found
3. java.lang.IllegalStateException: Unable to perform operation: resolve on com.resource.ResourceController
] with root cause
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=IMessagePrinter,parent=ResourceController,qualifiers={},position=-1,optional=false,self=false,unqualified=null,29372562)
我再次陷入困境。 预先感谢您的耐心配合:)
注意:但是,如果我在没有beans.xml
情况下遵循这种方法,则可以正常工作,但是我不想明确地实现实现和接口的绑定。
您不应该创建MessagePrinter bean = new MessagePrinter();
但是将其注入@Inject private MessagePrinter bean;
在带注释的模式下,您需要在要发现的bean上放置一个像@ApplicationScoped这样的作用域。 如果您需要任何bean,也许使用所有发现模式。
在beans.xml
您可以更改
bean-discovery-mode="annotated"
至
bean-discovery-mode="all"
正如talex所说,您不应使用new关键字来创建MessagePrinter,因为CDI容器正在控制MessagePrinter的生命周期,而使用new
则破坏了它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.