问题
In a Tomcat 8.5.15 environment using an Oracle 11 database, I want to implement a data source that handles encrypted passwords in the context.xml. I'm having troubles with that, as described in this StackOverflow question.
In hopes of determining the underlying problem, I simplified the scenario. First, I verified that the C3p0 resource specification worked fine.
<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"
/>
It worked fine. Then, I created a clone of the ComboPooledDataSource
, based on decompiling the class file:
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);
}
}
}
I created a revised resource specification using the cloned 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"
/>
When I try to connect to the database using this specification, the connection attempt fails.
...
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
Why does the clone attempt fail to connect?
UPDATE:
With assistance from our local DBA, we’ve been able to audit my connection attempts. It appears that we are successfully connecting to the database and logging in. Based on this, it sounds like the problem may be in how the code is handling the database’s response, rather than in our request generation.
回答1:
The error was a result of a class loading problem, where the Oracle classes were being loaded from multiple jars (%CATALINA_HOME%\lib\ojdbc7-12.1.0.2.0.jar
and %CATALINA_HOME%\webapps\my-webapp-1.0.0\WEB-INF\lib\ojdbc7-12.1.0.2.0.jar
) by different class loaders. When I deleted %CATALINA_HOME%\webapps\my-webapp-1.0.0\WEB-INF\lib\ojdbc7-12.1.0.2.0.jar
, my problem went away.
These sources (1, 2, 3) discuss this in more detail.
来源:https://stackoverflow.com/questions/45242652/why-does-c3p0s-combopooleddatasource-successfully-connect-to-a-database-but-it