[英]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容器無法識別該注釋,也無法對其執行任何操作。 手動查找有效,因為資源定義正確。
你需要一些依賴注入框架:
這里有很多事情要發生。 首先,除非您要讓應用程序服務器管理數據源,否則您的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.