为什么 C3p0 的 ComboPooledDataSource 成功连接到数据库,但它的克隆没有?

Why does C3p0's ComboPooledDataSource successfully connect to a database, but its clone doesn't?

在使用 Oracle 11 数据库的 Tomcat 8.5.15 环境中,我想在 context.xml 中实现一个处理加密密码的数据源。正如 .

中所述,我遇到了麻烦

为了确定根本问题,我简化了场景。首先,我验证了 C3p0 资源规范工作正常。

   <Resource 
              auth="Container"
              description="MyDataSource"
              driverClass="oracle.jdbc.OracleDriver" 
              maxPoolSize="100"  
              minPoolSize="10"   
              acquireIncrement="1"  
              name="jdbc/MyDataSource"
              user="me"  
              password="mypassword"
              factory="org.apache.naming.factory.BeanFactory"
              type="com.mchange.v2.c3p0.ComboPooledDataSource"
              jdbcUrl="jdbc:oracle:thin:@mydb:1521:dev12c"
              />

它运行良好。然后,我在反编译 class 文件的基础上创建了 ComboPooledDataSource 的克隆:

public final class ComboPooledDataSourceCopy
        extends AbstractComboPooledDataSource
        implements Serializable, Referenceable {
    private static final long serialVersionUID = 1L;
    private static final short VERSION = 2;

    public ComboPooledDataSourceCopy() {
    }

    public ComboPooledDataSourceCopy(boolean autoregister) {
        super(autoregister);
    }

    public ComboPooledDataSourceCopy(String configName) {
        super(configName);
    }

    private void writeObject(ObjectOutputStream oos) throws IOException {
        oos.writeShort(2);
    }

    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
        short version = ois.readShort();
        switch(version) {
            case 2:
                return;
            default:
                throw new IOException("Unsupported Serialized Version: " + version);
        }
    }
}

我使用克隆的 class:

创建了一个修订的资源规范
   <Resource 
              auth="Container"
              description="MyDataSource"
              driverClass="oracle.jdbc.OracleDriver" 
              maxPoolSize="100"  
              minPoolSize="10"   
              acquireIncrement="1"  
              name="jdbc/MyDataSource"
              user="me"  
              password="mypassword"
              factory="org.apache.naming.factory.BeanFactory"
              type=type="com.mycompany.ComboPooledDataSourceCopy"
              jdbcUrl="jdbc:oracle:thin:@mydb:1521:dev12c"
              />

当我尝试使用此规范连接到数据库时,连接尝试失败。

...
Caused by: java.sql.SQLException: com.mchange.v2.c3p0.impl.NewProxyConnection@6950dfda
[wrapping: oracle.jdbc.driver.T4CConnection@765426dd]
is not a wrapper for or implementation of oracle.jdbc.OracleConnection
    at com.mchange.v2.c3p0.impl.NewProxyConnection.unwrap(NewProxyConnection.java:1744)
    at org.jaffa.security.JDBCSecurityPlugin.executeStoredProcedure(JDBCSecurityPlugin.java:117)
    ... 67 more

为什么克隆尝试连接失败?

更新:

在我们本地 DBA 的帮助下,我们已经能够审核我的连接尝试。看来我们已成功连接到数据库并登录。基于此,听起来问题可能在于代码如何处理数据库的响应,而不是我们的请求生成。

错误是 class 加载问题的结果,其中 Oracle classes 是由不同的从多个 jar(%CATALINA_HOME%\lib\ojdbc7-12.1.0.2.0.jar%CATALINA_HOME%\webapps\my-webapp-1.0.0\WEB-INF\lib\ojdbc7-12.1.0.2.0.jar)加载的class 装载机。当我删除 %CATALINA_HOME%\webapps\my-webapp-1.0.0\WEB-INF\lib\ojdbc7-12.1.0.2.0.jar 后,我的问题就消失了。

这些来源 (1, 2, 3) 对此进行了更详细的讨论。