javaspringspring-bootconnection-poolingc3p0

Unable to find suitable method for property URL? ComboPooledDataSource, Spring Boot DataSourceBuilder 2.7.0


I am upgrading to spring boot 2.7.0 from 2.3.12.RELEASE as that has vulnerabilities. My application uses c3p0 for connection pooling and I need to keep using that.

Caused by: org.springframework.boot.jdbc.UnsupportedDataSourcePropertyException: Unable to find suitable method for url
    at org.springframework.boot.jdbc.UnsupportedDataSourcePropertyException.throwIf(UnsupportedDataSourcePropertyException.java:36) ~[spring-boot-2.7.0.jar:2.7.0]
    at org.springframework.boot.jdbc.DataSourceBuilder$ReflectionDataSourceProperties.getMethod(DataSourceBuilder.java:560) ~[spring-boot-2.7.0.jar:2.7.0]
    at org.springframework.boot.jdbc.DataSourceBuilder$ReflectionDataSourceProperties.set(DataSourceBuilder.java:542) ~[spring-boot-2.7.0.jar:2.7.0]
    at org.springframework.boot.jdbc.DataSourceBuilder.build(DataSourceBuilder.java:181) ~[spring-boot-2.7.0.jar:2.7.0]
    at com.informatica.cloud.service.admin.config.PersistenceConfig.dataSource(PersistenceConfig.java:21) ~[main/:?]
    at com.informatica.cloud.service.admin.config.PersistenceConfig$$EnhancerBySpringCGLIB$$6bae0fe3.CGLIB$dataSource$0(<generated>) ~[main/:?]
    at com.informatica.cloud.service.admin.config.PersistenceConfig$$EnhancerBySpringCGLIB$$6bae0fe3$$FastClassBySpringCGLIB$$4ab5ae17.invoke(<generated>) ~[main/:?]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.3.21.jar:5.3.21]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331) ~[spring-context-5.3.21.jar:5.3.21]
    at com.informatica.cloud.service.admin.config.PersistenceConfig$$EnhancerBySpringCGLIB$$6bae0fe3.dataSource(<generated>) ~[main/:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_332]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_332]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_332]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_332]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.3.21.jar:5.3.21]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653) ~[spring-beans-5.3.21.jar:5.3.21]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:638) ~[spring-beans-5.3.21.jar:5.3.21]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352) ~[spring-beans-5.3.21.jar:5.3.21]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195) ~[spring-beans-5.3.21.jar:5.3.21]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans-5.3.21.jar:5.3.21]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.21.jar:5.3.21]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.21.jar:5.3.21]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.21.jar:5.3.21]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.21.jar:5.3.21]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.21.jar:5.3.21]
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.3.21.jar:5.3.21]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1391) ~[spring-beans-5.3.21.jar:5.3.21]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311) ~[spring-beans-5.3.21.jar:5.3.21]
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) ~[spring-beans-5.3.21.jar:5.3.21]
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~[spring-beans-5.3.21.jar:5.3.21]

Property: spring.datasource.type=com.mchange.v2.c3p0.ComboPooledDataSource

The thing that breaks this is the change in DataSourceBuilder in spring boot 2.5.x or higher.

DataSourceBuilder:

private enum DataSourceProperty {

        URL(false, "url", "URL"),

DataSourceBuilder will look for setUrl or setURL in the ComboPooledDataSource class and that class has setJdbcUrl method, hence the exception.

Any suggestions to not create dataSource bean manually and use auto configuration without breaking the code?

Edit: application.properties

spring.datasource.url=jdbc:mysql://db-url:3307/service
spring.datasource.username=user
spring.datasource.password=pass

spring.datasource.type=com.mchange.v2.c3p0.ComboPooledDataSource
spring.datasource.pool.driverClass=com.mysql.cj.jdbc.Driver

Solution

  • It's indeed what our documentation states but we used to support C3P0 before. I've created https://github.com/spring-projects/spring-boot/issues/31920 to restore the support.