Java 无法使用cdi:NullPointerException注入bean

Java 无法使用cdi:NullPointerException注入bean,java,dependency-injection,cdi,Java,Dependency Injection,Cdi,好的,所以我是CDI新手,目前在注入bean时面临问题。以下是模块的详细信息: ResourceController.java //imports @Path("/resource") public class ResourceController { @GET @Path("/print/{message}") public void printMessage(@PathParam("message") String message){ Messag

好的,所以我是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);
    }
}    
//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

public class MessagePrinter  {

    @Inject
    private InjectedBean bean;


    public void print(String message) {

        bean.print(message);    
    }

}    
//imports

@ApplicationScoped
public class MessagePrinter implements IMessagePrinter {

    @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>
MessagePrinter.java

//imports

public class MessagePrinter  {

    @Inject
    private InjectedBean bean;


    public void print(String message) {

        bean.print(message);    
    }

}    
//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=newmessageprinter()
但注入它
@inject private MessagePrinter bean

您不应该创建
MessagePrinter bean=newmessageprinter()
但注入它
@inject private MessagePrinter bean

在注释模式下,您需要在要查找的bean上放置一个类似@ApplicationScoped的作用域。如果您想要任何bean,可以使用所有发现模式。

在注释模式下,您需要在要发现的bean上放置一个类似@ApplicationScoped的范围。如果您想要任何bean,可以使用所有发现模式。

beans.xml
中,您可以更改

bean发现模式=“注释”

bean发现模式=“全部”


正如talex所说,您不应该使用new关键字来创建MessagePrinter,因为CDI容器控制着MessagePrinter的生命周期,而通过使用
new
您正在破坏它

beans.xml
中,您可以更改

bean发现模式=“注释”

bean发现模式=“全部”


正如talex所说,您不应该使用new关键字来创建MessagePrinter,因为CDI容器控制着MessagePrinter的生命周期,而通过使用
new
您正在破坏它

也尝试过,但给出了相同的错误,即NullPointerException也尝试过,但给出了相同的错误,即NullPointerException您要部署到哪个容器?我在书堆里看到了汤姆和泽西。TomEE随CXF一起发货。理想情况下,您不应该发布自己的JAX-RS实现
绝对是胡说八道-您想将其注入。除此之外,您是否有
beans.xml
的发现设置为
all
?如果没有,您的bean将不会被拾取,因为您没有使用bean定义注释。@John Ament:抱歉,没有真正获得您对CXF附带的IE的评论。理想情况下,您不应该发布自己的JAX-RSimplementation@jCoder如果你不回答所提出的问题,就很难澄清。根据stacktrace,看起来您要部署到tomee,但附带了jersey JAX-RS库。“这就是你在做的吗?”约翰·阿门特:很抱歉反应太晚了。是的,我正在使用TomEE和jersey。您要部署到哪个容器?我在书堆里看到了汤姆和泽西。TomEE随CXF一起发货。理想情况下,您不应该发布自己的JAX-RS实现
绝对是胡说八道-您想将其注入。除此之外,您是否有
beans.xml
的发现设置为
all
?如果没有,您的bean将不会被拾取,因为您没有使用bean定义注释。@John Ament:抱歉,没有真正获得您对CXF附带的IE的评论。理想情况下,您不应该发布自己的JAX-RSimplementation@jCoder如果你不回答所提出的问题,就很难澄清。根据stacktrace,看起来您要部署到tomee,但附带了jersey JAX-RS库。“这就是你在做的吗?”约翰·阿门特:很抱歉反应太晚了。是的,我正在使用TomEE和jersey。正如您在上面的更新中所注意到的,我已经用@ApplicationScoped注释了beans'ResourceController.java'和'MessagePrinter.java'。但我还是得到了“不满意的支出例外”你确定jersey使用cdi吗?看起来它回到了hk2,如果你没有cdi扩展,它不知道bean。你可以在上面的更新中注意到,我已经用@ApplicationScoped注释了bean“ResourceController.java”和“MessagePrinter.java”。但我还是得到了“不满意的支出例外”你确定jersey使用cdi吗?如果没有cdi扩展的话,它会回到hk2,hk2不知道bean