From 988526bee92b1d29e8dcb0fd5820b4bfe09133b4 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 18 Nov 2020 11:35:11 +0000 Subject: [PATCH] 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 --- .../boot/jdbc/DataSourceUnwrapper.java | 4 ++-- .../boot/jdbc/DataSourceUnwrapperTests.java | 15 +++++++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DataSourceUnwrapper.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DataSourceUnwrapper.java index 7ddd99b2a4e0..133a73181ec8 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DataSourceUnwrapper.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DataSourceUnwrapper.java @@ -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 static T unwrap(DataSource dataSource, Class target) { private static S safeUnwrap(Wrapper wrapper, Class target) { try { - if (wrapper.isWrapperFor(target)) { + if (target.isInterface() && wrapper.isWrapperFor(target)) { return wrapper.unwrap(target); } } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/DataSourceUnwrapperTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/DataSourceUnwrapperTests.java index 75abb0b4f960..318a88c4aac8 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/DataSourceUnwrapperTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/jdbc/DataSourceUnwrapperTests.java @@ -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 @@ void unwrapDataSourceProxy() { 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); }