Spring boot fails to start when using UCP and Spring Boot 3.1.5 with JndiPropertySource enabled.
This happens because UCP exposes a property SSLConext of type javax.net.ssl.SSLContext. The constructor for SSLContext has a parameter of type java.security.Provider. This Provider class implements Map and is therefore treated by Spring Boot as a Map, an attempt will be made to create a Map using CollectionFactory which will cause the error because java.security.Provider does not expose a constructor with no parameters.
The following workarounds are possible :
- if JndiPropertySource is not being used, disable it by setting the following property in the spring.properties file:
spring.jndi.ignore=true - create the data source programatically.
This is the error when deploying the WAR on a Tomcat server:
23-Nov-2023 15:23:37.329 SEVERE [RMI TCP Connection(2)-127.0.0.1] org.apache.tomcat.util.modeler.BaseModelMBean.invoke Exception invoking method [createStandardContext]
javax.management.RuntimeOperationsException: Exception invoking method [manageApp]
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:304)
at java.management/com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:803)
at java.management/com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:802)
at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:422)
at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:376)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:294)
at java.management/com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:803)
at java.management/com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:802)
at java.management/com.sun.jmx.remote.security.MBeanServerAccessController.invoke(MBeanServerAccessController.java:472)
at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1472)
at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1310)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:714)
at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1412)
at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:360)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:714)
at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:598)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:844)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:721)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:720)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: java.lang.IllegalStateException: Error starting child
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:686)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:658)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:712)
at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1824)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:294)
... 30 more
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/my_todo_list_war_exploded]]
at org.apache.catalina.util.LifecycleBase.handleSubClassException(LifecycleBase.java:419)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:186)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:683)
... 36 more
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataSourceScriptDatabaseInitializer' defined in class path resource [org/springframework/boot/autoconfigure/sql/init/DataSourceInitializationConfiguration.class]: Unsatisfied dependency expressed through method 'dataSourceScriptDatabaseInitializer' parameter 0: Error creating bean with name 'dataSource': Could not bind properties to 'PoolDataSourceImpl' : prefix=spring.datasource.oracleucp, ignoreInvalidFields=false, ignoreUnknownFields=true
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:801)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:545)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1332)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1162)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:560)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:312)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1166)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:940)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:616)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:738)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:440)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:174)
at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:154)
at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:96)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:171)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4850)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171)
... 37 more
Caused by: org.springframework.boot.context.properties.ConfigurationPropertiesBindException: Error creating bean with name 'dataSource': Could not bind properties to 'PoolDataSourceImpl' : prefix=spring.datasource.oracleucp, ignoreInvalidFields=false, ignoreUnknownFields=true
at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.bind(ConfigurationPropertiesBindingPostProcessor.java:99)
at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization(ConfigurationPropertiesBindingPostProcessor.java:79)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:419)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1762)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:598)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1417)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1337)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:910)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:788)
... 61 more
Caused by: org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'spring.datasource.oracleucp.s-s-l-context.provider' to java.security.Provider
at org.springframework.boot.context.properties.bind.Binder.handleBindError(Binder.java:392)
at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:352)
at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$4(Binder.java:478)
at org.springframework.boot.context.properties.bind.ValueObjectBinder$ConstructorParameter.bind(ValueObjectBinder.java:318)
at org.springframework.boot.context.properties.bind.ValueObjectBinder.bind(ValueObjectBinder.java:76)
at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$5(Binder.java:482)
at org.springframework.boot.context.properties.bind.Binder$Context.withIncreasedDepth(Binder.java:596)
at org.springframework.boot.context.properties.bind.Binder$Context.withDataObject(Binder.java:582)
at org.springframework.boot.context.properties.bind.Binder.bindDataObject(Binder.java:480)
at org.springframework.boot.context.properties.bind.Binder.bindObject(Binder.java:419)
at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:348)
at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$4(Binder.java:478)
at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:99)
at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:87)
at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:63)
at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$5(Binder.java:482)
at org.springframework.boot.context.properties.bind.Binder$Context.withIncreasedDepth(Binder.java:596)
at org.springframework.boot.context.properties.bind.Binder$Context.withDataObject(Binder.java:582)
at org.springframework.boot.context.properties.bind.Binder.bindDataObject(Binder.java:480)
at org.springframework.boot.context.properties.bind.Binder.bindObject(Binder.java:419)
at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:348)
at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:337)
at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:267)
at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:254)
at org.springframework.boot.context.properties.ConfigurationPropertiesBinder.bind(ConfigurationPropertiesBinder.java:94)
at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.bind(ConfigurationPropertiesBindingPostProcessor.java:96)
... 75 more
Caused by: java.lang.IllegalArgumentException: Could not instantiate Map type: java.security.Provider
at org.springframework.core.CollectionFactory.createMap(CollectionFactory.java:327)
at org.springframework.core.CollectionFactory.createMap(CollectionFactory.java:273)
at org.springframework.boot.context.properties.bind.MapBinder.bindAggregate(MapBinder.java:57)
at org.springframework.boot.context.properties.bind.AggregateBinder.bind(AggregateBinder.java:56)
at org.springframework.boot.context.properties.bind.Binder.lambda$bindAggregate$3(Binder.java:443)
at org.springframework.boot.context.properties.bind.Binder$Context.withIncreasedDepth(Binder.java:596)
at org.springframework.boot.context.properties.bind.Binder.bindAggregate(Binder.java:443)
at org.springframework.boot.context.properties.bind.Binder.bindObject(Binder.java:404)
at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:348)
... 99 more
Caused by: java.lang.NoSuchMethodException: java.security.Provider.<init>()
at java.base/java.lang.Class.getConstructor0(Class.java:3761)
at java.base/java.lang.Class.getDeclaredConstructor(Class.java:2930)
at org.springframework.util.ReflectionUtils.accessibleConstructor(ReflectionUtils.java:185)
at org.springframework.core.CollectionFactory.createMap(CollectionFactory.java:324)
... 107 more
Comment From: wilkinsona
Thanks for the report.
The problem's occurring because JndiPropertySource is not enumerable. It can be reproduced by adding this test to OracleUcpDataSourceConfigurationTests:
@Test
void testDataSourceExistsWithNonEnumerablePropertySource() {
this.contextRunner.withInitializer((context) -> {
context.getEnvironment().getPropertySources().addFirst(new PropertySource<String>("name") {
@Override
public Object getProperty(String name) {
return null;
}
});
}).run((context) -> {
assertThat(context.getBeansOfType(DataSource.class)).hasSize(1);
assertThat(context.getBeansOfType(PoolDataSourceImpl.class)).hasSize(1);
try (Connection connection = context.getBean(DataSource.class).getConnection()) {
assertThat(connection.isValid(1000)).isTrue();
}
});
}
As far as I can tell, we've already addressed this in 3.2.0 through the changes made for https://github.com/spring-projects/spring-boot/issues/38201, although it's something of an unintended side-effect. We may want to back port that change to 3.1.x or consider a different fix.
@fmeheust can you please try 3.2.0 (released earlier today) and let us know if it fixes the problem?
Comment From: fmeheust
@wilkinsona I can't find 3.2.0 in maven central, where can I get it ?
Comment From: wilkinsona
It's in Maven Central. See https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot/3.2.0/, for example. Note that sites like https://search.maven.org/ take some time to catch up to new releases and as such aren't a great source of up-to-date information.
Comment From: fmeheust
@wilkinsona I confirm that my application starts correctly on spring boot 3.2.0. Thank you
Comment From: wilkinsona
Thanks, @fmeheust.
Comment From: philwebb
We discussed this today and feel that backporting #38201 is a bit risky. We're going to recommend that folks with this issue upgrade to 3.2.x.