diff --git a/extensions/liquibase/deployment/src/main/java/io/quarkus/liquibase/deployment/LiquibaseProcessor.java b/extensions/liquibase/deployment/src/main/java/io/quarkus/liquibase/deployment/LiquibaseProcessor.java index 7584fcad147e5..a78eb594f548b 100644 --- a/extensions/liquibase/deployment/src/main/java/io/quarkus/liquibase/deployment/LiquibaseProcessor.java +++ b/extensions/liquibase/deployment/src/main/java/io/quarkus/liquibase/deployment/LiquibaseProcessor.java @@ -12,6 +12,7 @@ import java.util.List; import java.util.Optional; import java.util.Set; +import java.util.function.BiConsumer; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -45,6 +46,7 @@ import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBundleBuildItem; import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem; +import io.quarkus.deployment.builditem.nativeimage.RuntimeReinitializedClassBuildItem; import io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem; import io.quarkus.deployment.pkg.steps.NativeOrNativeSourcesBuild; import io.quarkus.deployment.util.ServiceUtil; @@ -104,6 +106,7 @@ void nativeImageConfiguration( BuildProducer resource, BuildProducer services, BuildProducer runtimeInitialized, + BuildProducer runtimeReInitialized, BuildProducer resourceBundle) { runtimeInitialized.produce(new RuntimeInitializedClassBuildItem(liquibase.diff.compare.CompareControl.class.getName())); @@ -112,7 +115,8 @@ void nativeImageConfiguration( liquibase.change.AbstractSQLChange.class.getName(), liquibase.database.jvm.JdbcConnection.class.getName())); - reflective.produce(new ReflectiveClassBuildItem(true, false, false, "liquibase.command.LiquibaseCommandFactory")); + reflective.produce(new ReflectiveClassBuildItem(true, false, false, "liquibase.command.LiquibaseCommandFactory", + liquibase.command.CommandFactory.class.getName())); reflective.produce(new ReflectiveClassBuildItem(true, true, true, liquibase.parser.ChangeLogParserCofiguration.class.getName(), @@ -180,10 +184,26 @@ void nativeImageConfiguration( liquibase.sqlgenerator.SqlGenerator.class, liquibase.structure.DatabaseObject.class, liquibase.hub.HubService.class) - .forEach(t -> addService(services, reflective, t, false)); + .forEach(t -> consumeService(t, (serviceClass, implementations) -> { + services.produce( + new ServiceProviderBuildItem(serviceClass.getName(), implementations.toArray(new String[0]))); + reflective.produce(new ReflectiveClassBuildItem(true, true, false, implementations.toArray(new String[0]))); + })); // Register Precondition services, and the implementation class for reflection while also registering fields for reflection - addService(services, reflective, liquibase.precondition.Precondition.class, true); + consumeService(liquibase.precondition.Precondition.class, (serviceClass, implementations) -> { + services.produce(new ServiceProviderBuildItem(serviceClass.getName(), implementations.toArray(new String[0]))); + reflective.produce(new ReflectiveClassBuildItem(true, true, true, implementations.toArray(new String[0]))); + }); + + // CommandStep implementations are needed + consumeService(liquibase.command.CommandStep.class, (serviceClass, implementations) -> { + services.produce(new ServiceProviderBuildItem(serviceClass.getName(), implementations.toArray(new String[0]))); + reflective.produce(new ReflectiveClassBuildItem(true, false, false, implementations.toArray(new String[0]))); + for (String implementation : implementations) { + runtimeInitialized.produce(new RuntimeInitializedClassBuildItem(implementation)); + } + }); // liquibase XSD resource.produce(new NativeImageResourceBuildItem( @@ -207,17 +227,12 @@ void nativeImageConfiguration( resourceBundle.produce(new NativeImageResourceBundleBuildItem("liquibase/i18n/liquibase-core")); } - private void addService(BuildProducer services, - BuildProducer reflective, Class serviceClass, - boolean shouldRegisterFieldForReflection) { + private void consumeService(Class serviceClass, BiConsumer, Collection> consumer) { try { String service = "META-INF/services/" + serviceClass.getName(); Set implementations = ServiceUtil.classNamesNamedIn(Thread.currentThread().getContextClassLoader(), service); - services.produce(new ServiceProviderBuildItem(serviceClass.getName(), implementations.toArray(new String[0]))); - - reflective.produce(new ReflectiveClassBuildItem(true, true, shouldRegisterFieldForReflection, - implementations.toArray(new String[0]))); + consumer.accept(serviceClass, implementations); } catch (IOException ex) { throw new IllegalStateException(ex); }