Hi Team, could anyone please look into this and let me know the workaround for the issue? or if there is a fix planned for this one. Spring Boot Version: 3.0.1 Sample GitHub Repo:- https://github.com/mishraomp/spring-reactive On JVM mode the app starts fine but in native mode it throws exception during startup. I have pasted the log outputs for the same.
JVM mode
2023-01-04T14:59:14.678-08:00 INFO 20988 --- [ main] com.om.example.SbReactiveApplication : Starting SbReactiveApplication using Java 17 with PID 20988 (C:\projects\personal\spring-reactive\target\classes started by ompra in C:\projects\personal\spring-reactive)
2023-01-04T14:59:14.681-08:00 INFO 20988 --- [ main] com.om.example.SbReactiveApplication : No active profile set, falling back to 1 default profile: "default"
2023-01-04T14:59:15.231-08:00 INFO 20988 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data R2DBC repositories in DEFAULT mode.
2023-01-04T14:59:15.331-08:00 INFO 20988 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 96 ms. Found 1 R2DBC repository interfaces.
2023-01-04T14:59:16.958-08:00 INFO 20988 --- [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 14 endpoint(s) beneath base path ''
2023-01-04T14:59:17.189-08:00 INFO 20988 --- [ main] o.f.c.internal.license.VersionPrinter : Flyway Community Edition 9.5.1 by Redgate
2023-01-04T14:59:17.189-08:00 INFO 20988 --- [ main] o.f.c.internal.license.VersionPrinter : See what's new here: https://flywaydb.org/documentation/learnmore/releaseNotes#9.5.1
2023-01-04T14:59:17.190-08:00 INFO 20988 --- [ main] o.f.c.internal.license.VersionPrinter :
2023-01-04T14:59:17.468-08:00 INFO 20988 --- [ main] o.f.c.i.database.base.BaseDatabaseType : Database: jdbc:postgresql://localhost:5432/default (PostgreSQL 15.1)
2023-01-04T14:59:17.518-08:00 INFO 20988 --- [ main] o.f.core.internal.command.DbValidate : Successfully validated 1 migration (execution time 00:00.020s)
2023-01-04T14:59:17.547-08:00 INFO 20988 --- [ main] o.f.c.i.s.JdbcTableSchemaHistory : Creating Schema History table "public"."flyway_schema_history" ...
2023-01-04T14:59:17.645-08:00 INFO 20988 --- [ main] o.f.core.internal.command.DbMigrate : Current version of schema "public": << Empty Schema >>
2023-01-04T14:59:17.659-08:00 INFO 20988 --- [ main] o.f.core.internal.command.DbMigrate : Migrating schema "public" to version "1.0.0 - API"
2023-01-04T14:59:17.711-08:00 INFO 20988 --- [ main] o.f.core.internal.command.DbMigrate : Successfully applied 1 migration to schema "public", now at version v1.0.0 (execution time 00:00.079s)
2023-01-04T14:59:18.023-08:00 INFO 20988 --- [ main] o.s.b.web.embedded.netty.NettyWebServer : Netty started on port 3000
2023-01-04T14:59:18.043-08:00 INFO 20988 --- [ main] com.om.example.SbReactiveApplication : Started SbReactiveApplication in 3.78 seconds (process running for 4.213)
Native Mode
2023-01-04 14:54:47 :: Spring Boot :: (v3.0.1)
2023-01-04 14:54:47
2023-01-04 14:54:47 2023-01-04T22:54:47.534Z INFO 1 --- [ main] com.om.example.SbReactiveApplication : Starting AOT-processed SbReactiveApplication using Java 17.0.5 with PID 1 (/workspace/com.om.example.SbReactiveApplication started by cnb in /workspace)
2023-01-04 14:54:47 2023-01-04T22:54:47.534Z INFO 1 --- [ main] com.om.example.SbReactiveApplication : No active profile set, falling back to 1 default profile: "default"
2023-01-04 14:54:47 2023-01-04T22:54:47.637Z INFO 1 --- [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 14 endpoint(s) beneath base path ''
2023-01-04 14:54:47 2023-01-04T22:54:47.672Z WARN 1 --- [ main] .r.c.ReactiveWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flyway': Unexpected exception during bean creation
2023-01-04 14:54:47 2023-01-04T22:54:47.673Z ERROR 1 --- [ main] o.s.boot.SpringApplication : Application run failed
2023-01-04 14:54:47
2023-01-04 14:54:47 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flyway': Unexpected exception during bean creation
2023-01-04 14:54:47 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:534) ~[com.om.example.SbReactiveApplication:6.0.3]
2023-01-04 14:54:47 at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[com.om.example.SbReactiveApplication:6.0.3]
2023-01-04 14:54:47 at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[com.om.example.SbReactiveApplication:6.0.3]
2023-01-04 14:54:47 at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[com.om.example.SbReactiveApplication:6.0.3]
2023-01-04 14:54:47 at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[com.om.example.SbReactiveApplication:6.0.3]
2023-01-04 14:54:47 at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:961) ~[com.om.example.SbReactiveApplication:6.0.3]
2023-01-04 14:54:47 at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:915) ~[com.om.example.SbReactiveApplication:6.0.3]
2023-01-04 14:54:47 at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:584) ~[com.om.example.SbReactiveApplication:6.0.3]
2023-01-04 14:54:47 at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext.java:66) ~[com.om.example.SbReactiveApplication:3.0.1]
2023-01-04 14:54:47 at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730) ~[com.om.example.SbReactiveApplication:3.0.1]
2023-01-04 14:54:47 at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432) ~[com.om.example.SbReactiveApplication:3.0.1]
2023-01-04 14:54:47 at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[com.om.example.SbReactiveApplication:3.0.1]
2023-01-04 14:54:47 at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302) ~[com.om.example.SbReactiveApplication:3.0.1]
2023-01-04 14:54:47 at org.springframework.boot.SpringApplication.run(SpringApplication.java:1291) ~[com.om.example.SbReactiveApplication:3.0.1]
2023-01-04 14:54:47 at com.om.example.SbReactiveApplication.main(SbReactiveApplication.java:21) ~[com.om.example.SbReactiveApplication:na]
2023-01-04 14:54:47 Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.jdbc.datasource.SimpleDriverDataSource]: No default constructor found
2023-01-04 14:54:47 at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:146) ~[na:na]
2023-01-04 14:54:47 at org.springframework.boot.jdbc.DataSourceBuilder.build(DataSourceBuilder.java:175) ~[com.om.example.SbReactiveApplication:3.0.1]
2023-01-04 14:54:47 at org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration$FlywayConfiguration.getMigrationDataSource(FlywayAutoConfiguration.java:162) ~[com.om.example.SbReactiveApplication:na]
2023-01-04 14:54:47 at org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration$FlywayConfiguration.configureDataSource(FlywayAutoConfiguration.java:149) ~[com.om.example.SbReactiveApplication:na]
2023-01-04 14:54:47 at org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration$FlywayConfiguration.flyway(FlywayAutoConfiguration.java:138) ~[com.om.example.SbReactiveApplication:na]
2023-01-04 14:54:47 at org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration__BeanDefinitions$FlywayConfiguration__BeanDefinitions.lambda$getFlywayInstanceSupplier$0(FlywayAutoConfiguration__BeanDefinitions.java:99) ~[na:na]
2023-01-04 14:54:47 at org.springframework.util.function.ThrowingBiFunction.apply(ThrowingBiFunction.java:68) ~[com.om.example.SbReactiveApplication:6.0.3]
2023-01-04 14:54:47 at org.springframework.util.function.ThrowingBiFunction.apply(ThrowingBiFunction.java:54) ~[com.om.example.SbReactiveApplication:6.0.3]
2023-01-04 14:54:47 at org.springframework.beans.factory.aot.BeanInstanceSupplier.lambda$get$2(BeanInstanceSupplier.java:208) ~[na:na]
2023-01-04 14:54:47 at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:59) ~[com.om.example.SbReactiveApplication:6.0.3]
2023-01-04 14:54:47 at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:47) ~[com.om.example.SbReactiveApplication:6.0.3]
2023-01-04 14:54:47 at org.springframework.beans.factory.aot.BeanInstanceSupplier.invokeBeanSupplier(BeanInstanceSupplier.java:220) ~[na:na]
2023-01-04 14:54:47 at org.springframework.beans.factory.aot.BeanInstanceSupplier.get(BeanInstanceSupplier.java:208) ~[na:na]
2023-01-04 14:54:47 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainInstanceFromSupplier(AbstractAutowireCapableBeanFactory.java:1225) ~[com.om.example.SbReactiveApplication:6.0.3]
2023-01-04 14:54:47 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1210) ~[com.om.example.SbReactiveApplication:6.0.3]
2023-01-04 14:54:47 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1157) ~[com.om.example.SbReactiveApplication:6.0.3]
2023-01-04 14:54:47 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:561) ~[com.om.example.SbReactiveApplication:6.0.3]
2023-01-04 14:54:47 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) ~[com.om.example.SbReactiveApplication:6.0.3]
2023-01-04 14:54:47 ... 14 common frames omitted
2023-01-04 14:54:47 Caused by: java.lang.NoSuchMethodException: org.springframework.jdbc.datasource.SimpleDriverDataSource.<init>()
2023-01-04 14:54:47 at java.base@17.0.5/java.lang.Class.getConstructor0(DynamicHub.java:3585) ~[com.om.example.SbReactiveApplication:na]
2023-01-04 14:54:47 at java.base@17.0.5/java.lang.Class.getDeclaredConstructor(DynamicHub.java:2754) ~[com.om.example.SbReactiveApplication:na]
2023-01-04 14:54:47 at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:141) ~[na:na]
2023-01-04 14:54:47 ... 31 common frames omitted
2023-01-04 14:54:47
Comment From: wilkinsona
Thanks for the report. We're missing some reflection hints that allow the Flyway-specific DataSource to be created. You can work around this by providing the necessary hints manually:
class DataSourceBuilderHints implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
hints.reflection().registerType(SimpleDriverDataSource.class, MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS);
}
}
This registrar can be imported using @ImportRuntimeHints on your SbReactiveApplication class:
@ImportRuntimeHints(DataSourceBuilderHints.class)
Comment From: mishraomp
Thank you so much @wilkinsona for the quick response, the app now works in native mode.
2023-01-05 09:32:46 :: Spring Boot :: (v3.0.1)
2023-01-05 09:32:46
2023-01-05 09:32:46 2023-01-05T17:32:46.735Z INFO 1 --- [ main] com.om.example.SbReactiveApplication : Starting AOT-processed SbReactiveApplication using Java 17.0.5 with PID 1 (/workspace/com.om.example.SbReactiveApplication started by cnb in /workspace)
2023-01-05 09:32:46 2023-01-05T17:32:46.735Z INFO 1 --- [ main] com.om.example.SbReactiveApplication : No active profile set, falling back to 1 default profile: "default"
2023-01-05 09:32:46 2023-01-05T17:32:46.809Z INFO 1 --- [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 14 endpoint(s) beneath base path ''
2023-01-05 09:32:46 2023-01-05T17:32:46.837Z INFO 1 --- [ main] o.f.c.internal.license.VersionPrinter : Flyway Community Edition 9.5.1 by Redgate
2023-01-05 09:32:46 2023-01-05T17:32:46.837Z INFO 1 --- [ main] o.f.c.internal.license.VersionPrinter : See what's new here: https://flywaydb.org/documentation/learnmore/releaseNotes#9.5.1
2023-01-05 09:32:46 2023-01-05T17:32:46.837Z INFO 1 --- [ main] o.f.c.internal.license.VersionPrinter :
2023-01-05 09:32:46 2023-01-05T17:32:46.837Z WARN 1 --- [ main] o.f.core.internal.util.FeatureDetector : Unable to scan location: /db/migration (unsupported protocol: resource)
2023-01-05 09:32:46 2023-01-05T17:32:46.837Z WARN 1 --- [ main] o.f.c.i.s.classpath.ClassPathScanner : Unable to scan location: /db/migration (unsupported protocol: resource)
2023-01-05 09:32:46 2023-01-05T17:32:46.850Z INFO 1 --- [ main] o.f.c.i.database.base.BaseDatabaseType : Database: jdbc:postgresql://sb-reactive-db:5432/default (PostgreSQL 15.1)
2023-01-05 09:32:46 2023-01-05T17:32:46.855Z INFO 1 --- [ main] o.f.core.internal.command.DbValidate : Successfully validated 1 migration (execution time 00:00.001s)
2023-01-05 09:32:46 2023-01-05T17:32:46.860Z INFO 1 --- [ main] o.f.c.i.s.JdbcTableSchemaHistory : Creating Schema History table "public"."flyway_schema_history" ...
2023-01-05 09:32:46 2023-01-05T17:32:46.896Z INFO 1 --- [ main] o.f.core.internal.command.DbMigrate : Current version of schema "public": << Empty Schema >>
2023-01-05 09:32:46 2023-01-05T17:32:46.897Z INFO 1 --- [ main] o.f.core.internal.command.DbMigrate : Migrating schema "public" to version "1.0.0 - API"
2023-01-05 09:32:46 2023-01-05T17:32:46.915Z INFO 1 --- [ main] o.f.core.internal.command.DbMigrate : Successfully applied 1 migration to schema "public", now at version v1.0.0 (execution time 00:00.020s)
2023-01-05 09:32:46 2023-01-05T17:32:46.917Z WARN 1 --- [ main] i.m.c.i.binder.jvm.JvmGcMetrics : GC notifications will not be available because MemoryPoolMXBeans are not provided by the JVM
2023-01-05 09:32:46 2023-01-05T17:32:46.924Z INFO 1 --- [ main] o.s.b.web.embedded.netty.NettyWebServer : Netty started on port 3000
2023-01-05 09:32:46 2023-01-05T17:32:46.925Z INFO 1 --- [ main] com.om.example.SbReactiveApplication : Started SbReactiveApplication in 0.204 seconds (process running for 0.208)
Comment From: wilkinsona
There are a couple of ways that we could fix this:
- Provide a hint for
SimpleDriverDataSourcewhen Flyway's in the picture - Update
DataSourceBuilderto provide a method that takes aSupplier<D extends DataSource>to avoid reflectively creating theDataSourceinstance.
The second option is a more general solution. This would benefit org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration, org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration.LiquibaseConfiguration, and org.springframework.boot.autoconfigure.sql.init.DataSourceInitializationConfiguration which all rely on reflection at the moment and I suspect will have a similar problem.
Comment From: wilkinsona
https://github.com/wilkinsona/spring-boot/tree/gh-33692 contains an implementation of the second option. There are a couple of further considerations that I would like to discuss with the team:
- Should we update the documentation to use the new method rather than
type(Class)? - Should we even go as far as deprecating the
type(Class)method?
Comment From: philwebb
Team discussion: 1) yes. 2) also yes
Comment From: wilkinsona
The failures in this comment are interesting in the context of DataSourceBuilder and reflection. The sample does this:
@Bean(name = "db1ServerDataSource")
@ConfigurationProperties("db1")
DataSource db1ServerDataSource() {
return DataSourceBuilder.create().build();
}
Hikari's on the classpath so DataSourceBuilder tries to use it. It then fails to reflectively create a HikariDataSource instance. With a reflection hint for this in place, it then fails to call setJdbcUrl during configuration property binding. This is due to the bean method's return type being DataSource so no hints are generated for binding to HikariDataSource. While related to this issue, I think a different solution will be needed so perhaps this should be handled as a separate issue or pair of issues?
Comment From: philwebb
I wonder if adding hints might be a safer and less invasive option at this point? It's slightly annoying that the onus is on the caller to add the supplier. Hints might also allow the example above to work unchanged.
Here's something I think might work https://github.com/philwebb/spring-boot/tree/gh-33692-2
Comment From: philwebb
We're going to go with the hints approach for now since it doesn't require any API changes. Longer term, we may well look into adding supplier support.