spring-boot icon indicating copy to clipboard operation
spring-boot copied to clipboard

Flyway Java migration not supported in native images

Open bclozel opened this issue 3 years ago • 3 comments

As discussed on gitter with @jnizet :

Hi team. I was just experimenting with native image support with a small application I have, and I think I found a missing piece in the native support. Flyway migrations are correctly detected and run... except the Java migrations. I get the following warning from Flyway at startup:

WARN 1 --- [ main] o.f.core.internal.command.DbMigrate : Schema "public" has a version (011) that is newer than the latest available migration (010) !

And the reason is that the migration 011, which has been run by a previous run of the application (in "non-native" mode), is a Java migration rather than a more traditional SQL migration (https://flywaydb.org/documentation/tutorials/java)

While we support the discovery of static sql migration files at runtime in a native image (using a custom resolver, org.springframework.boot.autoconfigure.flyway.NativeImageResourceProviderCustomizer) we are currently missing reflection metadata entries for the Java migration classes, since they are instantiated reflectively.

bclozel avatar Dec 05 '22 08:12 bclozel

I'm not 100% sure that it's enough to register hints for the migration classes. Flyway somehow needs to find them, and classpath scanning in native-image doesn't work like it does on the JVM. We might need to find them at AOT build time and then help flyway find them later in the native image.

mhalbritter avatar Dec 05 '22 08:12 mhalbritter

I've documented the limitation here: https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-with-GraalVM#flyway

mhalbritter avatar Dec 05 '22 09:12 mhalbritter

You can work around this issue by declaring a bean of type FlywayConfigurationCustomizer and register your Flyway Java migrations manually:

@Component
class JavaMigrationsFlywayCustomizer implements FlywayConfigurationCustomizer {

	@Override
	public void customize(FluentConfiguration configuration) {
		configuration.javaMigrations(new V1__create_table(), new ...);
	}

}

mhalbritter avatar Dec 05 '22 10:12 mhalbritter

Another worker around according to docs is

import org.springframework.aot.hint.RuntimeHintsRegistrar;

public class MyRuntimeHints implements RuntimeHintsRegistrar {

    @Override
    public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
        // migration
        hints.resources().registerPattern("db/migration/V1__init_migration.sql");
    }

}

@SpringBootApplication
@ImportRuntimeHints(value = {MyRuntimeHints.class})
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

iTchTheRightSpot avatar Nov 08 '23 01:11 iTchTheRightSpot

This issue is about migrations written in Java. @emmanuelU17, your hint is for a script-based migration and should not be necessary as we already automatically register hints for db/migration/*:

https://github.com/spring-projects/spring-boot/blob/690cfa220a74903f0052095371e94f59d5c50c2a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java#L422-L429

If that's not working for you please open a new issue with a minimal sample that reproduces the problem and we will take a look.

wilkinsona avatar Nov 08 '23 07:11 wilkinsona

I don't think we should tackle this one. There's a fairly straightforward workaround (that I've added to the existing Flyway section in the wiki) and I think any further improvements in this area should be made in Flyway itself.

wilkinsona avatar Apr 22 '24 08:04 wilkinsona