正确配置Oracle JDBC驱动需将其置于$CATALINA_HOME/lib,配合context.xml中带<Context>标签的<Resource>配置、web.xml中严格匹配的<resource-ref>声明,并在代码中用"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" />
</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>的值(如jdbc/oracle)必须和<Resource name="...">完全一致,包括大小写和斜杠 - 这个声明只是“声明我需要一个叫这个名字的资源”,不是定义资源本身
- 如果用 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>)必须配合 <ResourceLink> 在应用级 context 中引用,否则应用还是看不见——这点连很多老项目都踩过坑。


















