In org.apache.tomcat.jdbc.pool.DataSourceProxy, isWrapperFor/unwrap always return false/null respectively. This is a spec violation, not least becaues unwrap should throw instead of returning null. A similar issue affects org.apache.tomcat.jdbc.pool.ProxyConnection. Correct implementations of these functions should look something like this (for DataSourceProxy): @SuppressWarnings("unused") // Has to match signature in DataSource public boolean isWrapperFor(Class<?> iface) throws SQLException { return poolProperties.getDataSource() instanceof DataSource && ((DataSource)poolProperties.getDataSource()).isWrapperFor(iface); } @SuppressWarnings("unused") // Has to match signature in DataSource public <T> T unwrap(Class<T> iface) throws SQLException { if (poolProperties.getDataSource() instanceof DataSource) { return ((DataSource)poolProperties.getDataSource()).unwrap(iface); } else { throw new SQLException("Not a wrapper for " + iface); } } And for ProxyConnection: public boolean isWrapperFor(Class<?> iface) throws SQLException { if (iface == XAConnection.class && connection.getXAConnection()!=null) { return true; } else { return connection.getConnection().isWrapperFor(iface); } } public Object unwrap(Class<?> iface) throws SQLException { if (iface == PooledConnection.class) { return connection; }else if (iface == XAConnection.class) { return connection.getXAConnection(); } else { return connection.getConnection().unwrap(iface); } }
This bug affects Tomcat DataSources used in a wrapping DataSource (example: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/jdbc/datasource/DelegatingDataSource.html). If you wrap a Tomcat DataSource in such a DataSource, there are the following problems: 1. wrapper.isWrapperFor(org.apache.tomcat.jdbc.pool.DataSource.class) wrongly returns false 2. wrapper.unwrap(org.apache.tomcat.jdbc.pool.DataSource.class) wrongly returns null instead of the Tomcat DataSource 3. wrapper.unwrap(org.apache.tomcat.jdbc.pool.DataSource) wrongly returns null instead of throwing an SQLException