You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When creating an initialization-specific DataSource, Flyway, Liquibase and our script-based auto-configuration all incorrectly assume that the primary DataSource will always have been derived from DataSourceProperties
#25643
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
If a user defines their own DataSource bean and configures flyway.user, FlywayAutoConfiguration will create a DataSource that doesn't work or that points to a different database. For example, with HSQLDB on the classpath, imagine that the user configures their own DataSource bean:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.4.3)
2021-03-15 10:45:16.814 INFO 66071 --- [ main] hManuallyConfiguredDatasourceApplication : Starting FlywayWithManuallyConfiguredDatasourceApplication using Java 1.8.0_282 on wilkinsona-a01.vmware.com with PID 66071 (/Users/awilkinson/dev/workspaces/spring-projects/spring-boot/master/flyway-with-manually-configured-datasource/target/classes started by awilkinson in /Users/awilkinson/dev/workspaces/spring-projects/spring-boot/master/flyway-with-manually-configured-datasource)
2021-03-15 10:45:16.816 INFO 66071 --- [ main] hManuallyConfiguredDatasourceApplication : No active profile set, falling back to default profiles: default
2021-03-15 10:45:17.363 WARN 66071 --- [ main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Unsatisfied dependency expressed through method 'flywayInitializer' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flyway' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.flywaydb.core.Flyway]: Factory method 'flyway' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Failed to determine suitable jdbc url
2021-03-15 10:45:17.374 INFO 66071 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-03-15 10:45:17.388 ERROR 66071 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine suitable jdbc url
Action:
Consider the following:
If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).
The failure analysis hasn't helped very much here as it has hidden the fact that the failure is occurring when trying to configure Flyway. Running with --debug reveals the point at which the failure occurs:
2021-03-15 10:48:17.294 DEBUG 66817 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter : Application failed to start due to an exception
org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Failed to determine suitable jdbc url
at org.springframework.boot.autoconfigure.jdbc.DataSourceProperties.determineUrl(DataSourceProperties.java:280) ~[spring-boot-autoconfigure-2.4.3.jar:2.4.3]
at org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration$FlywayConfiguration.getProperty(FlywayAutoConfiguration.java:294) ~[spring-boot-autoconfigure-2.4.3.jar:2.4.3]
at org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration$FlywayConfiguration.configureDataSource(FlywayAutoConfiguration.java:149) ~[spring-boot-autoconfigure-2.4.3.jar:2.4.3]
at org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration$FlywayConfiguration.flyway(FlywayAutoConfiguration.java:133) ~[spring-boot-autoconfigure-2.4.3.jar:2.4.3]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_282]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_282]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_282]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_282]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.3.4.jar:5.3.4]
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653) ~[spring-beans-5.3.4.jar:5.3.4]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:638) ~[spring-beans-5.3.4.jar:5.3.4]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1334) ~[spring-beans-5.3.4.jar:5.3.4]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) ~[spring-beans-5.3.4.jar:5.3.4]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564) ~[spring-beans-5.3.4.jar:5.3.4]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.4.jar:5.3.4]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.4.jar:5.3.4]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.4.jar:5.3.4]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.4.jar:5.3.4]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.4.jar:5.3.4]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.3.4.jar:5.3.4]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1380) ~[spring-beans-5.3.4.jar:5.3.4]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300) ~[spring-beans-5.3.4.jar:5.3.4]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) ~[spring-beans-5.3.4.jar:5.3.4]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~[spring-beans-5.3.4.jar:5.3.4]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:541) ~[spring-beans-5.3.4.jar:5.3.4]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1334) ~[spring-beans-5.3.4.jar:5.3.4]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) ~[spring-beans-5.3.4.jar:5.3.4]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564) ~[spring-beans-5.3.4.jar:5.3.4]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.4.jar:5.3.4]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.4.jar:5.3.4]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.4.jar:5.3.4]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.4.jar:5.3.4]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.4.jar:5.3.4]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322) ~[spring-beans-5.3.4.jar:5.3.4]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.4.jar:5.3.4]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944) ~[spring-beans-5.3.4.jar:5.3.4]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:917) ~[spring-context-5.3.4.jar:5.3.4]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:582) ~[spring-context-5.3.4.jar:5.3.4]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:767) [spring-boot-2.4.3.jar:2.4.3]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) [spring-boot-2.4.3.jar:2.4.3]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:426) [spring-boot-2.4.3.jar:2.4.3]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:326) [spring-boot-2.4.3.jar:2.4.3]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1311) [spring-boot-2.4.3.jar:2.4.3]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1300) [spring-boot-2.4.3.jar:2.4.3]
at com.example.demo.FlywayWithManuallyConfiguredDatasourceApplication.main(FlywayWithManuallyConfiguredDatasourceApplication.java:17) [classes/:na]
2021-03-15 10:48:17.294 ERROR 66817 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine suitable jdbc url
Action:
Consider the following:
If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).
I think we need to decouple Flyway's auto-configuration from DataSourceProperties. Ideally, we'd derive the configuration of the Flyway-specific DataSource from the metadata of the primary DataSource. If that's not possible then we'll need to provide a new type that encapsulates everything we need to create the Flyway-specific DataSource. Users would then need to define a bean that is an instance of this type for Flyway auto-configuration to work with Flyway-specific credentials.
The text was updated successfully, but these errors were encountered:
wilkinsona
changed the title
When creating a Flyway-specific DataSource, FlywayAutoConfiguration incorrectly assumes that the primary DataSource was derived from DataSourceProperties
When creating a Flyway-specific DataSource, FlywayAutoConfiguration incorrectly assumes that the primary DataSource will always have been derived from DataSourceProperties
Mar 15, 2021
wilkinsona
changed the title
When creating a Flyway-specific DataSource, FlywayAutoConfiguration incorrectly assumes that the primary DataSource will always have been derived from DataSourceProperties
When creating an initialization-specific DataSource, Flyway, Liquibase and our script-based auto-configuration all incorrectly assume that the primary DataSource will always have been derived from DataSourceProperties
Mar 15, 2021
Refactor `DataSourceBuilder` to use direct property mappers rather than
the `Binder` and aliases. Supported DataSource types now include two-way
mappers which allows us to both get and set properties in a uniform way.
A new `derivedFrom` factory method has been added which allows a new
`DataSource` to be derived from an existing one. This update is
primarily to allow Flyway and Liquibase migrations to work against a
`@Bean` configured DataSource rather than assuming that the primary
DataSource was always created via auto-configuration.
See gh-25643
Uh oh!
There was an error while loading. Please reload this page.
If a user defines their own
DataSource
bean and configuresflyway.user
,FlywayAutoConfiguration
will create aDataSource
that doesn't work or that points to a different database. For example, with HSQLDB on the classpath, imagine that the user configures their ownDataSource
bean:And also configures some custom credentials for Flyway to use:
When the application starts, Flyway will migrate a different in-memory database:
Alternatively, if HSQLDB is swapped for an external database such as Postgres:
The application will fail to start:
The failure analysis hasn't helped very much here as it has hidden the fact that the failure is occurring when trying to configure Flyway. Running with
--debug
reveals the point at which the failure occurs:I think we need to decouple Flyway's auto-configuration from
DataSourceProperties
. Ideally, we'd derive the configuration of the Flyway-specificDataSource
from the metadata of the primaryDataSource
. If that's not possible then we'll need to provide a new type that encapsulates everything we need to create the Flyway-specificDataSource
. Users would then need to define a bean that is an instance of this type for Flyway auto-configuration to work with Flyway-specific credentials.The text was updated successfully, but these errors were encountered: