question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add native-image support for Flyway

See original GitHub issue

The Flyway smoke tests currently fail with GraalVM complaining about proxy generation, which could be related to @FlywayDataSource:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataSource': Unsatisfied dependency expressed through method 'dataSource' parameter 0: Error creating bean with name 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties': Proxy class defined by interfaces [interface org.springframework.beans.factory.annotation.Qualifier, interface org.springframework.core.annotation.SynthesizedAnnotation] not found. Generating proxy classes at runtime is not supported. Proxy classes need to be defined at image build time by specifying the list of interfaces that they implement. To define proxy classes use -H:DynamicProxyConfigurationFiles=<comma-separated-config-files> and -H:DynamicProxyConfigurationResources=<comma-separated-config-resources> options.
	at org.springframework.beans.factory.aot.BeanInstanceSupplier.resolveArgument(BeanInstanceSupplier.java:349) ~[na:na]
	at org.springframework.beans.factory.aot.BeanInstanceSupplier.resolveArguments(BeanInstanceSupplier.java:265) ~[na:na]
	at org.springframework.beans.factory.aot.BeanInstanceSupplier.get(BeanInstanceSupplier.java:208) ~[na:na]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainInstanceFromSupplier(AbstractAutowireCapableBeanFactory.java:1224) ~[flyway:6.0.0-SNAPSHOT]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1209) ~[flyway:6.0.0-SNAPSHOT]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1156) ~[flyway:6.0.0-SNAPSHOT]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:566) ~[flyway:6.0.0-SNAPSHOT]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:526) ~[flyway:6.0.0-SNAPSHOT]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[flyway:6.0.0-SNAPSHOT]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[flyway:6.0.0-SNAPSHOT]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[flyway:6.0.0-SNAPSHOT]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[flyway:6.0.0-SNAPSHOT]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:930) ~[flyway:6.0.0-SNAPSHOT]
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:926) ~[flyway:6.0.0-SNAPSHOT]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:592) ~[flyway:6.0.0-SNAPSHOT]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:731) ~[flyway:3.0.0-SNAPSHOT]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:430) ~[flyway:3.0.0-SNAPSHOT]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) ~[flyway:3.0.0-SNAPSHOT]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303) ~[flyway:3.0.0-SNAPSHOT]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292) ~[flyway:3.0.0-SNAPSHOT]
	at com.example.flyway.FlywayApplication.main(FlywayApplication.java:13) ~[flyway:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties': Proxy class defined by interfaces [interface org.springframework.beans.factory.annotation.Qualifier, interface org.springframework.core.annotation.SynthesizedAnnotation] not found. Generating proxy classes at runtime is not supported. Proxy classes need to be defined at image build time by specifying the list of interfaces that they implement. To define proxy classes use -H:DynamicProxyConfigurationFiles=<comma-separated-config-files> and -H:DynamicProxyConfigurationResources=<comma-separated-config-resources> options.
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:611) ~[flyway:6.0.0-SNAPSHOT]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:526) ~[flyway:6.0.0-SNAPSHOT]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[flyway:6.0.0-SNAPSHOT]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[flyway:6.0.0-SNAPSHOT]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[flyway:6.0.0-SNAPSHOT]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[flyway:6.0.0-SNAPSHOT]
	at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254) ~[flyway:6.0.0-SNAPSHOT]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1374) ~[flyway:6.0.0-SNAPSHOT]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1294) ~[flyway:6.0.0-SNAPSHOT]
	at org.springframework.beans.factory.aot.BeanInstanceSupplier.resolveArgument(BeanInstanceSupplier.java:332) ~[na:na]
	... 20 common frames omitted
Caused by: com.oracle.svm.core.jdk.UnsupportedFeatureError: Proxy class defined by interfaces [interface org.springframework.beans.factory.annotation.Qualifier, interface org.springframework.core.annotation.SynthesizedAnnotation] not found. Generating proxy classes at runtime is not supported. Proxy classes need to be defined at image build time by specifying the list of interfaces that they implement. To define proxy classes use -H:DynamicProxyConfigurationFiles=<comma-separated-config-files> and -H:DynamicProxyConfigurationResources=<comma-separated-config-resources> options.
	at com.oracle.svm.core.util.VMError.unsupportedFeature(VMError.java:89) ~[na:na]
	at com.oracle.svm.reflect.proxy.DynamicProxySupport.getProxyClass(DynamicProxySupport.java:158) ~[na:na]
	at java.lang.reflect.Proxy.getProxyConstructor(Proxy.java:48) ~[flyway:na]
	at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:1037) ~[flyway:na]
	at org.springframework.core.annotation.SynthesizedMergedAnnotationInvocationHandler.createProxy(SynthesizedMergedAnnotationInvocationHandler.java:305) ~[na:na]
	at org.springframework.core.annotation.TypeMappedAnnotation.createSynthesizedAnnotation(TypeMappedAnnotation.java:333) ~[na:na]
	at org.springframework.core.annotation.AbstractMergedAnnotation.synthesize(AbstractMergedAnnotation.java:210) ~[flyway:6.0.0-SNAPSHOT]
	at org.springframework.core.annotation.AbstractMergedAnnotation.synthesize(AbstractMergedAnnotation.java:200) ~[flyway:6.0.0-SNAPSHOT]
	at org.springframework.core.annotation.AnnotationUtils.getAnnotation(AnnotationUtils.java:227) ~[na:na]
	at org.springframework.core.annotation.AnnotationUtils.getAnnotation(AnnotationUtils.java:252) ~[na:na]
	at org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils.isQualifierMatch(BeanFactoryAnnotationUtils.java:182) ~[na:na]
	at org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils.qualifiedBeansOfType(BeanFactoryAnnotationUtils.java:68) ~[na:na]
	at org.springframework.boot.context.properties.ConversionServiceDeducer$ConverterBeans.beans(ConversionServiceDeducer.java:99) ~[na:na]
	at org.springframework.boot.context.properties.ConversionServiceDeducer$ConverterBeans.<init>(ConversionServiceDeducer.java:93) ~[na:na]
	at org.springframework.boot.context.properties.ConversionServiceDeducer.getConversionServices(ConversionServiceDeducer.java:65) ~[na:na]
	at org.springframework.boot.context.properties.ConversionServiceDeducer.getConversionServices(ConversionServiceDeducer.java:55) ~[na:na]
	at org.springframework.boot.context.properties.ConfigurationPropertiesBinder.getConversionServices(ConfigurationPropertiesBinder.java:183) ~[flyway:na]
	at org.springframework.boot.context.properties.ConfigurationPropertiesBinder.getBinder(ConfigurationPropertiesBinder.java:168) ~[flyway:na]
	at org.springframework.boot.context.properties.ConfigurationPropertiesBinder.bind(ConfigurationPropertiesBinder.java:95) ~[flyway:na]
	at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.bind(ConfigurationPropertiesBindingPostProcessor.java:89) ~[flyway:na]
	at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization(ConfigurationPropertiesBindingPostProcessor.java:78) ~[flyway:na]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:425) ~[flyway:6.0.0-SNAPSHOT]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1745) ~[flyway:6.0.0-SNAPSHOT]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:604) ~[flyway:6.0.0-SNAPSHOT]
	... 29 common frames omitted

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:14 (14 by maintainers)

github_iconTop GitHub Comments

1reaction
mhalbrittercommented, Oct 17, 2022

I’m not 100% convinced that the scanner created by NativeImageResourceProviderCustomizer behaves exactly the same as the default one from Flyway. That’s the reason I was hesitant to always use the NativeImageResourceProviderCustomizer on JVM and on native image.

1reaction
mhalbrittercommented, Aug 25, 2022

Even if GraalVM team / Flyway team doesn’t want to support it by themselves, I found a better workaround than to look for the migrations at AOT phase: Implement a Flyway custom ResourceProvider which uses the resource: scheme from GraalVM to find the migrations. The PoC is here: https://github.com/mhalbritter/flyway-native-image

All that is left with this ResourceProvider in place is resource hints on db/migration/*.sql (or whatever the user has configured).

Drawback of that approach is that, when the custom ResourceProvider is in place, it get’s called for all migration locations, maybe even one with filesystem: or s3: prefixes. It would be nice to delegate this back to the default ResourceProvider, but it doesn’t seem like there is an easy way to do that.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Micronaut Flyway
Micronaut Flyway is compatible with GraalVM so it is possible to create native images and run the migrations during application startup. The list...
Read more >
How add Flyway dependency and build native image Quarkus ...
1 Answer 1 ... Quarkus supports Flyway without issues when executing in JVM mode, so you can use it as always. Quarkus native...
Read more >
Schema Migration with Flyway - Micronaut Guides
In this guide, we will create a Micronaut application written in Java. You use Flyway: Flyway is an open-source database migration tool. It...
Read more >
Release Notes - Flyway by Redgate • Database Migrations ...
New features. Add ability to specify 'target=next' to apply just the next migration; Add Kerberos authentication support for SQL Server; Issue 3306 Add...
Read more >
Creating a native image with Micronaut 2 and PostgreSQL
Particularly, we are going to add to support for a relational database (Postgres), a migration system (Flyway), and a dockerized database to ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found