Taken from https://issues.apache.org/jira/browse/DBCP-191

Index: src/test/org/apache/commons/dbcp/TesterPreparedStatement.java
===================================================================
--- src/test/org/apache/commons/dbcp/TesterPreparedStatement.java	(revision 558600)
+++ src/test/org/apache/commons/dbcp/TesterPreparedStatement.java	(working copy)
@@ -28,6 +28,13 @@
 import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 import java.util.Calendar;
+/* JDBC_4_ANT_KEY_BEGIN */
+import java.io.InputStream;
+import java.io.Reader;
+import java.sql.NClob;
+import java.sql.RowId;
+import java.sql.SQLXML;
+/* JDBC_4_ANT_KEY_END */
 
 /**
  * A dummy {@link PreparedStatement}, for testing purposes.
@@ -288,7 +295,79 @@
     public java.sql.ParameterMetaData getParameterMetaData() throws SQLException {
         throw new SQLException("Not implemented.");
     }
-
 /* JDBC_3_ANT_KEY_END */
+/* JDBC_4_ANT_KEY_BEGIN */
 
+    public void setRowId(int parameterIndex, RowId value) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void setNString(int parameterIndex, String value) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void setNClob(int parameterIndex, NClob value) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void setSQLXML(int parameterIndex, SQLXML value) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void setAsciiStream(int parameterIndex, InputStream inputStream, long length) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void setBinaryStream(int parameterIndex, InputStream inputStream, long length) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void setAsciiStream(int parameterIndex, InputStream inputStream) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void setBinaryStream(int parameterIndex, InputStream inputStream) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void setNCharacterStream(int parameterIndex, Reader reader) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void setClob(int parameterIndex, Reader reader) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void setNClob(int parameterIndex, Reader reader) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+/* JDBC_4_ANT_KEY_END */
 }
Index: src/test/org/apache/commons/dbcp/TesterResultSet.java
===================================================================
--- src/test/org/apache/commons/dbcp/TesterResultSet.java	(revision 558600)
+++ src/test/org/apache/commons/dbcp/TesterResultSet.java	(working copy)
@@ -28,6 +28,13 @@
 import java.sql.SQLWarning;
 import java.sql.Statement;
 import java.util.Calendar;
+/* JDBC_4_ANT_KEY_BEGIN */
+import java.io.InputStream;
+import java.io.Reader;
+import java.sql.NClob;
+import java.sql.RowId;
+import java.sql.SQLXML;
+/* JDBC_4_ANT_KEY_END */
 
 /**
  * A dummy {@link ResultSet}, for testing purposes.
@@ -759,7 +766,207 @@
         throws SQLException {
         throw new SQLException("Not implemented.");
     }
-
 /* JDBC_3_ANT_KEY_END */
+/* JDBC_4_ANT_KEY_BEGIN */
 
+    public boolean isWrapperFor(Class<?> iface) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public <T> T unwrap(Class<T> iface) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public RowId getRowId(int columnIndex) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public RowId getRowId(String columnLabel) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateRowId(int columnIndex, RowId value) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateRowId(String columnLabel, RowId value) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public int getHoldability() throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public boolean isClosed() throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateNString(int columnIndex, String value) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateNString(String columnLabel, String value) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateNClob(int columnIndex, NClob value) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateNClob(String columnLabel, NClob value) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public NClob getNClob(int columnIndex) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public NClob getNClob(String columnLabel) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public SQLXML getSQLXML(int columnIndex) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public SQLXML getSQLXML(String columnLabel) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateSQLXML(int columnIndex, SQLXML value) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateSQLXML(String columnLabel, SQLXML value) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public String getNString(int columnIndex) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public String getNString(String columnLabel) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public Reader getNCharacterStream(int columnIndex) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public Reader getNCharacterStream(String columnLabel) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateNCharacterStream(int columnIndex, Reader reader, long length) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateNCharacterStream(String columnLabel, Reader reader, long length) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateAsciiStream(int columnIndex, InputStream inputStream, long length) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateBinaryStream(int columnIndex, InputStream inputStream, long length) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateCharacterStream(int columnIndex, Reader reader, long length) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateAsciiStream(String columnLabel, InputStream inputStream, long length) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateBinaryStream(String columnLabel, InputStream inputStream, long length) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateCharacterStream(String columnLabel, Reader reader, long length) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateClob(int columnIndex, Reader reader, long length) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateClob(String columnLabel, Reader reader, long length) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateNCharacterStream(int columnIndex, Reader reader) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateNCharacterStream(String columnLabel, Reader reader) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateAsciiStream(int columnIndex, InputStream inputStream) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateBinaryStream(int columnIndex, InputStream inputStream) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateCharacterStream(int columnIndex, Reader reader) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateAsciiStream(String columnLabel, InputStream inputStream) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateBinaryStream(String columnLabel, InputStream inputStream) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateCharacterStream(String columnLabel, Reader reader) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateClob(int columnIndex, Reader reader) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateClob(String columnLabel, Reader reader) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateNClob(int columnIndex, Reader reader) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void updateNClob(String columnLabel, Reader reader) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+/* JDBC_4_ANT_KEY_END */
 }
Index: src/test/org/apache/commons/dbcp/TesterConnection.java
===================================================================
--- src/test/org/apache/commons/dbcp/TesterConnection.java	(revision 558600)
+++ src/test/org/apache/commons/dbcp/TesterConnection.java	(working copy)
@@ -25,6 +25,16 @@
 import java.sql.SQLWarning;
 import java.sql.Statement;
 import java.util.Map;
+/* JDBC_4_ANT_KEY_BEGIN */
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.NClob;
+import java.sql.SQLClientInfoException;
+import java.sql.SQLXML;
+import java.sql.Struct;
+import java.util.Properties;
+/* JDBC_4_ANT_KEY_END */
 
 /**
  * A dummy {@link Connection}, for testing purposes.
@@ -274,6 +284,59 @@
         throws SQLException {
         return prepareStatement(sql);
     }
+/* JDBC_3_ANT_KEY_END */
+/* JDBC_4_ANT_KEY_BEGIN */
 
-/* JDBC_3_ANT_KEY_END */
+    public boolean isWrapperFor(Class<?> iface) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public <T> T unwrap(Class<T> iface) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public Blob createBlob() throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public Clob createClob() throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public NClob createNClob() throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public SQLXML createSQLXML() throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public boolean isValid(int timeout) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void setClientInfo(String name, String value) throws SQLClientInfoException {
+        throw new SQLClientInfoException();
+    }
+
+    public void setClientInfo(Properties properties) throws SQLClientInfoException {
+        throw new SQLClientInfoException();
+    }
+
+    public Properties getClientInfo() throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public String getClientInfo(String name) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+/* JDBC_4_ANT_KEY_END */
 }
Index: src/test/org/apache/commons/dbcp/TesterStatement.java
===================================================================
--- src/test/org/apache/commons/dbcp/TesterStatement.java	(revision 558600)
+++ src/test/org/apache/commons/dbcp/TesterStatement.java	(working copy)
@@ -268,5 +268,26 @@
         throw new SQLException("Not implemented.");
     }
 /* JDBC_3_ANT_KEY_END */
+/* JDBC_4_ANT_KEY_BEGIN */
 
+    public boolean isWrapperFor(Class<?> iface) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public <T> T unwrap(Class<T> iface) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public boolean isClosed() throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public void setPoolable(boolean poolable) throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+
+    public boolean isPoolable() throws SQLException {
+        throw new SQLException("Not implemented.");
+    }
+/* JDBC_4_ANT_KEY_END */
 }
Index: src/java/org/apache/commons/dbcp/DelegatingCallableStatement.java
===================================================================
--- src/java/org/apache/commons/dbcp/DelegatingCallableStatement.java	(revision 558600)
+++ src/java/org/apache/commons/dbcp/DelegatingCallableStatement.java	(working copy)
@@ -32,6 +32,11 @@
 import java.io.InputStream;
 import java.io.Reader;
 import java.sql.SQLException;
+/* JDBC_4_ANT_KEY_BEGIN */
+import java.sql.NClob;
+import java.sql.RowId;
+import java.sql.SQLXML;
+/* JDBC_4_ANT_KEY_END */
 
 /**
  * A base delegating implementation of {@link CallableStatement}.
@@ -332,6 +337,337 @@
 
     public URL getURL(String parameterName) throws SQLException
     { checkOpen(); try { return _stmt.getURL(parameterName); } catch (SQLException e) { handleException(e); return null; } }
+/* JDBC_3_ANT_KEY_END */
+/* JDBC_4_ANT_KEY_BEGIN */
 
-/* JDBC_3_ANT_KEY_END */
+    public RowId getRowId(int parameterIndex) throws SQLException {
+        checkOpen();
+        try {
+            return _stmt.getRowId(parameterIndex);
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public RowId getRowId(String parameterName) throws SQLException {
+        checkOpen();
+        try {
+            return _stmt.getRowId(parameterName);
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public void setRowId(String parameterName, RowId value) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setRowId(parameterName, value);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setNString(String parameterName, String value) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setNString(parameterName, value);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setNCharacterStream(String parameterName, Reader reader, long length) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setNCharacterStream(parameterName, reader, length);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setNClob(String parameterName, NClob value) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setNClob(parameterName, value);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setClob(String parameterName, Reader reader, long length) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setClob(parameterName, reader, length);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setBlob(String parameterName, InputStream inputStream, long length) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setBlob(parameterName, inputStream, length);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setNClob(String parameterName, Reader reader, long length) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setNClob(parameterName, reader, length);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public NClob getNClob(int parameterIndex) throws SQLException {
+        checkOpen();
+        try {
+            return _stmt.getNClob(parameterIndex);
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public NClob getNClob(String parameterName) throws SQLException {
+        checkOpen();
+        try {
+            return _stmt.getNClob(parameterName);
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public void setSQLXML(String parameterName, SQLXML value) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setSQLXML(parameterName, value);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public SQLXML getSQLXML(int parameterIndex) throws SQLException {
+        checkOpen();
+        try {
+            return _stmt.getSQLXML(parameterIndex);
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public SQLXML getSQLXML(String parameterName) throws SQLException {
+        checkOpen();
+        try {
+            return _stmt.getSQLXML(parameterName);
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public String getNString(int parameterIndex) throws SQLException {
+        checkOpen();
+        try {
+            return _stmt.getNString(parameterIndex);
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public String getNString(String parameterName) throws SQLException {
+        checkOpen();
+        try {
+            return _stmt.getNString(parameterName);
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public Reader getNCharacterStream(int parameterIndex) throws SQLException {
+        checkOpen();
+        try {
+            return _stmt.getNCharacterStream(parameterIndex);
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public Reader getNCharacterStream(String parameterName) throws SQLException {
+        checkOpen();
+        try {
+            return _stmt.getNCharacterStream(parameterName);
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public Reader getCharacterStream(int parameterIndex) throws SQLException {
+        checkOpen();
+        try {
+            return _stmt.getCharacterStream(parameterIndex);
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public Reader getCharacterStream(String parameterName) throws SQLException {
+        checkOpen();
+        try {
+            return _stmt.getCharacterStream(parameterName);
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public void setBlob(String parameterName, Blob blob) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setBlob(parameterName, blob);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setClob(String parameterName, Clob clob) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setClob(parameterName, clob);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setAsciiStream(String parameterName, InputStream inputStream, long length) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setAsciiStream(parameterName, inputStream, length);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setBinaryStream(String parameterName, InputStream inputStream, long length) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setBinaryStream(parameterName, inputStream, length);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setCharacterStream(String parameterName, Reader reader, long length) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setCharacterStream(parameterName, reader, length);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setAsciiStream(String parameterName, InputStream inputStream) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setAsciiStream(parameterName, inputStream);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setBinaryStream(String parameterName, InputStream inputStream) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setBinaryStream(parameterName, inputStream);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setCharacterStream(String parameterName, Reader reader) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setCharacterStream(parameterName, reader);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setNCharacterStream(String parameterName, Reader reader) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setNCharacterStream(parameterName, reader);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setClob(String parameterName, Reader reader) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setClob(parameterName, reader);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }    }
+
+    public void setBlob(String parameterName, InputStream inputStream) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setBlob(parameterName, inputStream);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }    }
+
+    public void setNClob(String parameterName, Reader reader) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setNClob(parameterName, reader);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+/* JDBC_4_ANT_KEY_END */
 }
Index: src/java/org/apache/commons/dbcp/cpdsadapter/ConnectionImpl.java
===================================================================
--- src/java/org/apache/commons/dbcp/cpdsadapter/ConnectionImpl.java	(revision 558600)
+++ src/java/org/apache/commons/dbcp/cpdsadapter/ConnectionImpl.java	(working copy)
@@ -25,6 +25,19 @@
 import java.sql.Statement;
 import java.sql.SQLWarning;
 import java.sql.SQLException;
+/* JDBC_4_ANT_KEY_BEGIN */
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.ClientInfoStatus;
+import java.sql.Clob;
+import java.sql.NClob;
+import java.sql.SQLClientInfoException;
+import java.sql.SQLXML;
+import java.sql.Struct;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Properties;
+/* JDBC_4_ANT_KEY_END */
 
 /**
  * This class is the <code>Connection</code> that will be returned
@@ -42,6 +55,11 @@
     private static final String CLOSED 
             = "Attempted to use Connection after closed() was called.";
 
+/* JDBC_4_ANT_KEY_BEGIN */
+    private static final Map<String, ClientInfoStatus> EMPTY_FAILED_PROPERTIES =
+        Collections.<String, ClientInfoStatus>emptyMap();
+/* JDBC_4_ANT_KEY_END */
+
     /** The JDBC database connection. */
     private Connection connection;
 
@@ -453,6 +471,86 @@
         assertOpen();
         return connection.prepareStatement(sql, columnNames);
     }
+/* JDBC_3_ANT_KEY_END */
+/* JDBC_4_ANT_KEY_BEGIN */
 
-/* JDBC_3_ANT_KEY_END */
+    public boolean isWrapperFor(Class<?> iface) throws SQLException {
+        return connection.isWrapperFor(iface);
+    }
+
+    public <T> T unwrap(Class<T> iface) throws SQLException {
+        return connection.unwrap(iface);
+    }
+
+    public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
+        assertOpen();
+        return connection.createArrayOf(typeName, elements);
+    }
+
+    public Blob createBlob() throws SQLException {
+        assertOpen();
+        return connection.createBlob();
+    }
+
+    public Clob createClob() throws SQLException {
+        assertOpen();
+        return connection.createClob();
+    }
+
+    public NClob createNClob() throws SQLException {
+        assertOpen();
+        return connection.createNClob();
+    }
+
+    public SQLXML createSQLXML() throws SQLException {
+        assertOpen();
+        return connection.createSQLXML();
+    }
+
+    public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
+        assertOpen();
+        return connection.createStruct(typeName, attributes);
+    }
+
+    public boolean isValid(int timeout) throws SQLException {
+        assertOpen();
+        return connection.isValid(timeout);
+    }
+
+    public void setClientInfo(String name, String value) throws SQLClientInfoException {
+        try {
+            assertOpen();
+            connection.setClientInfo(name, value);
+        }
+        catch (SQLClientInfoException e) {
+            throw e;
+        }
+        catch (SQLException e) {
+            throw new SQLClientInfoException("Connection is closed.", EMPTY_FAILED_PROPERTIES, e);
+        }
+    }
+
+    public void setClientInfo(Properties properties) throws SQLClientInfoException {
+        try {
+            assertOpen();
+            connection.setClientInfo(properties);
+        }
+        catch (SQLClientInfoException e) {
+            throw e;
+        }
+        catch (SQLException e) {
+            throw new SQLClientInfoException("Connection is closed.", EMPTY_FAILED_PROPERTIES, e);
+        }
+    }
+
+    public Properties getClientInfo() throws SQLException {
+        assertOpen();
+        return connection.getClientInfo();
+    }
+
+    public String getClientInfo(String name) throws SQLException {
+        assertOpen();
+        return connection.getClientInfo(name);
+    }
+/* JDBC_4_ANT_KEY_END */
 }
Index: src/java/org/apache/commons/dbcp/cpdsadapter/PooledConnectionImpl.java
===================================================================
--- src/java/org/apache/commons/dbcp/cpdsadapter/PooledConnectionImpl.java	(revision 558600)
+++ src/java/org/apache/commons/dbcp/cpdsadapter/PooledConnectionImpl.java	(working copy)
@@ -26,6 +26,7 @@
 import javax.sql.ConnectionEvent;
 import javax.sql.ConnectionEventListener;
 import javax.sql.PooledConnection;
+import javax.sql.StatementEventListener;
 
 import org.apache.commons.dbcp.DelegatingConnection;
 import org.apache.commons.dbcp.DelegatingPreparedStatement;
@@ -66,6 +67,11 @@
     private Vector eventListeners;
 
     /**
+     * StatementEventListeners
+     */
+    private Vector statementEventListeners;
+
+    /**
      * flag set to true, once close() is called.
      */
     boolean isClosed;
@@ -101,6 +107,12 @@
         }
     }
 
+    public void addStatementEventListener(StatementEventListener listener) {
+        if (!statementEventListeners.contains(listener)) {
+            statementEventListeners.add(listener);
+        }
+    }
+
     /**
      * Closes the physical connection and marks this 
      * <code>PooledConnection</code> so that it may not be used 
@@ -169,6 +181,10 @@
         eventListeners.remove(listener);
     }
 
+    public void removeStatementEventListener(StatementEventListener listener) {
+        statementEventListeners.remove(listener);
+    }
+
     /**
      * Closes the physical connection and checks that the logical connection
      * was closed as well.
Index: src/java/org/apache/commons/dbcp/DelegatingPreparedStatement.java
===================================================================
--- src/java/org/apache/commons/dbcp/DelegatingPreparedStatement.java	(revision 558600)
+++ src/java/org/apache/commons/dbcp/DelegatingPreparedStatement.java	(working copy)
@@ -27,6 +27,13 @@
 import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 import java.util.Calendar;
+/* JDBC_4_ANT_KEY_BEGIN */
+import java.io.InputStream;
+import java.io.Reader;
+import java.sql.NClob;
+import java.sql.RowId;
+import java.sql.SQLXML;
+/* JDBC_4_ANT_KEY_END */
 
 /**
  * A base delegating implementation of {@link PreparedStatement}.
@@ -221,6 +228,187 @@
 
     public java.sql.ParameterMetaData getParameterMetaData() throws SQLException
     { checkOpen(); try { return _stmt.getParameterMetaData(); } catch (SQLException e) { handleException(e); return null; } }
+/* JDBC_3_ANT_KEY_END */
+/* JDBC_4_ANT_KEY_BEGIN */
 
-/* JDBC_3_ANT_KEY_END */
+    public void setRowId(int parameterIndex, RowId value) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setRowId(parameterIndex, value);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setNString(int parameterIndex, String value) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setNString(parameterIndex, value);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setNCharacterStream(parameterIndex, value, length);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setNClob(int parameterIndex, NClob value) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setNClob(parameterIndex, value);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setClob(parameterIndex, reader, length);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setBlob(parameterIndex, inputStream, length);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setNClob(parameterIndex, reader, length);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setSQLXML(int parameterIndex, SQLXML value) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setSQLXML(parameterIndex, value);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setAsciiStream(int parameterIndex, InputStream inputStream, long length) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setAsciiStream(parameterIndex, inputStream, length);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setBinaryStream(int parameterIndex, InputStream inputStream, long length) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setBinaryStream(parameterIndex, inputStream, length);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setCharacterStream(parameterIndex, reader, length);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setAsciiStream(int parameterIndex, InputStream inputStream) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setAsciiStream(parameterIndex, inputStream);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setBinaryStream(int parameterIndex, InputStream inputStream) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setBinaryStream(parameterIndex, inputStream);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setCharacterStream(parameterIndex, reader);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setNCharacterStream(int parameterIndex, Reader reader) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setNCharacterStream(parameterIndex, reader);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setClob(int parameterIndex, Reader reader) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setClob(parameterIndex, reader);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setBlob(parameterIndex, inputStream);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void setNClob(int parameterIndex, Reader reader) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setNClob(parameterIndex, reader);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+/* JDBC_4_ANT_KEY_END */
 }
Index: src/java/org/apache/commons/dbcp/DelegatingResultSet.java
===================================================================
--- src/java/org/apache/commons/dbcp/DelegatingResultSet.java	(revision 558600)
+++ src/java/org/apache/commons/dbcp/DelegatingResultSet.java	(working copy)
@@ -34,6 +34,11 @@
 import java.sql.Clob;
 import java.sql.Array;
 import java.util.Calendar;
+/* JDBC_4_ANT_KEY_BEGIN */
+import java.sql.NClob;
+import java.sql.RowId;
+import java.sql.SQLXML;
+/* JDBC_4_ANT_KEY_END */
 
 /**
  * A base delegating implementation of {@link ResultSet}.
@@ -585,6 +590,459 @@
 
     public void updateArray(String columnName, java.sql.Array x) throws SQLException
     { try { _res.updateArray(columnName, x); } catch (SQLException e) { handleException(e); } }
+/* JDBC_3_ANT_KEY_END */
+/* JDBC_4_ANT_KEY_BEGIN */
 
-/* JDBC_3_ANT_KEY_END */
+    public boolean isWrapperFor(Class<?> iface) throws SQLException {
+        return _res.isWrapperFor(iface);
+    }
+
+    public <T> T unwrap(Class<T> iface) throws SQLException {
+        return _res.unwrap(iface);
+    }
+
+    public RowId getRowId(int columnIndex) throws SQLException {
+        try {
+            return _res.getRowId(columnIndex);
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public RowId getRowId(String columnLabel) throws SQLException {
+        try {
+            return _res.getRowId(columnLabel);
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public void updateRowId(int columnIndex, RowId value) throws SQLException {
+        try {
+            _res.updateRowId(columnIndex, value);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateRowId(String columnLabel, RowId value) throws SQLException {
+        try {
+            _res.updateRowId(columnLabel, value);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public int getHoldability() throws SQLException {
+        try {
+            return _res.getHoldability();
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return 0;
+        }
+    }
+
+    public boolean isClosed() throws SQLException {
+        try {
+            return _res.isClosed();
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return false;
+        }
+    }
+
+    public void updateNString(int columnIndex, String value) throws SQLException {
+        try {
+            _res.updateNString(columnIndex, value);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateNString(String columnLabel, String value) throws SQLException {
+        try {
+            _res.updateNString(columnLabel, value);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateNClob(int columnIndex, NClob value) throws SQLException {
+        try {
+            _res.updateNClob(columnIndex, value);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateNClob(String columnLabel, NClob value) throws SQLException {
+        try {
+            _res.updateNClob(columnLabel, value);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public NClob getNClob(int columnIndex) throws SQLException {
+        try {
+            return _res.getNClob(columnIndex);
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public NClob getNClob(String columnLabel) throws SQLException {
+        try {
+            return _res.getNClob(columnLabel);
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public SQLXML getSQLXML(int columnIndex) throws SQLException {
+        try {
+            return _res.getSQLXML(columnIndex);
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public SQLXML getSQLXML(String columnLabel) throws SQLException {
+        try {
+            return _res.getSQLXML(columnLabel);
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public void updateSQLXML(int columnIndex, SQLXML value) throws SQLException {
+        try {
+            _res.updateSQLXML(columnIndex, value);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateSQLXML(String columnLabel, SQLXML value) throws SQLException {
+        try {
+            _res.updateSQLXML(columnLabel, value);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public String getNString(int columnIndex) throws SQLException {
+        try {
+            return _res.getNString(columnIndex);
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public String getNString(String columnLabel) throws SQLException {
+        try {
+            return _res.getNString(columnLabel);
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public Reader getNCharacterStream(int columnIndex) throws SQLException {
+        try {
+            return _res.getNCharacterStream(columnIndex);
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public Reader getNCharacterStream(String columnLabel) throws SQLException {
+        try {
+            return _res.getNCharacterStream(columnLabel);
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public void updateNCharacterStream(int columnIndex, Reader reader, long length) throws SQLException {
+        try {
+            _res.updateNCharacterStream(columnIndex, reader, length);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateNCharacterStream(String columnLabel, Reader reader, long length) throws SQLException {
+        try {
+            _res.updateNCharacterStream(columnLabel, reader, length);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateAsciiStream(int columnIndex, InputStream inputStream, long length) throws SQLException {
+        try {
+            _res.updateAsciiStream(columnIndex, inputStream, length);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateBinaryStream(int columnIndex, InputStream inputStream, long length) throws SQLException {
+        try {
+            _res.updateBinaryStream(columnIndex, inputStream, length);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateCharacterStream(int columnIndex, Reader reader, long length) throws SQLException {
+        try {
+            _res.updateCharacterStream(columnIndex, reader, length);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateAsciiStream(String columnLabel, InputStream inputStream, long length) throws SQLException {
+        try {
+            _res.updateAsciiStream(columnLabel, inputStream, length);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateBinaryStream(String columnLabel, InputStream inputStream, long length) throws SQLException {
+        try {
+            _res.updateBinaryStream(columnLabel, inputStream, length);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateCharacterStream(String columnLabel, Reader reader, long length) throws SQLException {
+        try {
+            _res.updateCharacterStream(columnLabel, reader, length);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException {
+        try {
+            _res.updateBlob(columnIndex, inputStream, length);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException {
+        try {
+            _res.updateBlob(columnLabel, inputStream, length);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateClob(int columnIndex, Reader reader, long length) throws SQLException {
+        try {
+            _res.updateClob(columnIndex, reader, length);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateClob(String columnLabel, Reader reader, long length) throws SQLException {
+        try {
+            _res.updateClob(columnLabel, reader, length);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException {
+        try {
+            _res.updateNClob(columnIndex, reader, length);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException {
+        try {
+            _res.updateNClob(columnLabel, reader, length);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateNCharacterStream(int columnIndex, Reader reader) throws SQLException {
+        try {
+            _res.updateNCharacterStream(columnIndex, reader);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateNCharacterStream(String columnLabel, Reader reader) throws SQLException {
+        try {
+            _res.updateNCharacterStream(columnLabel, reader);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateAsciiStream(int columnIndex, InputStream inputStream) throws SQLException {
+        try {
+            _res.updateAsciiStream(columnIndex, inputStream);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateBinaryStream(int columnIndex, InputStream inputStream) throws SQLException {
+        try {
+            _res.updateBinaryStream(columnIndex, inputStream);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateCharacterStream(int columnIndex, Reader reader) throws SQLException {
+        try {
+            _res.updateCharacterStream(columnIndex, reader);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateAsciiStream(String columnLabel, InputStream inputStream) throws SQLException {
+        try {
+            _res.updateAsciiStream(columnLabel, inputStream);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateBinaryStream(String columnLabel, InputStream inputStream) throws SQLException {
+        try {
+            _res.updateBinaryStream(columnLabel, inputStream);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateCharacterStream(String columnLabel, Reader reader) throws SQLException {
+        try {
+            _res.updateCharacterStream(columnLabel, reader);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException {
+        try {
+            _res.updateBlob(columnIndex, inputStream);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException {
+        try {
+            _res.updateBlob(columnLabel, inputStream);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateClob(int columnIndex, Reader reader) throws SQLException {
+        try {
+            _res.updateClob(columnIndex, reader);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateClob(String columnLabel, Reader reader) throws SQLException {
+        try {
+            _res.updateClob(columnLabel, reader);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateNClob(int columnIndex, Reader reader) throws SQLException {
+        try {
+            _res.updateNClob(columnIndex, reader);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public void updateNClob(String columnLabel, Reader reader) throws SQLException {
+        try {
+            _res.updateNClob(columnLabel, reader);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+/* JDBC_4_ANT_KEY_END */
 }
Index: src/java/org/apache/commons/dbcp/PoolingDataSource.java
===================================================================
--- src/java/org/apache/commons/dbcp/PoolingDataSource.java	(revision 558600)
+++ src/java/org/apache/commons/dbcp/PoolingDataSource.java	(working copy)
@@ -84,6 +84,14 @@
     public void setAccessToUnderlyingConnectionAllowed(boolean allow) {
         this.accessToUnderlyingConnectionAllowed = allow;
     }
+
+    public boolean isWrapperFor(Class<?> iface) throws SQLException {
+        return false;
+    }
+
+    public <T> T unwrap(Class<T> iface) throws SQLException {
+        throw new SQLException("PoolingDataSource is not a wrapper.");
+    }
     
     //--- DataSource methods -----------------------------------------
 
Index: src/java/org/apache/commons/dbcp/DelegatingConnection.java
===================================================================
--- src/java/org/apache/commons/dbcp/DelegatingConnection.java	(revision 558600)
+++ src/java/org/apache/commons/dbcp/DelegatingConnection.java	(working copy)
@@ -26,6 +26,19 @@
 import java.sql.Statement;
 import java.util.List;
 import java.util.Map;
+/* JDBC_4_ANT_KEY_BEGIN */
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.ClientInfoStatus;
+import java.sql.Clob;
+import java.sql.NClob;
+import java.sql.SQLClientInfoException;
+import java.sql.SQLXML;
+import java.sql.Struct;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Properties;
+/* JDBC_4_ANT_KEY_END */
 
 /**
  * A base delegating implementation of {@link Connection}.
@@ -50,6 +63,10 @@
  */
 public class DelegatingConnection extends AbandonedTrace
         implements Connection {
+/* JDBC_4_ANT_KEY_BEGIN */
+    private static final Map<String, ClientInfoStatus> EMPTY_FAILED_PROPERTIES =
+        Collections.<String, ClientInfoStatus>emptyMap();
+/* JDBC_4_ANT_KEY_END */
     /** My delegate {@link Connection}. */
     protected Connection _conn = null;
 
@@ -495,4 +512,139 @@
         }
     }
 /* JDBC_3_ANT_KEY_END */
+/* JDBC_4_ANT_KEY_BEGIN */
+
+    public boolean isWrapperFor(Class<?> iface) throws SQLException {
+        return _conn.isWrapperFor(iface);
+    }
+
+    public <T> T unwrap(Class<T> iface) throws SQLException {
+        return _conn.unwrap(iface);
+    }
+
+    public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
+        checkOpen();
+        try {
+            return _conn.createArrayOf(typeName, elements);
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public Blob createBlob() throws SQLException {
+        checkOpen();
+        try {
+            return _conn.createBlob();
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public Clob createClob() throws SQLException {
+        checkOpen();
+        try {
+            return _conn.createClob();
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public NClob createNClob() throws SQLException {
+        checkOpen();
+        try {
+            return _conn.createNClob();
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public SQLXML createSQLXML() throws SQLException {
+        checkOpen();
+        try {
+            return _conn.createSQLXML();
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
+        checkOpen();
+        try {
+            return _conn.createStruct(typeName, attributes);
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public boolean isValid(int timeout) throws SQLException {
+        checkOpen();
+        try {
+            return _conn.isValid(timeout);
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return false;
+        }
+    }
+
+    public void setClientInfo(String name, String value) throws SQLClientInfoException {
+        try {
+            checkOpen();
+            _conn.setClientInfo(name, value);
+        }
+        catch (SQLClientInfoException e) {
+            throw e;
+        }
+        catch (SQLException e) {
+            throw new SQLClientInfoException("Connection is closed.", EMPTY_FAILED_PROPERTIES, e);
+        }
+    }
+
+    public void setClientInfo(Properties properties) throws SQLClientInfoException {
+        try {
+            checkOpen();
+            _conn.setClientInfo(properties);
+        }
+        catch (SQLClientInfoException e) {
+            throw e;
+        }
+        catch (SQLException e) {
+            throw new SQLClientInfoException("Connection is closed.", EMPTY_FAILED_PROPERTIES, e);
+        }
+    }
+
+    public Properties getClientInfo() throws SQLException {
+        checkOpen();
+        try {
+            return _conn.getClientInfo();
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+
+    public String getClientInfo(String name) throws SQLException {
+        checkOpen();
+        try {
+            return _conn.getClientInfo(name);
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return null;
+        }
+    }
+/* JDBC_4_ANT_KEY_END */
 }
Index: src/java/org/apache/commons/dbcp/DelegatingStatement.java
===================================================================
--- src/java/org/apache/commons/dbcp/DelegatingStatement.java	(revision 558600)
+++ src/java/org/apache/commons/dbcp/DelegatingStatement.java	(working copy)
@@ -128,10 +128,6 @@
 
     protected boolean _closed = false;
 
-    protected boolean isClosed() {
-        return _closed;
-    }
-
     protected void checkOpen() throws SQLException {
         if(isClosed()) {
             throw new SQLException
@@ -346,4 +342,39 @@
     { checkOpen(); try { return _stmt.getResultSetHoldability(); } catch (SQLException e) { handleException(e); return 0; } }
 
 /* JDBC_3_ANT_KEY_END */
+/* JDBC_4_ANT_KEY_BEGIN */
+
+    public boolean isWrapperFor(Class<?> iface) throws SQLException {
+        return _conn.isWrapperFor(iface);
+    }
+
+    public <T> T unwrap(Class<T> iface) throws SQLException {
+        return _conn.unwrap(iface);
+    }
+
+    public boolean isClosed() throws SQLException {
+        return _closed;
+    }
+
+    public void setPoolable(boolean poolable) throws SQLException {
+        checkOpen();
+        try {
+            _stmt.setPoolable(poolable);
+        }
+        catch (SQLException e) {
+            handleException(e);
+        }
+    }
+
+    public boolean isPoolable() throws SQLException {
+        checkOpen();
+        try {
+            return _stmt.isPoolable();
+        }
+        catch (SQLException e) {
+            handleException(e);
+            return false;
+        }
+    }
+/* JDBC_4_ANT_KEY_END */
 }
Index: src/java/org/apache/commons/dbcp/BasicDataSource.java
===================================================================
--- src/java/org/apache/commons/dbcp/BasicDataSource.java	(revision 558600)
+++ src/java/org/apache/commons/dbcp/BasicDataSource.java	(working copy)
@@ -1115,7 +1115,14 @@
         }
     }
 
+    public boolean isWrapperFor(Class<?> iface) throws SQLException {
+        return false;
+    }
 
+    public <T> T unwrap(Class<T> iface) throws SQLException {
+        throw new SQLException("BasicDataSource is not a wrapper.");
+    }
+
     // ------------------------------------------------------ Protected Methods
 
 
Index: src/java/org/apache/commons/dbcp/datasources/InstanceKeyDataSource.java
===================================================================
--- src/java/org/apache/commons/dbcp/datasources/InstanceKeyDataSource.java	(revision 558600)
+++ src/java/org/apache/commons/dbcp/datasources/InstanceKeyDataSource.java	(working copy)
@@ -154,6 +154,14 @@
      */
     public abstract void close() throws Exception;
 
+    public boolean isWrapperFor(Class<?> iface) throws SQLException {
+        return false;
+    }
+
+    public <T> T unwrap(Class<T> iface) throws SQLException {
+        throw new SQLException("InstanceKeyDataSource is not a wrapper.");
+    }
+
     // -------------------------------------------------------------------
     // Properties
 
Index: project.properties
===================================================================
--- project.properties	(revision 558600)
+++ project.properties	(working copy)
@@ -30,8 +30,8 @@
 maven.xdoc.developmentProcessUrl=http://jakarta.apache.org/commons/charter.html
 
 # JDK level
-maven.compile.source=1.3
-maven.compile.target=1.3
+maven.compile.source=1.6
+maven.compile.target=1.6
 
 # Merge in a file containing just Built-By attribute
 maven.jar.manifest=${basedir}/manifestMods.txt