自定义DataSourceFactory触发ORA-28040无匹配认证协议错误排查
问题原因与解决方案
ORA-28040是客户端与数据库服务器认证协议不匹配的错误,结合自定义工厂后才触发问题的现象,核心原因集中在DBCP版本兼容性或类加载冲突导致的数据源创建逻辑异常:
具体分析
Tomcat 8.5.x默认使用Apache Commons DBCP 2.x(包路径为org.apache.tomcat.dbcp.dbcp2),如果你的MyFactory继承的是旧版DBCP 1.x的org.apache.commons.dbcp.BasicDataSourceFactory,会创建DBCP1版本的BasicDataSource实例——它与ojdbc8兼容性较差,无法正确处理Oracle 19c所需的认证协议参数,从而触发ORA-28040。
即使继承的是DBCP2类,也可能因应用类加载器与Tomcat容器类加载器的隔离性,导致自定义工厂加载的DBCP、驱动类与Tomcat默认工厂使用的不一致,引发连接参数处理异常。
解决方案
- 继承正确的DBCP2工厂类
修改MyFactory继承Tomcat自带的DBCP2工厂,同时对齐接口方法的异常声明:
import org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory; import javax.naming.Name; import javax.naming.Context; import java.util.Hashtable; public class MyFactory extends BasicDataSourceFactory { public MyFactory() {} @Override public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception { return super.getObjectInstance(obj, name, nameCtx, environment); } }
移除应用中冲突的DBCP依赖
检查应用WEB-INF/lib目录,删除commons-dbcp-1.x.jar或其他版本的DBCP包,避免与Tomcat自带的DBCP2类冲突。显式指定认证协议连接属性
在context.xml的Resource配置中添加连接属性,强制驱动使用兼容的认证方式:
<Resource name="MyResource" auth="Container" type="javax.sql.DataSource" factory="path.to.my.factory.MyFactory" username="myusername" password="mypassword" driverClassName="oracle.jdbc.OracleDriver" url="myUrl" maxTotal="8" maxIdle="4" defaultAutoCommit="true" removeAbandonedOnBorrow="true" removeAbandonedOnMaintenance="true" removeAbandonedTimeout="60" validationQuery="SELECT 1 FROM DUAL" connectionProperties="oracle.net.authentication_services=(NONE)"/>
- 统一类加载器
将MyFactory的class文件放入Tomcat的lib目录(而非应用WEB-INF/classes),使其与Tomcat的DBCP2类使用同一个容器类加载器,避免类加载隔离导致的参数处理差异。
内容的提问来源于stack exchange,提问作者avitoria
相关产品推荐
相关产品推荐

