From 04938477f3663012fa4f96f1e59877c2dc3d4f3b Mon Sep 17 00:00:00 2001 From: Maziz Date: Sun, 19 May 2024 13:05:55 +0800 Subject: [PATCH 1/5] 1. Implement scanner for flyway10 2. Add test for flyway10 case --- ...NativeImageResourceProviderCustomizer.java | 49 +++++++++++++++-- ...eImageResourceProviderCustomizerTests.java | 52 +++++++++++++++++++ 2 files changed, 97 insertions(+), 4 deletions(-) create mode 100644 spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/Flyway10NativeImageResourceProviderCustomizerTests.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/NativeImageResourceProviderCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/NativeImageResourceProviderCustomizer.java index 1dd7b6e55ecb..e7f191cd45cd 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/NativeImageResourceProviderCustomizer.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/NativeImageResourceProviderCustomizer.java @@ -16,6 +16,8 @@ package org.springframework.boot.autoconfigure.flyway; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import java.util.Arrays; import org.flywaydb.core.api.configuration.FluentConfiguration; @@ -24,6 +26,8 @@ import org.flywaydb.core.internal.scanner.ResourceNameCache; import org.flywaydb.core.internal.scanner.Scanner; +import org.springframework.util.ClassUtils; + /** * Registers {@link NativeImageResourceProvider} as a Flyway * {@link org.flywaydb.core.api.ResourceProvider}. @@ -32,13 +36,34 @@ */ class NativeImageResourceProviderCustomizer extends ResourceProviderCustomizer { + public static final int NUM_FLYWAY10_SCANNER_PARAMETERS = 5; + @Override public void customize(FluentConfiguration configuration) { if (configuration.getResourceProvider() == null) { - Scanner scanner = new Scanner<>(JavaMigration.class, - Arrays.asList(configuration.getLocations()), configuration.getClassLoader(), - configuration.getEncoding(), configuration.isDetectEncoding(), false, new ResourceNameCache(), - new LocationScannerCache(), configuration.isFailOnMissingLocations()); + Constructor scannerConstructor; + Scanner scanner; + try { + scannerConstructor = ClassUtils.forName("org.flywaydb.core.internal.scanner.Scanner", null) + .getDeclaredConstructors()[0]; + if (scannerConstructor.getParameters().length > NUM_FLYWAY10_SCANNER_PARAMETERS) { + scanner = getFlyway9Scanner(configuration); + } + else { + scanner = getFlyway10Scanner(configuration, scannerConstructor); + } + NativeImageResourceProvider resourceProvider = new NativeImageResourceProvider(scanner, + configuration.getClassLoader(), Arrays.asList(configuration.getLocations()), + configuration.getEncoding(), configuration.isFailOnMissingLocations()); + configuration.resourceProvider(resourceProvider); + } + catch (ClassNotFoundException ex) { + throw new IllegalStateException(ex); + } + catch (InvocationTargetException | InstantiationException | IllegalAccessException ex) { + throw new RuntimeException(ex); + } + NativeImageResourceProvider resourceProvider = new NativeImageResourceProvider(scanner, configuration.getClassLoader(), Arrays.asList(configuration.getLocations()), configuration.getEncoding(), configuration.isFailOnMissingLocations()); @@ -46,4 +71,20 @@ public void customize(FluentConfiguration configuration) { } } + private static Scanner getFlyway10Scanner(FluentConfiguration configuration, Constructor scannerConstructor) + throws InstantiationException, IllegalAccessException, InvocationTargetException { + Scanner scanner; + scanner = (Scanner) scannerConstructor.newInstance(JavaMigration.class, false, new ResourceNameCache(), + new LocationScannerCache(), configuration); + return scanner; + } + + private static Scanner getFlyway9Scanner(FluentConfiguration configuration) { + Scanner scanner; + scanner = new Scanner<>(JavaMigration.class, Arrays.asList(configuration.getLocations()), + configuration.getClassLoader(), configuration.getEncoding(), configuration.isDetectEncoding(), false, + new ResourceNameCache(), new LocationScannerCache(), configuration.isFailOnMissingLocations()); + return scanner; + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/Flyway10NativeImageResourceProviderCustomizerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/Flyway10NativeImageResourceProviderCustomizerTests.java new file mode 100644 index 000000000000..9e3e5e4db3b8 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/Flyway10NativeImageResourceProviderCustomizerTests.java @@ -0,0 +1,52 @@ +/* + * Copyright 2012-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.flyway; + +import java.util.Collection; + +import org.flywaydb.core.api.ResourceProvider; +import org.flywaydb.core.api.configuration.FluentConfiguration; +import org.flywaydb.core.api.resource.LoadableResource; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.testsupport.classpath.ClassPathOverrides; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link NativeImageResourceProviderCustomizer} with Flyway 10. + * + * @author Moritz Halbritter + * @author Andy Wilkinson + * @author Maziz + */ +@ClassPathOverrides("org.flywaydb:flyway-core:10.12.0") +class Flyway10NativeImageResourceProviderCustomizerTests { + + private final NativeImageResourceProviderCustomizer customizer = new NativeImageResourceProviderCustomizer(); + + @Test + void nativeImageResourceProviderShouldFindMigrations() { + FluentConfiguration configuration = new FluentConfiguration(); + this.customizer.customize(configuration); + ResourceProvider resourceProvider = configuration.getResourceProvider(); + Collection migrations = resourceProvider.getResources("V", new String[] { ".sql" }); + LoadableResource migration = resourceProvider.getResource("V1__init.sql"); + assertThat(migrations).containsExactly(migration); + } + +} From dba62c0c1ada8db3051c46811ef2007ee89c174c Mon Sep 17 00:00:00 2001 From: Maziz Date: Sun, 19 May 2024 17:35:02 +0800 Subject: [PATCH 2/5] Update authors --- .../flyway/NativeImageResourceProviderCustomizer.java | 1 + .../autoconfigure/flyway/Flyway10xAutoConfigurationTests.java | 1 + 2 files changed, 2 insertions(+) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/NativeImageResourceProviderCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/NativeImageResourceProviderCustomizer.java index e7f191cd45cd..fe0422e15e93 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/NativeImageResourceProviderCustomizer.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/NativeImageResourceProviderCustomizer.java @@ -33,6 +33,7 @@ * {@link org.flywaydb.core.api.ResourceProvider}. * * @author Moritz Halbritter + * @author Maziz */ class NativeImageResourceProviderCustomizer extends ResourceProviderCustomizer { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/Flyway10xAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/Flyway10xAutoConfigurationTests.java index e1e8ebdddbe3..60fe533a28ad 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/Flyway10xAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/Flyway10xAutoConfigurationTests.java @@ -34,6 +34,7 @@ * Tests for {@link FlywayAutoConfiguration} with Flyway 10.x. * * @author Andy Wilkinson + * @author Maziz */ @ClassPathExclusions({ "flyway-core-*.jar", "flyway-sqlserver-*.jar" }) @ClassPathOverrides({ "org.flywaydb:flyway-core:10.0.0", "com.h2database:h2:2.1.210" }) From 17658b6f2fae64b03c2f74fe6d5e2eb6505737e4 Mon Sep 17 00:00:00 2001 From: Maziz Date: Sun, 19 May 2024 20:10:04 +0800 Subject: [PATCH 3/5] Fix comment formatting --- ...NativeImageResourceProviderCustomizer.java | 22 +++++++++++++------ .../Flyway10xAutoConfigurationTests.java | 2 +- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/NativeImageResourceProviderCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/NativeImageResourceProviderCustomizer.java index fe0422e15e93..08b472581846 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/NativeImageResourceProviderCustomizer.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/NativeImageResourceProviderCustomizer.java @@ -33,7 +33,7 @@ * {@link org.flywaydb.core.api.ResourceProvider}. * * @author Moritz Halbritter - * @author Maziz + * @author Maziz Esa */ class NativeImageResourceProviderCustomizer extends ResourceProviderCustomizer { @@ -47,12 +47,7 @@ public void customize(FluentConfiguration configuration) { try { scannerConstructor = ClassUtils.forName("org.flywaydb.core.internal.scanner.Scanner", null) .getDeclaredConstructors()[0]; - if (scannerConstructor.getParameters().length > NUM_FLYWAY10_SCANNER_PARAMETERS) { - scanner = getFlyway9Scanner(configuration); - } - else { - scanner = getFlyway10Scanner(configuration, scannerConstructor); - } + scanner = getFlyway9Or10ScannerObject(configuration, scannerConstructor); NativeImageResourceProvider resourceProvider = new NativeImageResourceProvider(scanner, configuration.getClassLoader(), Arrays.asList(configuration.getLocations()), configuration.getEncoding(), configuration.isFailOnMissingLocations()); @@ -72,6 +67,19 @@ public void customize(FluentConfiguration configuration) { } } + private static Scanner getFlyway9Or10ScannerObject(FluentConfiguration configuration, + Constructor scannerConstructor) + throws InstantiationException, IllegalAccessException, InvocationTargetException { + Scanner scanner; + if (scannerConstructor.getParameters().length > NUM_FLYWAY10_SCANNER_PARAMETERS) { + scanner = getFlyway9Scanner(configuration); + } + else { + scanner = getFlyway10Scanner(configuration, scannerConstructor); + } + return scanner; + } + private static Scanner getFlyway10Scanner(FluentConfiguration configuration, Constructor scannerConstructor) throws InstantiationException, IllegalAccessException, InvocationTargetException { Scanner scanner; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/Flyway10xAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/Flyway10xAutoConfigurationTests.java index 60fe533a28ad..3d61ad825050 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/Flyway10xAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/Flyway10xAutoConfigurationTests.java @@ -34,7 +34,7 @@ * Tests for {@link FlywayAutoConfiguration} with Flyway 10.x. * * @author Andy Wilkinson - * @author Maziz + * @author Maziz Esa */ @ClassPathExclusions({ "flyway-core-*.jar", "flyway-sqlserver-*.jar" }) @ClassPathOverrides({ "org.flywaydb:flyway-core:10.0.0", "com.h2database:h2:2.1.210" }) From 726d61485abb2575bd96885f79f6fb9c3749c412 Mon Sep 17 00:00:00 2001 From: Maziz Date: Sun, 19 May 2024 20:51:24 +0800 Subject: [PATCH 4/5] Revert unnecessary changes --- .../autoconfigure/flyway/Flyway10xAutoConfigurationTests.java | 1 - 1 file changed, 1 deletion(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/Flyway10xAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/Flyway10xAutoConfigurationTests.java index 3d61ad825050..e1e8ebdddbe3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/Flyway10xAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/Flyway10xAutoConfigurationTests.java @@ -34,7 +34,6 @@ * Tests for {@link FlywayAutoConfiguration} with Flyway 10.x. * * @author Andy Wilkinson - * @author Maziz Esa */ @ClassPathExclusions({ "flyway-core-*.jar", "flyway-sqlserver-*.jar" }) @ClassPathOverrides({ "org.flywaydb:flyway-core:10.0.0", "com.h2database:h2:2.1.210" }) From 0b2de8dedcfc12e87c6107cb12930b12c87eb9ee Mon Sep 17 00:00:00 2001 From: Maziz Date: Sun, 26 May 2024 11:25:34 +0800 Subject: [PATCH 5/5] Make default case with flyway 9, calls from default constructor and flyway10 via reflection. --- ...NativeImageResourceProviderCustomizer.java | 51 ++++++++----------- 1 file changed, 20 insertions(+), 31 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/NativeImageResourceProviderCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/NativeImageResourceProviderCustomizer.java index 08b472581846..4e7668379eba 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/NativeImageResourceProviderCustomizer.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/NativeImageResourceProviderCustomizer.java @@ -37,29 +37,10 @@ */ class NativeImageResourceProviderCustomizer extends ResourceProviderCustomizer { - public static final int NUM_FLYWAY10_SCANNER_PARAMETERS = 5; - @Override public void customize(FluentConfiguration configuration) { if (configuration.getResourceProvider() == null) { - Constructor scannerConstructor; - Scanner scanner; - try { - scannerConstructor = ClassUtils.forName("org.flywaydb.core.internal.scanner.Scanner", null) - .getDeclaredConstructors()[0]; - scanner = getFlyway9Or10ScannerObject(configuration, scannerConstructor); - NativeImageResourceProvider resourceProvider = new NativeImageResourceProvider(scanner, - configuration.getClassLoader(), Arrays.asList(configuration.getLocations()), - configuration.getEncoding(), configuration.isFailOnMissingLocations()); - configuration.resourceProvider(resourceProvider); - } - catch (ClassNotFoundException ex) { - throw new IllegalStateException(ex); - } - catch (InvocationTargetException | InstantiationException | IllegalAccessException ex) { - throw new RuntimeException(ex); - } - + final var scanner = getFlyway9OrFallbackTo10ScannerObject(configuration); NativeImageResourceProvider resourceProvider = new NativeImageResourceProvider(scanner, configuration.getClassLoader(), Arrays.asList(configuration.getLocations()), configuration.getEncoding(), configuration.isFailOnMissingLocations()); @@ -67,24 +48,32 @@ public void customize(FluentConfiguration configuration) { } } - private static Scanner getFlyway9Or10ScannerObject(FluentConfiguration configuration, - Constructor scannerConstructor) - throws InstantiationException, IllegalAccessException, InvocationTargetException { + private static Scanner getFlyway9OrFallbackTo10ScannerObject(FluentConfiguration configuration) { Scanner scanner; - if (scannerConstructor.getParameters().length > NUM_FLYWAY10_SCANNER_PARAMETERS) { + try { scanner = getFlyway9Scanner(configuration); } - else { - scanner = getFlyway10Scanner(configuration, scannerConstructor); + catch (NoSuchMethodError noSuchMethodError) { + // happens when scanner is flyway version 10, which the constructor accepts + // different number of parameters. + scanner = getFlyway10Scanner(configuration); } return scanner; } - private static Scanner getFlyway10Scanner(FluentConfiguration configuration, Constructor scannerConstructor) - throws InstantiationException, IllegalAccessException, InvocationTargetException { - Scanner scanner; - scanner = (Scanner) scannerConstructor.newInstance(JavaMigration.class, false, new ResourceNameCache(), - new LocationScannerCache(), configuration); + private static Scanner getFlyway10Scanner(FluentConfiguration configuration) { + final Constructor scannerConstructor; + final Scanner scanner; + try { + scannerConstructor = ClassUtils.forName("org.flywaydb.core.internal.scanner.Scanner", null) + .getDeclaredConstructors()[0]; + scanner = (Scanner) scannerConstructor.newInstance(JavaMigration.class, false, new ResourceNameCache(), + new LocationScannerCache(), configuration); + } + catch (ClassNotFoundException | InstantiationException | IllegalAccessException + | InvocationTargetException ex) { + throw new RuntimeException(ex); + } return scanner; }