繁体   English   中英

在tomcat 7中获取空指针异常@Resource注释

[英]Getting null pointer exception @Resource annotation in tomcat 7

这是context.xml中的我的Resource元素::

<Resource name="jdbc/myoracle" auth="Container"
              type="javax.sql.DataSource" driverClassName="oracle.jdbc.driver.OracleDriver"
              url="jdbc:oracle:thin:@localhost:1521:XE"
              username="hr" password="hr" maxActive="20" maxIdle="10"
              maxWait="-1"/> 

这是我在web.xml中的资源引用:

       <resource-ref>
            <description>Oracle Datasource</description>
            <res-ref-name>jdbc/myoracle</res-ref-name>
            <res-type>javax.sql.DataSource</res-type>
            <res-auth>Container</res-auth>
        </resource-ref>

然后我在代码中使用@Resource注释:

      @Resource(mappedName = "jdbc/myoracle")
        DataSource ds;

当我尝试在ds上使用getConnection()创建连接对象时,我在运行时得到一个空指针异常:

    Oct 24, 2011 12:18:21 PM org.apache.catalina.core.StandardWrapperValve invoke
    INFO: java.lang.NullPointerException
        at jdbc.patientDaoImpl.get_patients(patientDaoImpl.java:248)
        at org.apache.jsp.index2_jsp._jspService(index2_jsp.java:92)
        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:419)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:333)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:223)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:563)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:399)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:317)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:204)
        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:311)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:662)

但如果我使用initialContext查找,该应用程序工作正常。

    Context initContext = new InitialContext();
    Context envContext  = (Context)initContext.lookup("java:/comp/env");
    DataSource ds = (DataSource)envContext.lookup("jdbc/myoracle");

我哪里错了?

注意Tomcat 确实支持@Resource注入。 你真的很亲密。

问题是你用过的:

  • @Resource(mappedName = "jdbc/myoracle")

这会有效:

  • @Resource(name = "jdbc/myoracle")

我会注意到,如果你一直在使用Apache TomEE(经过JavaEE认证的Tomcat版本),两者都可以使用你的context.xml没有任何变化

另外,您还可以获得CDI,EJB,JPA以及其他一些答案中提到的其他内容。

这里比较小。

Tomcat本身不支持@Resource注入。 换句话说,servlet容器无法识别该注释,也无法对其执行任何操作。 手动查找有效,因为资源定义正确。

你需要一些依赖注入框架:

  • 弹簧
  • CDI(JavaEE6 Web配置文件的一部分)
  • EJB(JavaEE6 Web配置文件的一部分,不完全是“DI框架”)

这里有很多事情要发生。 首先,除非您要让应用程序服务器管理数据源,否则您的web.xml中不需要resource-ref。 如果您使用IBM WAS或Apache Tomcat之类的东西,并在服务器配置中指定数据源参数,这将非常有用。 如果你这样做,你将需要保留资源引用,并添加一个jndi工厂bean:

<bean id="myDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
     <property name="jndiName"><value>java:comp/env/jdbc/myOracle</value></property>
</bean>

巧合的是,如果您只是添加这个bean,我很确定您的设置现在可以正常工作。

从你现在拥有的,或者如果你使用jndi工厂bean,你所要做的就是从那里自动装配bean:

@Autowired
@Qualifier("myDataSource")
DataSource dataSource;

如果要验证bean的状态,可以始终实现InitializingBean ,这将强制您实现afterPropertiesSet

@Override
public void afterPropertiesSet() throws Exception {
    Assert.notNull(dataSource);
}

虽然1 @ Autowired`应该通过异常,如果它默认不能自动装配。

值得注意的是,使用构造函数是一个更好的范例:

@Autowired
public MyClass(@Qualifier("myDataSource") DataSource dataSource) {
   this.dataSource = dataSource;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM