Fix Flyway sub-folders support in Native image

Prior to this commit, the native image support for scanning Flyway
migration scripts would not scan sub-folders at runtime when running a
Native image.

This commit ensures that the resource scanning at runtime also considers
sub-directories for native images.

Fixes gh-49661
This commit is contained in:
Brian Clozel
2026-03-23 09:50:02 +01:00
parent 10df287bbb
commit e65732e178
3 changed files with 17 additions and 1 deletions
@@ -145,7 +145,7 @@ class NativeImageResourceProvider implements ResourceProvider {
private Resource[] getResources(PathMatchingResourcePatternResolver resolver, Location location, Resource root) {
try {
return resolver.getResources(root.getURI() + "/*");
return resolver.getResources(root.getURI() + "/**/*");
}
catch (IOException ex) {
throw new UncheckedIOException("Failed to list resources for " + location.getDescriptor(), ex);
@@ -968,6 +968,8 @@ class FlywayAutoConfigurationTests {
new FlywayAutoConfigurationRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader());
assertThat(RuntimeHintsPredicates.resource().forResource("db/migration/")).accepts(runtimeHints);
assertThat(RuntimeHintsPredicates.resource().forResource("db/migration/V1__init.sql")).accepts(runtimeHints);
assertThat(RuntimeHintsPredicates.resource().forResource("db/migration/nested/V2__users.sql"))
.accepts(runtimeHints);
}
@Test
@@ -25,6 +25,7 @@ import org.flywaydb.core.internal.resource.NoopResourceProvider;
import org.junit.jupiter.api.Test;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.boot.testsupport.classpath.resources.WithResources;
import static org.assertj.core.api.Assertions.assertThat;
@@ -56,6 +57,19 @@ class NativeImageResourceProviderCustomizerTests {
assertThat(migrations).containsExactly(migration);
}
@Test
@WithResources({ @WithResource(name = "db/migration/V1__init.sql"),
@WithResource(name = "db/migration/nested/V2__users.sql") })
void nativeImageResourceProviderShouldFindNestedMigrations() {
FluentConfiguration configuration = new FluentConfiguration();
this.customizer.customize(configuration);
ResourceProvider resourceProvider = configuration.getResourceProvider();
Collection<LoadableResource> migrations = resourceProvider.getResources("V", new String[] { ".sql" });
LoadableResource v1 = resourceProvider.getResource("V1__init.sql");
LoadableResource v2 = resourceProvider.getResource("nested/V2__users.sql");
assertThat(migrations).containsExactly(v1, v2);
}
@Test
void shouldBackOffOnCustomResourceProvider() {
FluentConfiguration configuration = new FluentConfiguration();