Spring Boot gets exception when using oracle ucp datasource and actuator.
This is because that "isWrapperFor" call specifically throws an exception if the class it's checking is not an interface. The HikariDataSource.class class is not an interface, so it explodes.
I am on spring boot 2.3.3.RELEASE, and using version 12.1.0.2.0 of oracle UCP, and it looks like the DataSourceUnwrapper for a hikaridatasource causes the following exception to be thrown when the underlying datasource is an oracle ucp datasource.
java.sql.SQLException: The argument is not an interface
at oracle.ucp.util.UCPErrorHandler.newSQLException(UCPErrorHandler.java:479) ~[com.oracle.ucp-12.1.0.2.0.jar:12.1.0.2.0]
at oracle.ucp.util.UCPErrorHandler.throwSQLException(UCPErrorHandler.java:154) ~[com.oracle.ucp-12.1.0.2.0.jar:12.1.0.2.0]
at oracle.ucp.jdbc.PoolDataSourceImpl.isWrapperFor(PoolDataSourceImpl.java:3237) ~[com.oracle.ucp-12.1.0.2.0.jar:12.1.0.2.0]
at org.springframework.boot.jdbc.DataSourceUnwrapper.safeUnwrap(DataSourceUnwrapper.java:77) ~[spring-boot-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.boot.jdbc.DataSourceUnwrapper.unwrap(DataSourceUnwrapper.java:56) ~[spring-boot-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.boot.autoconfigure.jdbc.metadata.DataSourcePoolMetadataProvidersConfiguration$HikariPoolDataSourceMetadataProviderConfiguration.lambda$hikariPoolDataSourceMetadataProvider$0(DataSourcePoolMetadataProvidersConfiguration.java:66) ~[spring-boot-autoconfigure-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.boot.jdbc.metadata.CompositeDataSourcePoolMetadataProvider.getDataSourcePoolMetadata(CompositeDataSourcePoolMetadataProvider.java:50) ~[spring-boot-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.boot.actuate.metrics.jdbc.DataSourcePoolMetrics$CachingDataSourcePoolMetadataProvider.getDataSourcePoolMetadata(DataSourcePoolMetrics.java:113) ~[spring-boot-actuator-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.boot.actuate.metrics.jdbc.DataSourcePoolMetrics.bindTo(DataSourcePoolMetrics.java:68) ~[spring-boot-actuator-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.boot.actuate.autoconfigure.metrics.jdbc.DataSourcePoolMetricsAutoConfiguration$DataSourcePoolMetadataMetricsConfiguration.bindDataSourceToRegistry(DataSourcePoolMetricsAutoConfiguration.java:82) ~[spring-boot-actuator-autoconfigure-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.boot.actuate.autoconfigure.metrics.jdbc.DataSourcePoolMetricsAutoConfiguration$DataSourcePoolMetadataMetricsConfiguration.lambda$bindDataSourcesToRegistry$0(DataSourcePoolMetricsAutoConfiguration.java:75) ~[spring-boot-actuator-autoconfigure-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684) ~[?:1.8.0_121]
at org.springframework.boot.actuate.autoconfigure.metrics.jdbc.DataSourcePoolMetricsAutoConfiguration$DataSourcePoolMetadataMetricsConfiguration.bindDataSourcesToRegistry(DataSourcePoolMetricsAutoConfiguration.java:74) ~[spring-boot-actuator-autoconfigure-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_121]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_121]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_121]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_121]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:755) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:130) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1420) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:897) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:879) ~[spring-context-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551) ~[spring-context-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143) ~[spring-boot-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758) ~[spring-boot-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750) ~[spring-boot-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.3.3.RELEASE.jar:2.3.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-2.3.3.RELEASE.jar:2.3.3.RELEASE]
Comment From: wilkinsona
Thanks for the report. safeUnwrap
should catch and swallow any exception thrown by isWrapperFor(Class<?>)
:
https://github.com/spring-projects/spring-boot/blob/602e62998eb2254517d695fa67246399ba40b8bf/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DataSourceUnwrapper.java#L76-L83
It's not clear to me at the moment where you're seeing the exception. Is this a purely cosmetic problem as it's appearing in the logs or is it have an unwanted effect on functionality?
Comment From: nwertzberger
You know what? it is cosmetic... Sorry!
Comment From: wilkinsona
Thanks for the clarification. It may still be worth fixing even if it's only cosmetic. We'd need to be careful that we don't break anything with other wrappers that are less strict about the interface requirement.