Java 在tomcat 7中获取资源注释处的空指针异常

Java 在tomcat 7中获取资源注释处的空指针异常,java,tomcat,jdbc,annotations,datasource,Java,Tomcat,Jdbc,Annotations,Datasource,以下是context.xml中的资源元素: <Resource name="jdbc/myoracle" auth="Container" type="javax.sql.DataSource" driverClassName="oracle.jdbc.driver.OracleDriver" url="jdbc:oracle:thin:@localhost:1521:XE" username="hr" p

以下是context.xml中的资源元素:

<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"/> 
当我尝试在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");

我哪里出错了?

这里发生了很多事情。首先,除非让应用服务器管理数据源,否则web.xml中不需要资源引用。如果您使用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的状态,您可以始终实现
初始化bean
,这将强制您实现
AfterPropertieSet

@Override
public void afterPropertiesSet() throws Exception {
    Assert.notNull(dataSource);
}
虽然1@Autowired`如果默认情况下无法自动连线,则应通过异常

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

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

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

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

  • 弹簧
  • CDI(JavaEE6 web概要文件的一部分)
  • EJB(JavaEE6Web概要文件的一部分,不完全是“DI框架”)

注意Tomcat确实支持
@Resource
注入。你真的很接近

您使用的问题是:

  • @Resource(mappedName=“jdbc/myoracle”)
这本可以奏效的:

  • @Resource(name=“jdbc/myoracle”)
我要指出的是,如果您一直在使用ApacheTomee(Tomcat的JavaEE认证版本),那么这两个版本都可以在不更改
context.xml

此外,您还可以获得CDI、EJB、JPA和其他一些答案中提到的其他内容


小。

请注意,您使用的是Spring注释,op可能使用也可能不使用。(Autowiring@Resource它不是Tomcat支持的独立工具,自动布线通常由JEE应用服务器提供)感谢您的回复。但我的应用程序没有使用spring框架。我是在JavaEE中完成的,我的后端逻辑是用java类编写的。你能告诉我如何在JavaEE中实现它吗?奇怪的是,它在Tomcat6中工作得很好,而在Tomcat7中却中断了。知道为什么吗?@BjörnPollex我也从Tomcat 6升级到了Tomcat 7,并且
@Resource
停止了工作。你找到解决方案了吗?@PanuHaaramo:对不起,我从来没有找到一个可移植的解决方案(一个与Tomcat 6和7一起使用的解决方案)。如果我没记错的话(这已经是很久以前的事了),我们最终还是坚持使用Tomcat 6,因为其他原因。在这些类中,有JSP-s、servlet、过滤器等,但Srinivas试图将资源注入到自己的DAO类中(该类不由Tomcat管理)。我想这就是问题所在。参见JavaEE5教程,表3-1“WebComponentsThatAcceptResourceInjections”,这对Tomcat7有用吗?它在Tomcat 6中工作,但在我升级到Tomcat 7时停止工作。我在Tomcat 8上使用Weld,这是正确的答案。救生圈只需使用@autowired即可
@Autowired
@Qualifier("myDataSource")
DataSource dataSource;
@Override
public void afterPropertiesSet() throws Exception {
    Assert.notNull(dataSource);
}
@Autowired
public MyClass(@Qualifier("myDataSource") DataSource dataSource) {
   this.dataSource = dataSource;
}