繁体   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