Repository: commons-dbcp
Updated Branches:
  refs/heads/master 81aea9441 -> 3449a42bb


[DBCP-518] Allow DBCP to work with old Java 6/JDBC drivers without
throwing AbstractMethodError.

Project: http://git-wip-us.apache.org/repos/asf/commons-dbcp/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-dbcp/commit/3449a42b
Tree: http://git-wip-us.apache.org/repos/asf/commons-dbcp/tree/3449a42b
Diff: http://git-wip-us.apache.org/repos/asf/commons-dbcp/diff/3449a42b

Branch: refs/heads/master
Commit: 3449a42bbaeed0ff5b0d07998169ff2896bf45c7
Parents: 81aea94
Author: Gary Gregory <garydgreg...@gmail.com>
Authored: Wed Aug 15 21:51:59 2018 -0600
Committer: Gary Gregory <garydgreg...@gmail.com>
Committed: Wed Aug 15 21:51:59 2018 -0600

----------------------------------------------------------------------
 .../commons/dbcp2/DelegatingConnection.java     |  10 +-
 .../dbcp2/DelegatingDatabaseMetaData.java       |   6 +-
 .../commons/dbcp2/DelegatingResultSet.java      |   4 +-
 .../commons/dbcp2/DelegatingStatement.java      |   4 +-
 .../org/apache/commons/dbcp2/Jdbc41Bridge.java  | 464 +++++++++++++++++++
 .../dbcp2/PoolableConnectionFactory.java        |   4 +-
 .../java/org/apache/commons/dbcp2/Utils.java    |  19 -
 .../dbcp2/cpdsadapter/PooledConnectionImpl.java |   4 +-
 .../ConnectionPoolDataSourceProxy.java          |   4 +-
 9 files changed, 483 insertions(+), 36 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-dbcp/blob/3449a42b/src/main/java/org/apache/commons/dbcp2/DelegatingConnection.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/dbcp2/DelegatingConnection.java 
b/src/main/java/org/apache/commons/dbcp2/DelegatingConnection.java
index 5e04bd2..a94b665 100644
--- a/src/main/java/org/apache/commons/dbcp2/DelegatingConnection.java
+++ b/src/main/java/org/apache/commons/dbcp2/DelegatingConnection.java
@@ -928,7 +928,7 @@ public class DelegatingConnection<C extends Connection> 
extends AbandonedTrace i
     public void setSchema(final String schema) throws SQLException {
         checkOpen();
         try {
-            connection.setSchema(schema);
+            Jdbc41Bridge.setSchema(connection, schema);
         } catch (final SQLException e) {
             handleException(e);
         }
@@ -938,7 +938,7 @@ public class DelegatingConnection<C extends Connection> 
extends AbandonedTrace i
     public String getSchema() throws SQLException {
         checkOpen();
         try {
-            return Utils.getSchema(connection);
+            return Jdbc41Bridge.getSchema(connection);
         } catch (final SQLException e) {
             handleException(e);
             return null;
@@ -949,7 +949,7 @@ public class DelegatingConnection<C extends Connection> 
extends AbandonedTrace i
     public void abort(final Executor executor) throws SQLException {
         checkOpen();
         try {
-            connection.abort(executor);
+            Jdbc41Bridge.abort(connection, executor);
         } catch (final SQLException e) {
             handleException(e);
         }
@@ -959,7 +959,7 @@ public class DelegatingConnection<C extends Connection> 
extends AbandonedTrace i
     public void setNetworkTimeout(final Executor executor, final int 
milliseconds) throws SQLException {
         checkOpen();
         try {
-            connection.setNetworkTimeout(executor, milliseconds);
+            Jdbc41Bridge.setNetworkTimeout(connection, executor, milliseconds);
         } catch (final SQLException e) {
             handleException(e);
         }
@@ -969,7 +969,7 @@ public class DelegatingConnection<C extends Connection> 
extends AbandonedTrace i
     public int getNetworkTimeout() throws SQLException {
         checkOpen();
         try {
-            return connection.getNetworkTimeout();
+            return Jdbc41Bridge.getNetworkTimeout(connection);
         } catch (final SQLException e) {
             handleException(e);
             return 0;

http://git-wip-us.apache.org/repos/asf/commons-dbcp/blob/3449a42b/src/main/java/org/apache/commons/dbcp2/DelegatingDatabaseMetaData.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/dbcp2/DelegatingDatabaseMetaData.java 
b/src/main/java/org/apache/commons/dbcp2/DelegatingDatabaseMetaData.java
index 3423979..9aea2d3 100644
--- a/src/main/java/org/apache/commons/dbcp2/DelegatingDatabaseMetaData.java
+++ b/src/main/java/org/apache/commons/dbcp2/DelegatingDatabaseMetaData.java
@@ -130,7 +130,7 @@ public class DelegatingDatabaseMetaData implements 
DatabaseMetaData {
     public boolean generatedKeyAlwaysReturned() throws SQLException {
         connection.checkOpen();
         try {
-            return databaseMetaData.generatedKeyAlwaysReturned();
+            return Jdbc41Bridge.generatedKeyAlwaysReturned(databaseMetaData);
         } catch (final SQLException e) {
             handleException(e);
             return false;
@@ -744,8 +744,8 @@ public class DelegatingDatabaseMetaData implements 
DatabaseMetaData {
             final String columnNamePattern) throws SQLException {
         connection.checkOpen();
         try {
-            return DelegatingResultSet.wrapResultSet(connection,
-                    databaseMetaData.getPseudoColumns(catalog, schemaPattern, 
tableNamePattern, columnNamePattern));
+            return DelegatingResultSet.wrapResultSet(connection, 
Jdbc41Bridge.getPseudoColumns(databaseMetaData,
+                    catalog, schemaPattern, tableNamePattern, 
columnNamePattern));
         } catch (final SQLException e) {
             handleException(e);
             throw new AssertionError();

http://git-wip-us.apache.org/repos/asf/commons-dbcp/blob/3449a42b/src/main/java/org/apache/commons/dbcp2/DelegatingResultSet.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/dbcp2/DelegatingResultSet.java 
b/src/main/java/org/apache/commons/dbcp2/DelegatingResultSet.java
index dcec14f..cac9133 100644
--- a/src/main/java/org/apache/commons/dbcp2/DelegatingResultSet.java
+++ b/src/main/java/org/apache/commons/dbcp2/DelegatingResultSet.java
@@ -740,7 +740,7 @@ public final class DelegatingResultSet extends 
AbandonedTrace implements ResultS
     @Override
     public <T> T getObject(final int columnIndex, final Class<T> type) throws 
SQLException {
         try {
-            return resultSet.getObject(columnIndex, type);
+            return Jdbc41Bridge.getObject(resultSet, columnIndex, type);
         } catch (final SQLException e) {
             handleException(e);
             return null;
@@ -770,7 +770,7 @@ public final class DelegatingResultSet extends 
AbandonedTrace implements ResultS
     @Override
     public <T> T getObject(final String columnLabel, final Class<T> type) 
throws SQLException {
         try {
-            return resultSet.getObject(columnLabel, type);
+            return Jdbc41Bridge.getObject(resultSet, columnLabel, type);
         } catch (final SQLException e) {
             handleException(e);
             return null;

http://git-wip-us.apache.org/repos/asf/commons-dbcp/blob/3449a42b/src/main/java/org/apache/commons/dbcp2/DelegatingStatement.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/dbcp2/DelegatingStatement.java 
b/src/main/java/org/apache/commons/dbcp2/DelegatingStatement.java
index 38980f6..3df926b 100644
--- a/src/main/java/org/apache/commons/dbcp2/DelegatingStatement.java
+++ b/src/main/java/org/apache/commons/dbcp2/DelegatingStatement.java
@@ -161,7 +161,7 @@ public class DelegatingStatement extends AbandonedTrace 
implements Statement {
     public void closeOnCompletion() throws SQLException {
         checkOpen();
         try {
-            statement.closeOnCompletion();
+            Jdbc41Bridge.closeOnCompletion(statement);
         } catch (final SQLException e) {
             handleException(e);
         }
@@ -630,7 +630,7 @@ public class DelegatingStatement extends AbandonedTrace 
implements Statement {
     public boolean isCloseOnCompletion() throws SQLException {
         checkOpen();
         try {
-            return statement.isCloseOnCompletion();
+            return Jdbc41Bridge.isCloseOnCompletion(statement);
         } catch (final SQLException e) {
             handleException(e);
             return false;

http://git-wip-us.apache.org/repos/asf/commons-dbcp/blob/3449a42b/src/main/java/org/apache/commons/dbcp2/Jdbc41Bridge.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/dbcp2/Jdbc41Bridge.java 
b/src/main/java/org/apache/commons/dbcp2/Jdbc41Bridge.java
new file mode 100644
index 0000000..5c34181
--- /dev/null
+++ b/src/main/java/org/apache/commons/dbcp2/Jdbc41Bridge.java
@@ -0,0 +1,464 @@
+package org.apache.commons.dbcp2;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.Date;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.SQLXML;
+import java.sql.Statement;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.concurrent.Executor;
+import java.util.logging.Logger;
+
+import javax.sql.CommonDataSource;
+
+/**
+ * Defines bridge methods to JDBC 4.1 (Java 7) methods to allow call sites to 
operate safely (without
+ * {@link AbstractMethodError}) when using a JDBC driver written for JDBC 4.0 
(Java 6).
+ */
+public class Jdbc41Bridge {
+
+    /**
+     * Delegates to {@link Connection#abort(Executor)} without throwing a 
{@link AbstractMethodError}.
+     * <p>
+     * If the JDBC driver does not implement {@link 
Connection#abort(Executor)}, then call {@link Connection#close()}.
+     * </p>
+     *
+     * @param connection
+     *            the receiver
+     * @param executor
+     *            See {@link Connection#abort(Executor)}.
+     * @throws SQLException
+     *             See {@link Connection#abort(Executor)}.
+     * @see Connection#abort(Executor)
+     */
+    public static void abort(final Connection connection, final Executor 
executor) throws SQLException {
+        try {
+            connection.abort(executor);
+        } catch (final AbstractMethodError e) {
+            connection.close();
+        }
+    }
+
+    /**
+     * Delegates to {@link DatabaseMetaData#generatedKeyAlwaysReturned()} 
without throwing a
+     * {@link AbstractMethodError}.
+     * <p>
+     * If the JDBC driver does not implement {@link 
DatabaseMetaData#generatedKeyAlwaysReturned()}, then return false.
+     * </p>
+     *
+     * @param databaseMetaData
+     *            See {@link DatabaseMetaData#generatedKeyAlwaysReturned()}
+     * @return See {@link DatabaseMetaData#generatedKeyAlwaysReturned()}
+     * @throws SQLException
+     *             See {@link DatabaseMetaData#generatedKeyAlwaysReturned()}
+     * @see DatabaseMetaData#generatedKeyAlwaysReturned()
+     */
+    public static boolean generatedKeyAlwaysReturned(final DatabaseMetaData 
databaseMetaData) throws SQLException {
+        try {
+            return databaseMetaData.generatedKeyAlwaysReturned();
+        } catch (final AbstractMethodError e) {
+            // do nothing
+            return false;
+        }
+    }
+
+    /**
+     * Delegates to {@link Connection#getNetworkTimeout()} without throwing a 
{@link AbstractMethodError}.
+     * <p>
+     * If the JDBC driver does not implement {@link 
Connection#getNetworkTimeout()}, then return 0.
+     * </p>
+     *
+     * @param connection
+     *            the receiver
+     * @return See {@link Connection#getNetworkTimeout()}
+     * @throws SQLException
+     *             See {@link Connection#getNetworkTimeout()}
+     * @see Connection#getNetworkTimeout()
+     */
+    public static int getNetworkTimeout(final Connection connection) throws 
SQLException {
+        try {
+            return connection.getNetworkTimeout();
+        } catch (final AbstractMethodError e) {
+            return 0;
+        }
+    }
+
+    /**
+     * Delegates to {@link ResultSet#getObject(int, Class)} without throwing a 
{@link AbstractMethodError}.
+     * <p>
+     * If the JDBC driver does not implement {@link ResultSet#getObject(int, 
Class)}, then return 0.
+     * </p>
+     *
+     * @param <T>
+     *            See {@link ResultSet#getObject(int, Class)}
+     * @param resultSet
+     *            See {@link ResultSet#getObject(int, Class)}
+     * @param columnIndex
+     *            See {@link ResultSet#getObject(int, Class)}
+     * @param type
+     *            See {@link ResultSet#getObject(int, Class)}
+     * @return See {@link ResultSet#getObject(int, Class)}
+     * @throws SQLException
+     *             See {@link ResultSet#getObject(int, Class)}
+     * @see ResultSet#getObject(int, Class)
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T getObject(final ResultSet resultSet, final int 
columnIndex, final Class<T> type)
+            throws SQLException {
+        try {
+            return resultSet.getObject(columnIndex, type);
+        } catch (final AbstractMethodError e) {
+            if (type == String.class) {
+                return (T) resultSet.getString(columnIndex);
+            }
+            // Numbers
+            if (type == Integer.class) {
+                return (T) Integer.valueOf(resultSet.getInt(columnIndex));
+            }
+            if (type == Long.class) {
+                return (T) Long.valueOf(resultSet.getLong(columnIndex));
+            }
+            if (type == Double.class) {
+                return (T) Double.valueOf(resultSet.getDouble(columnIndex));
+            }
+            if (type == Float.class) {
+                return (T) Float.valueOf(resultSet.getFloat(columnIndex));
+            }
+            if (type == Short.class) {
+                return (T) Short.valueOf(resultSet.getShort(columnIndex));
+            }
+            if (type == BigDecimal.class) {
+                return (T) resultSet.getBigDecimal(columnIndex);
+            }
+            if (type == Byte.class) {
+                return (T) Byte.valueOf(resultSet.getByte(columnIndex));
+            }
+            // Dates
+            if (type == Date.class) {
+                return (T) resultSet.getDate(columnIndex);
+            }
+            if (type == Time.class) {
+                return (T) resultSet.getTime(columnIndex);
+            }
+            if (type == Timestamp.class) {
+                return (T) resultSet.getTimestamp(columnIndex);
+            }
+            // Streams
+            if (type == InputStream.class) {
+                return (T) resultSet.getBinaryStream(columnIndex);
+            }
+            if (type == Reader.class) {
+                return (T) resultSet.getCharacterStream(columnIndex);
+            }
+            // Other
+            if (type == Object.class) {
+                return (T) resultSet.getObject(columnIndex);
+            }
+            if (type == Boolean.class) {
+                return (T) Boolean.valueOf(resultSet.getBoolean(columnIndex));
+            }
+            if (type == Array.class) {
+                return (T) resultSet.getArray(columnIndex);
+            }
+            if (type == Blob.class) {
+                return (T) resultSet.getBlob(columnIndex);
+            }
+            if (type == Clob.class) {
+                return (T) resultSet.getClob(columnIndex);
+            }
+            if (type == Ref.class) {
+                return (T) resultSet.getRef(columnIndex);
+            }
+            if (type == RowId.class) {
+                return (T) resultSet.getRowId(columnIndex);
+            }
+            if (type == SQLXML.class) {
+                return (T) resultSet.getSQLXML(columnIndex);
+            }
+            if (type == URL.class) {
+                return (T) resultSet.getURL(columnIndex);
+            }
+            throw new SQLFeatureNotSupportedException(
+                    String.format("resultSet=%s, columnIndex=%,d, type=%s", 
resultSet, columnIndex, type));
+        }
+    }
+
+    /**
+     * Delegates to {@link ResultSet#getObject(String, Class)} without 
throwing a {@link AbstractMethodError}.
+     *
+     * @param <T>
+     *            See {@link ResultSet#getObject(String, Class)}
+     * @param resultSet
+     *            See {@link ResultSet#getObject(String, Class)}
+     * @param columnLabel
+     *            See {@link ResultSet#getObject(String, Class)}
+     * @param type
+     *            See {@link ResultSet#getObject(String, Class)}
+     * @return See {@link ResultSet#getObject(String, Class)}
+     * @throws SQLException
+     *             See {@link ResultSet#getObject(String, Class)}
+     * @see ResultSet#getObject(int, Class)
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T getObject(final ResultSet resultSet, final String 
columnLabel, final Class<T> type)
+            throws SQLException {
+        try {
+            return resultSet.getObject(columnLabel, type);
+        } catch (final AbstractMethodError e) {
+            // Numbers
+            if (type == Integer.class) {
+                return (T) Integer.valueOf(resultSet.getInt(columnLabel));
+            }
+            if (type == Long.class) {
+                return (T) Long.valueOf(resultSet.getLong(columnLabel));
+            }
+            if (type == Double.class) {
+                return (T) Double.valueOf(resultSet.getDouble(columnLabel));
+            }
+            if (type == Float.class) {
+                return (T) Float.valueOf(resultSet.getFloat(columnLabel));
+            }
+            if (type == Short.class) {
+                return (T) Short.valueOf(resultSet.getShort(columnLabel));
+            }
+            if (type == BigDecimal.class) {
+                return (T) resultSet.getBigDecimal(columnLabel);
+            }
+            if (type == Byte.class) {
+                return (T) Byte.valueOf(resultSet.getByte(columnLabel));
+            }
+            // Dates
+            if (type == Date.class) {
+                return (T) resultSet.getDate(columnLabel);
+            }
+            if (type == Time.class) {
+                return (T) resultSet.getTime(columnLabel);
+            }
+            if (type == Timestamp.class) {
+                return (T) resultSet.getTimestamp(columnLabel);
+            }
+            // Streams
+            if (type == InputStream.class) {
+                return (T) resultSet.getBinaryStream(columnLabel);
+            }
+            if (type == Reader.class) {
+                return (T) resultSet.getCharacterStream(columnLabel);
+            }
+            // Other
+            if (type == Object.class) {
+                return (T) resultSet.getObject(columnLabel);
+            }
+            if (type == Boolean.class) {
+                return (T) Boolean.valueOf(resultSet.getBoolean(columnLabel));
+            }
+            if (type == Array.class) {
+                return (T) resultSet.getArray(columnLabel);
+            }
+            if (type == Blob.class) {
+                return (T) resultSet.getBlob(columnLabel);
+            }
+            if (type == Clob.class) {
+                return (T) resultSet.getClob(columnLabel);
+            }
+            if (type == Ref.class) {
+                return (T) resultSet.getRef(columnLabel);
+            }
+            if (type == RowId.class) {
+                return (T) resultSet.getRowId(columnLabel);
+            }
+            if (type == SQLXML.class) {
+                return (T) resultSet.getSQLXML(columnLabel);
+            }
+            if (type == URL.class) {
+                return (T) resultSet.getURL(columnLabel);
+            }
+            throw new SQLFeatureNotSupportedException(
+                    String.format("resultSet=%s, columnLabel=%,d, type=%s", 
resultSet, columnLabel, type));
+        }
+    }
+
+    /**
+     * Delegates to {@link DatabaseMetaData#getPseudoColumns(String, String, 
String, String)} without throwing a
+     * {@link AbstractMethodError}.
+     * <p>
+     * If the JDBC driver does not implement {@link 
DatabaseMetaData#getPseudoColumns(String, String, String, String)},
+     * then return null.
+     * </p>
+     *
+     * @param databaseMetaData
+     *            the receiver
+     * @param catalog
+     *            See {@link DatabaseMetaData#getPseudoColumns(String, String, 
String, String)}
+     * @param schemaPattern
+     *            See {@link DatabaseMetaData#getPseudoColumns(String, String, 
String, String)}
+     * @param tableNamePattern
+     *            See {@link DatabaseMetaData#getPseudoColumns(String, String, 
String, String)}
+     * @param columnNamePattern
+     *            See {@link DatabaseMetaData#getPseudoColumns(String, String, 
String, String)}
+     * @return See {@link DatabaseMetaData#getPseudoColumns(String, String, 
String, String)}
+     * @throws SQLException
+     *             See {@link DatabaseMetaData#getPseudoColumns(String, 
String, String, String)}
+     * @see DatabaseMetaData#getPseudoColumns(String, String, String, String)
+     */
+    public static ResultSet getPseudoColumns(final DatabaseMetaData 
databaseMetaData, final String catalog,
+            final String schemaPattern, final String tableNamePattern, final 
String columnNamePattern)
+            throws SQLException {
+        try {
+            return databaseMetaData.getPseudoColumns(catalog, schemaPattern, 
tableNamePattern, columnNamePattern);
+        } catch (final AbstractMethodError e) {
+            // do nothing
+            return null;
+        }
+    }
+
+    /**
+     * Delegates to {@link Connection#getSchema()} without throwing a {@link 
AbstractMethodError}.
+     * <p>
+     * If the JDBC driver does not implement {@link Connection#getSchema()}, 
then return null.
+     * </p>
+     *
+     * @param connection
+     *            the receiver
+     * @return null for a JDBC 4 driver or a value per {@link 
Connection#getSchema()}.
+     * @throws SQLException
+     *             See {@link Connection#getSchema()}.
+     * @see Connection#getSchema()
+     */
+    public static String getSchema(final Connection connection) throws 
SQLException {
+        try {
+            return connection.getSchema();
+        } catch (final AbstractMethodError e) {
+            // do nothing
+            return null;
+        }
+    }
+
+    /**
+     * Delegates to {@link Connection#setNetworkTimeout(Executor, int)} 
without throwing a {@link AbstractMethodError}.
+     * <p>
+     * If the JDBC driver does not implement {@link 
Connection#setNetworkTimeout(Executor, int)}, then do nothing.
+     * </p>
+     *
+     * @param connection
+     *            the receiver
+     * @param executor
+     *            See {@link Connection#setNetworkTimeout(Executor, int)}
+     * @param milliseconds
+     *            {@link Connection#setNetworkTimeout(Executor, int)}
+     * @throws SQLException
+     *             {@link Connection#setNetworkTimeout(Executor, int)}
+     * @see Connection#setNetworkTimeout(Executor, int)
+     */
+    public static void setNetworkTimeout(final Connection connection, final 
Executor executor, final int milliseconds)
+            throws SQLException {
+        try {
+            connection.setNetworkTimeout(executor, milliseconds);
+        } catch (final AbstractMethodError e) {
+            // do nothing
+        }
+    }
+
+    /**
+     * Delegates to {@link Connection#setSchema(String)} without throwing a 
{@link AbstractMethodError}.
+     * <p>
+     * If the JDBC driver does not implement {@link 
Connection#setSchema(String)}, then do nothing.
+     * </p>
+     *
+     * @param connection
+     *            the receiver
+     * @param schema
+     *            See {@link Connection#setSchema(String)}.
+     * @throws SQLException
+     *             See {@link Connection#setSchema(String)}.
+     * @see Connection#setSchema(String)
+     */
+    public static void setSchema(final Connection connection, final String 
schema) throws SQLException {
+        try {
+            connection.setSchema(schema);
+        } catch (final AbstractMethodError e) {
+            // do nothing
+        }
+    }
+
+    /**
+     * Delegates to {@link Statement#closeOnCompletion()} without throwing a 
{@link AbstractMethodError}.
+     * <p>
+     * If the JDBC driver does not implement {@link 
Statement#closeOnCompletion()}, then just check that the connection
+     * is closed to then throw a SQLException.
+     * </p>
+     *
+     * @param statement
+     *            See {@link Statement#closeOnCompletion()}
+     * @throws SQLException
+     *             See {@link Statement#closeOnCompletion()}
+     * @see Statement#closeOnCompletion()
+     */
+    public static void closeOnCompletion(final Statement statement) throws 
SQLException {
+        try {
+            statement.closeOnCompletion();
+        } catch (final AbstractMethodError e) {
+            if (statement.isClosed()) {
+                throw new SQLException("Statement closed");
+            }
+        }
+    }
+
+    /**
+     * Delegates to {@link Statement#isCloseOnCompletion()} without throwing a 
{@link AbstractMethodError}.
+     * <p>
+     * If the JDBC driver does not implement {@link 
Statement#isCloseOnCompletion()}, then just check that the
+     * connection is closed to then throw a SQLException.
+     * </p>
+     *
+     * @param statement
+     *            See {@link Statement#isCloseOnCompletion()}
+     * @return See {@link Statement#isCloseOnCompletion()}
+     * @throws SQLException
+     *             See {@link Statement#isCloseOnCompletion()}
+     * @see Statement#closeOnCompletion()
+     */
+    public static boolean isCloseOnCompletion(final Statement statement) 
throws SQLException {
+        try {
+            return statement.isCloseOnCompletion();
+        } catch (final AbstractMethodError e) {
+            if (statement.isClosed()) {
+                throw new SQLException("Statement closed");
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Delegates to {@link CommonDataSource#getParentLogger()} without 
throwing a {@link AbstractMethodError}.
+     * <p>
+     * If the JDBC driver does not implement {@link 
CommonDataSource#getParentLogger()}, then return null.
+     * </p>
+     *
+     * @param commonDataSource
+     *            See {@link CommonDataSource#getParentLogger()}
+     * @return See {@link CommonDataSource#getParentLogger()}
+     * @throws SQLFeatureNotSupportedException
+     *             See {@link CommonDataSource#getParentLogger()}
+     */
+    public static Logger getParentLogger(final CommonDataSource 
commonDataSource) throws SQLFeatureNotSupportedException {
+        try {
+            return commonDataSource.getParentLogger();
+        } catch (final AbstractMethodError e) {
+            throw new 
SQLFeatureNotSupportedException("javax.sql.CommonDataSource#getParentLogger()");
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/commons-dbcp/blob/3449a42b/src/main/java/org/apache/commons/dbcp2/PoolableConnectionFactory.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/dbcp2/PoolableConnectionFactory.java 
b/src/main/java/org/apache/commons/dbcp2/PoolableConnectionFactory.java
index d99d728..8b4bfaa 100644
--- a/src/main/java/org/apache/commons/dbcp2/PoolableConnectionFactory.java
+++ b/src/main/java/org/apache/commons/dbcp2/PoolableConnectionFactory.java
@@ -440,8 +440,8 @@ public class PoolableConnectionFactory implements 
PooledObjectFactory<PoolableCo
         if (defaultCatalog != null && 
!defaultCatalog.equals(conn.getCatalog())) {
             conn.setCatalog(defaultCatalog);
         }
-        if (defaultSchema != null && 
!defaultSchema.equals(Utils.getSchema(conn))) {
-            conn.setSchema(defaultSchema);
+        if (defaultSchema != null && 
!defaultSchema.equals(Jdbc41Bridge.getSchema(conn))) {
+            Jdbc41Bridge.setSchema(conn, defaultSchema);
         }
         conn.setDefaultQueryTimeout(defaultQueryTimeoutSeconds);
     }

http://git-wip-us.apache.org/repos/asf/commons-dbcp/blob/3449a42b/src/main/java/org/apache/commons/dbcp2/Utils.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/dbcp2/Utils.java 
b/src/main/java/org/apache/commons/dbcp2/Utils.java
index 3a1ba1a..244b51b 100644
--- a/src/main/java/org/apache/commons/dbcp2/Utils.java
+++ b/src/main/java/org/apache/commons/dbcp2/Utils.java
@@ -20,7 +20,6 @@ package org.apache.commons.dbcp2;
 
 import java.sql.Connection;
 import java.sql.ResultSet;
-import java.sql.SQLException;
 import java.sql.Statement;
 import java.text.MessageFormat;
 import java.util.HashSet;
@@ -132,24 +131,6 @@ public final class Utils {
     }
 
     /**
-     * Gets the schema for the given connection while allowing for the 
underlying JDBC method to be missing when the
-     * driver is written for Java 6/JDBC 4.0.
-     * 
-     * @param conn
-     *            the Connection to query
-     * @return null for a JDBC 4 driver or a value per {@link 
Connection#getSchema()}.
-     * @throws SQLException
-     *             See {@link Connection#getSchema()}.
-     */
-    public static String getSchema(final Connection conn) throws SQLException {
-        try {
-            return conn.getSchema();
-        } catch (AbstractMethodError e) {
-            return null;
-        }
-    }
-    
-    /**
      * Gets the correct i18n message for the given key.
      *
      * @param key

http://git-wip-us.apache.org/repos/asf/commons-dbcp/blob/3449a42b/src/main/java/org/apache/commons/dbcp2/cpdsadapter/PooledConnectionImpl.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/dbcp2/cpdsadapter/PooledConnectionImpl.java 
b/src/main/java/org/apache/commons/dbcp2/cpdsadapter/PooledConnectionImpl.java
index 06edefb..715c0de 100644
--- 
a/src/main/java/org/apache/commons/dbcp2/cpdsadapter/PooledConnectionImpl.java
+++ 
b/src/main/java/org/apache/commons/dbcp2/cpdsadapter/PooledConnectionImpl.java
@@ -30,10 +30,10 @@ import javax.sql.StatementEventListener;
 
 import org.apache.commons.dbcp2.DelegatingConnection;
 import org.apache.commons.dbcp2.DelegatingPreparedStatement;
+import org.apache.commons.dbcp2.Jdbc41Bridge;
 import org.apache.commons.dbcp2.PStmtKey;
 import org.apache.commons.dbcp2.PoolableCallableStatement;
 import org.apache.commons.dbcp2.PoolablePreparedStatement;
-import org.apache.commons.dbcp2.Utils;
 import org.apache.commons.dbcp2.PoolingConnection.StatementType;
 import org.apache.commons.pool2.KeyedObjectPool;
 import org.apache.commons.pool2.KeyedPooledObjectFactory;
@@ -296,7 +296,7 @@ class PooledConnectionImpl
 
     private String getSchemaOrNull() {
         try {
-            return connection == null ? null : Utils.getSchema(connection);
+            return connection == null ? null : 
Jdbc41Bridge.getSchema(connection);
         } catch (final SQLException e) {
             return null;
         }

http://git-wip-us.apache.org/repos/asf/commons-dbcp/blob/3449a42b/src/test/java/org/apache/commons/dbcp2/datasources/ConnectionPoolDataSourceProxy.java
----------------------------------------------------------------------
diff --git 
a/src/test/java/org/apache/commons/dbcp2/datasources/ConnectionPoolDataSourceProxy.java
 
b/src/test/java/org/apache/commons/dbcp2/datasources/ConnectionPoolDataSourceProxy.java
index 0d51d47..1a2de79 100644
--- 
a/src/test/java/org/apache/commons/dbcp2/datasources/ConnectionPoolDataSourceProxy.java
+++ 
b/src/test/java/org/apache/commons/dbcp2/datasources/ConnectionPoolDataSourceProxy.java
@@ -25,6 +25,8 @@ import java.util.logging.Logger;
 import javax.sql.ConnectionPoolDataSource;
 import javax.sql.PooledConnection;
 
+import org.apache.commons.dbcp2.Jdbc41Bridge;
+
 /**
  * ConnectionPoolDataSource implementation that proxies another
  * ConnectionPoolDataSource.
@@ -80,7 +82,7 @@ public class ConnectionPoolDataSourceProxy implements 
ConnectionPoolDataSource {
 
     @Override
     public Logger getParentLogger() throws SQLFeatureNotSupportedException {
-        return delegate.getParentLogger();
+        return Jdbc41Bridge.getParentLogger(delegate);
     }
 
     /**

Reply via email to