Only attempt unwrapping of interfaces

Wrapper's isWrapperFor and unwrap methods both take a Class<?> target
but document that the target should be an interface. Prior to this
change, we were calling isWrapperFor with any Class<?> irrespective of
whether or not it was an interface. When using Oracle UCP each call
to isWrapperFor with an interface results in an exception stack trace
being logged.

This commit upates DataSourceUnwrapper to adhere to Wrapper's contract
by only calling isWrapperFor and unwrap with interfaces.

Fixes gh-24154
pull/24264/head
Andy Wilkinson 4 years ago
parent 46c9a4fbc7
commit 988526bee9

@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -74,7 +74,7 @@ public final class DataSourceUnwrapper {
private static <S> S safeUnwrap(Wrapper wrapper, Class<S> target) {
try {
if (wrapper.isWrapperFor(target)) {
if (target.isInterface() && wrapper.isWrapperFor(target)) {
return wrapper.unwrap(target);
}
}

@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,6 +17,7 @@
package org.springframework.boot.jdbc;
import java.sql.SQLException;
import java.util.function.Consumer;
import javax.sql.DataSource;
@ -87,12 +88,18 @@ class DataSourceUnwrapperTests {
assertThat(DataSourceUnwrapper.unwrap(actual, DataSourceProxy.class)).isSameAs(dataSource);
}
@Test
void unwrappingIsNotAttemptedWhenTargetIsNotAnInterface() throws SQLException {
DataSource dataSource = mock(DataSource.class);
assertThat(DataSourceUnwrapper.unwrap(dataSource, HikariDataSource.class)).isNull();
verifyNoMoreInteractions(dataSource);
}
@Test
void unwrappingIsNotAttemptedWhenDataSourceIsNotWrapperForTarget() throws SQLException {
DataSource dataSource = mock(DataSource.class);
DataSource actual = DataSourceUnwrapper.unwrap(dataSource, HikariDataSource.class);
assertThat(actual).isNull();
verify(dataSource).isWrapperFor(HikariDataSource.class);
assertThat(DataSourceUnwrapper.unwrap(dataSource, Consumer.class)).isNull();
verify(dataSource).isWrapperFor(Consumer.class);
verifyNoMoreInteractions(dataSource);
}

Loading…
Cancel
Save