簡體   English   中英

無法使用cdi注入bean:NullPointerException

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM