正确配置oracle jdbc驱动需将其置于$catalina_home/lib,配合context.xml中带标签的配置、web.xml中严格匹配的声明,并在代码中用"java:comp/env/jdbc/xxx"完整路径lookup,三者任一出错均导致namenotfoundexception。

直接把 Oracle JDBC 驱动放到 $CATALINA_HOME/lib,再配好 context.xml 或 server.xml,就能用 java:comp/env/jdbc/xxx 查到数据源。别放错位置、别漏写 <context></context> 标签、别拼错 JNDI 名,这三处一错就 javax.naming.NameNotFoundException。
Oracle JDBC 驱动必须放对位置
Tomcat 7+ 不会扫描 WEB-INF/lib 里的 JDBC 驱动来初始化 JNDI 数据源——这是关键前提。驱动必须放在容器级目录:
-
$CATALINA_HOME/lib(推荐):所有应用共享,避免类加载冲突 - 不能放
WEB-INF/lib:JNDI 初始化发生在应用加载前,此时 WebApp 类加载器还没启动 - 注意文件名:
ojdbc8.jar(Java 8+)、ojdbc6.jar(Java 6/7),旧版classes12.zip要重命名为classes12.jar
context.xml 中的 Resource 配置要点
最常用的是应用级配置,在 META-INF/context.xml(打包进 WAR)或 $CATALINA_HOME/conf/Catalina/localhost/yourapp.xml(外部配置)里写:
<context><resource name="jdbc/oracle" auth="Container" type="javax.sql.DataSource" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" driverclassname="oracle.jdbc.OracleDriver" url="jdbc:oracle:thin:@localhost:1521:ORCL" username="scott" password="tiger" maxactive="20" maxidle="10" maxwait="10000" validationquery="SELECT 1 FROM DUAL" testwhileidle="true" timebetweenevictionrunsmillis="30000"></resource></context>
注意:
- 必须包裹在
<context></context>标签内,否则 Tomcat 7+ 会静默忽略 -
factory属性推荐显式指定为org.apache.tomcat.jdbc.pool.DataSourceFactory(Tomcat 7+ 默认连接池),不写可能 fallback 到已废弃的BasicDataSourceFactory -
validationQuery用SELECT 1 FROM DUAL,不是SELECT COUNT(0) FROM DUAL(后者语法错误) -
url中的 SID(如ORCL)要和 Oracle 实例实际一致;若用 Service Name,应写成jdbc:oracle:thin:@localhost:1521/ORCL(斜杠)
web.xml 中 resource-ref 必须严格匹配
这是最容易被跳过的一步,但缺了它,java:comp/env/xxx 就查不到:
<resource-ref><description>Oracle DataSource</description><res-ref-name>jdbc/oracle</res-ref-name><res-type>javax.sql.DataSource</res-type><res-auth>Container</res-auth></resource-ref>
重点:
-
<res-ref-name></res-ref-name>的值(如jdbc/oracle)必须和<resource name="..."></resource>完全一致,包括大小写和斜杠 - 这个声明只是“声明我需要一个叫这个名字的资源”,不是定义资源本身
- 如果用 Spring,
JndiObjectFactoryBean的jndiName属性也得是java:comp/env/jdbc/oracle,不能少前缀
代码中 lookup 的路径不能省略 java:comp/env
运行时获取数据源必须带完整 JNDI 命名空间:
Context ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/oracle");
常见错误:
- 写成
"jdbc/oracle"→NameNotFoundException - 写成
"java:comp/env/jdbc/oracle/"(末尾斜杠)→ 找不到 - 在非 Web 环境(如单元测试)里直接 new
InitialContext()会失败,因为没绑定 Tomcat 的命名上下文
真正容易被忽略的是:全局 JNDI(配在 server.xml 的 <globalnamingresources></globalnamingresources>)必须配合 <resourcelink></resourcelink> 在应用级 context 中引用,否则应用还是看不见——这点连很多老项目都踩过坑。











