[英]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.