因为容器(WebLogic/Tomcat)启动时优先加载自身lib目录中的旧版ojdbc.jar,导致运行时加载了不含新方法的旧类,引发NoSuchMethodError;需通过prefer-application-packages(WebLogic)或移除容器驱动(Tomcat)解决。
为什么 java.lang.NoSuchMethodError 总在 WebLogic 或 Tomcat 启动后才报?
因为应用里引入了新版 ojdbc8.jar,但容器(weblogic/tomcat)启动时优先加载了自己 lib 目录下的旧版 ojdbc6.jar 或 ojdbc7.jar,导致类加载器实际加载的是旧类——而旧类里根本没有你调用的新方法(比如 setnetworktimeout()、createoraclearray())。这不是编译失败,是运行时“找得到类、找不到方法”。
常见错误现象:
java.lang.NoSuchMethodError: oracle.jdbc.OracleConnection.setNetworkTimeout(Ljava/util/concurrent/Executor;I)V- 本地 IDE 运行正常,部署到 WebLogic 就崩
- 同一个 WAR 包,在 Tomcat 9 上 OK,在 WebLogic 12c 上报错
实操建议:
立即学习“Java免费学习笔记(深入)”;
- 先确认容器自带的驱动路径:WebLogic 是
ORACLE_HOME/wlserver/server/lib/ojdbc*.jar;Tomcat 是$CATALINA_HOME/lib/ojdbc*.jar - 别删容器自带 jar —— 可能被其内部 JDBC 数据源或管理控制台依赖,直接删会导致控制台连不上数据库
- 改用类加载策略隔离,而不是硬删或覆盖
WebLogic 怎么强制应用用自己带的 ojdbc8.jar?
WebLogic 默认用 system classloader 加载 ojdbc,你的应用无法“覆盖”。必须显式声明类加载顺序,让应用自己的 WEB-INF/lib/ojdbc8.jar 优先于系统路径。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- 在应用的
WEB-INF/weblogic.xml中添加:<wls:container-descriptor> <wls:prefer-application-packages> <wls:package-name>oracle.jdbc.*</wls:package-name> <wls:package-name>oracle.sql.*</wls:package-name> </wls:prefer-application-packages> </wls:container-descriptor> - 确保
weblogic.xml的命名空间正确(wls前缀需绑定到http://xmlns.oracle.com/weblogic/weblogic-web-app) - 如果用了 Spring Boot 打成 WAR 部署,注意
spring-boot-thin-launcher或嵌入式 classloader 可能干扰该配置,此时应改用传统 WAR + 显式WEB-INF/lib
Tomcat 下怎么绕过 $CATALINA_HOME/lib/ojdbc6.jar?
Tomcat 的类加载机制默认把 $CATALINA_HOME/lib 放在应用 classpath 前面,且不支持像 WebLogic 那样细粒度包级优先。最稳的方式是让 Tomcat “看不见”它。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- 把
$CATALINA_HOME/lib/ojdbc6.jar移出该目录(例如重命名为ojdbc6.jar.bak),再把你的ojdbc8.jar放进应用的WEB-INF/lib/ - 如果必须保留容器级驱动(如多个应用共用一个数据源配置),就别在应用里再放
ojdbc*.jar,而是统一用 JNDI 数据源,并确保context.xml中的driverClassName指向兼容类(如oracle.jdbc.driver.OracleDriver旧写法仍可用,但新特性如OracleConnection子类需强转) - 注意:Tomcat 9+ 默认启用
parallelCapable类加载器,但不会自动跳过lib目录下的冲突 jar,不存在“自动选新版本”逻辑
为什么加了 prefer-application-packages 还报错?
因为 Oracle 驱动有多个关键包,漏掉任何一个都可能触发间接依赖失败。比如只写了 oracle.jdbc.*,但 oracle.sql.ARRAY 或 oracle.xdb.XMLType 被其他代码引用,而这些类仍在旧驱动里,就会在运行中某次反射调用时突然崩。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- 至少补全这三个包:
oracle.jdbc.*、oracle.sql.*、oracle.ucp.*(如果用了 UCP 连接池) - 检查是否用了 MyBatis、Hibernate 等框架的 Oracle 方言扩展,它们可能隐式依赖
oracle.dms.*或oracle.net.*,必要时一并加入prefer-application-packages - 用
jps -l+jstack或开启 WebLogic 的-verbose:class,确认报错类到底从哪个 jar 加载的
最容易被忽略的是:WebLogic 的域(domain)级 lib 目录($DOMAIN_HOME/lib)也会参与类加载,且优先级高于 prefer-application-packages。那里如果也扔了个 ojdbc6.jar,上面所有配置都白搭。











