Avoid NoSuchMethodError from UCP's PoolDataSource.getPassword()

While still present and marked as deprecated, the getPassword()
method on UCP's PoolDataSource has been implemented to throw a
NoSuchMethodError making it useless for our purposes.

This commit updates DataSourceBuilder to avoid using the getter. This
means that a password must now be provided when trying to derive a
new DataSource from an existing PoolDataSource.

Closes gh-28127
This commit is contained in:
Andy Wilkinson
2021-09-24 10:10:15 +01:00
parent ab95c2fa3b
commit 2d2cbff504
2 changed files with 26 additions and 11 deletions

View File

@@ -646,17 +646,7 @@ public final class DataSourceBuilder<T extends DataSource> {
add(DataSourceProperty.DRIVER_CLASS_NAME, PoolDataSource::getConnectionFactoryClassName,
PoolDataSource::setConnectionFactoryClassName);
add(DataSourceProperty.USERNAME, PoolDataSource::getUser, PoolDataSource::setUser);
add(DataSourceProperty.PASSWORD, passwordGetter(), PoolDataSource::setPassword);
}
@SuppressWarnings("deprecation")
static Getter<PoolDataSource, String> passwordGetter() {
try {
return (dataSource) -> dataSource.getPassword();
}
catch (NoSuchMethodError ex) {
return null;
}
add(DataSourceProperty.PASSWORD, null, PoolDataSource::setPassword);
}
}

View File

@@ -30,6 +30,7 @@ import com.microsoft.sqlserver.jdbc.SQLServerDataSource;
import com.zaxxer.hikari.HikariDataSource;
import oracle.jdbc.internal.OpaqueString;
import oracle.jdbc.pool.OracleDataSource;
import oracle.ucp.jdbc.PoolDataSource;
import oracle.ucp.jdbc.PoolDataSourceImpl;
import org.apache.commons.dbcp2.BasicDataSource;
import org.h2.Driver;
@@ -293,6 +294,16 @@ class DataSourceBuilderTests {
.isThrownBy(() -> DataSourceBuilder.derivedFrom(dataSource).url("example.org").build());
}
@Test
void buildWhenDerivedFromOracleUcpWithPasswordNotSetThrowsException() throws Exception {
PoolDataSource dataSource = new PoolDataSourceImpl();
dataSource.setUser("test");
dataSource.setPassword("secret");
dataSource.setURL("example.com");
assertThatExceptionOfType(UnsupportedDataSourcePropertyException.class)
.isThrownBy(() -> DataSourceBuilder.derivedFrom(dataSource).url("example.org").build());
}
@Test
void buildWhenDerivedFromOracleDataSourceWithPasswordSetReturnsDataSource() throws Exception {
oracle.jdbc.datasource.impl.OracleDataSource dataSource = new oracle.jdbc.datasource.impl.OracleDataSource();
@@ -308,6 +319,20 @@ class DataSourceBuilderTests {
assertThat(built.getURL()).isEqualTo("example.com");
}
@Test
void buildWhenDerivedFromOracleUcpWithPasswordSetReturnsDataSource() throws SQLException {
PoolDataSource dataSource = new PoolDataSourceImpl();
dataSource.setUser("test");
dataSource.setPassword("secret");
dataSource.setURL("example.com");
DataSourceBuilder<?> builder = DataSourceBuilder.derivedFrom(dataSource);
PoolDataSource built = (PoolDataSource) builder.username("test2").password("secret2").build();
assertThat(built.getUser()).isEqualTo("test2");
assertThat(built).extracting("password").extracting((opaque) -> ((oracle.ucp.util.OpaqueString) opaque).get())
.isEqualTo("secret2");
assertThat(built.getURL()).isEqualTo("example.com");
}
@Test
void buildWhenDerivedFromEmbeddedDatabase() {
EmbeddedDatabase database = new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.HSQL).build();