From 2fa551627f038f4b2eb761b573aa2aac6326971d Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Mon, 6 Oct 2025 11:48:44 +0300 Subject: [PATCH 1/3] Drop long deprecated native config options --- .../quarkus/deployment/pkg/NativeConfig.java | 56 ------------------- .../pkg/steps/NativeImageBuildStep.java | 35 ------------ .../deployment/pkg/TestNativeConfig.java | 30 ---------- 3 files changed, 121 deletions(-) diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/NativeConfig.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/NativeConfig.java index b1a007eac409b..243d958168002 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/NativeConfig.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/NativeConfig.java @@ -64,31 +64,6 @@ public interface NativeConfig { @WithDefault("false") boolean enableHttpsUrlHandler(); - /** - * If all security services should be added to the native image - * - * @deprecated {@code --enable-all-security-services} was removed in GraalVM 21.1 https://github.com/oracle/graal/pull/3258 - */ - @WithDefault("false") - @Deprecated - boolean enableAllSecurityServices(); - - /** - * If {@code -H:+InlineBeforeAnalysis} flag will be added to the native-image run - * - * @deprecated inlineBeforeAnalysis is always enabled starting from GraalVM 21.3. - */ - @Deprecated - @WithDefault("true") - boolean inlineBeforeAnalysis(); - - /** - * @deprecated JNI is always enabled starting from GraalVM 19.3.1. - */ - @Deprecated - @WithDefault("true") - boolean enableJni(); - /** * The default value for java.awt.headless JVM option. * Switching this option affects linking of awt libraries. @@ -173,16 +148,6 @@ public interface NativeConfig { @WithDefault("true") boolean publishDebugBuildProcessPort(); - /** - * If the native image server should be restarted. - * - * @deprecated Since GraalVM 20.2.0 the native image server has become an experimental feature and is disabled by - * default. - */ - @Deprecated - @WithDefault("false") - boolean cleanupServer(); - /** * If isolates should be enabled */ @@ -196,18 +161,6 @@ public interface NativeConfig { @WithDefault("false") boolean enableFallbackImages(); - /** - * If the native image server should be used. This can speed up compilation but can result in changes not always - * being picked up due to cache invalidation not working 100% - * - * @deprecated This used to be the default prior to GraalVM 20.2.0 and this configuration item was used to disable - * it as it was not stable. Since GraalVM 20.2.0 the native image server has become an experimental - * feature. - */ - @Deprecated - @WithDefault("false") - boolean enableServer(); - /** * If all META-INF/services entries should be automatically registered */ @@ -339,15 +292,6 @@ default String getEffectiveImage() { */ Optional> monitoring(); - /** - * If full stack traces are enabled in the resulting image - * - * @deprecated GraalVM 23.1+ will always build with full stack traces. - */ - @WithDefault("true") - @Deprecated - boolean fullStackTraces(); - /** * If the reports on call paths and included packages/classes/methods should be generated */ diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStep.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStep.java index 1f4fc463e30ca..a0b778a9d8134 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStep.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStep.java @@ -246,14 +246,6 @@ public NativeImageBuildItem build(NativeConfig nativeConfig, LocalesBuildTimeCon checkGraalVMVersion(graalVMVersion); try { - if (nativeConfig.cleanupServer()) { - log.warn( - "Your application is setting the deprecated 'quarkus.native.cleanup-server' configuration key" - + " to true. Please consider removing this configuration key as it is ignored" - + " (The Native image build server is always disabled) and it will be removed in a" - + " future Quarkus version."); - } - NativeImageInvokerInfo commandAndExecutable = new NativeImageInvokerInfo.Builder() .setNativeConfig(nativeConfig) .setLocalesBuildTimeConfig(localesBuildTimeConfig) @@ -717,7 +709,6 @@ public Builder setNativeMonitoringOptions(List option public NativeImageInvokerInfo build() { List nativeImageArgs = new ArrayList<>(); boolean enableSslNative = false; - boolean inlineBeforeAnalysis = nativeConfig.inlineBeforeAnalysis(); boolean addAllCharsets = nativeConfig.addAllCharsets(); boolean enableHttpsUrlHandler = nativeConfig.enableHttpsUrlHandler(); for (NativeImageSystemPropertyBuildItem prop : nativeImageProperties) { @@ -735,8 +726,6 @@ public NativeImageInvokerInfo build() { + " will be removed in a future Quarkus version."); } else if (prop.getKey().equals("quarkus.native.enable-all-charsets") && prop.getValue() != null) { addAllCharsets |= Boolean.parseBoolean(prop.getValue()); - } else if (prop.getKey().equals("quarkus.native.inline-before-analysis") && prop.getValue() != null) { - inlineBeforeAnalysis = Boolean.parseBoolean(prop.getValue()); } else { // todo maybe just -D is better than -J-D in this case if (prop.getValue() == null) { @@ -922,9 +911,6 @@ public NativeImageInvokerInfo build() { if (!protocols.isEmpty()) { nativeImageArgs.add("--enable-url-protocols=" + String.join(",", protocols)); } - if (!inlineBeforeAnalysis) { - addExperimentalVMOption(nativeImageArgs, "-H:-InlineBeforeAnalysis"); - } if (!pie.isEmpty()) { nativeImageArgs.add("-H:NativeLinkerOption=" + pie); } @@ -932,19 +918,6 @@ public NativeImageInvokerInfo build() { if (!nativeConfig.enableIsolates()) { addExperimentalVMOption(nativeImageArgs, "-H:-SpawnIsolates"); } - if (!nativeConfig.enableJni()) { - log.warn( - "Your application is setting the deprecated 'quarkus.native.enable-jni' configuration key to false." - + " Please consider removing this configuration key as it is ignored (JNI is always enabled) and it" - + " will be removed in a future Quarkus version."); - } - if (nativeConfig.enableServer()) { - log.warn( - "Your application is setting the deprecated 'quarkus.native.enable-server' configuration key to true." - + " Please consider removing this configuration key as it is ignored" - + " (The Native image build server is always disabled) and it" - + " will be removed in a future Quarkus version."); - } if (nativeConfig.enableVmInspection()) { addExperimentalVMOption(nativeImageArgs, "-H:+AllowVMInspection"); } @@ -1000,14 +973,6 @@ public NativeImageInvokerInfo build() { } else { addExperimentalVMOption(nativeImageArgs, "-H:-UseServiceLoaderFeature"); } - // This option has no effect on GraalVM 23.1+ - if (graalVMVersion.compareTo(GraalVM.Version.VERSION_23_1_0) < 0) { - if (nativeConfig.fullStackTraces()) { - nativeImageArgs.add("-H:+StackTrace"); - } else { - nativeImageArgs.add("-H:-StackTrace"); - } - } if (nativeConfig.enableDashboardDump()) { addExperimentalVMOption(nativeImageArgs, diff --git a/core/deployment/src/test/java/io/quarkus/deployment/pkg/TestNativeConfig.java b/core/deployment/src/test/java/io/quarkus/deployment/pkg/TestNativeConfig.java index 13fb96f4cb8fc..dfba88ebbc537 100644 --- a/core/deployment/src/test/java/io/quarkus/deployment/pkg/TestNativeConfig.java +++ b/core/deployment/src/test/java/io/quarkus/deployment/pkg/TestNativeConfig.java @@ -50,21 +50,6 @@ public boolean enableHttpsUrlHandler() { return false; } - @Override - public boolean enableAllSecurityServices() { - return false; - } - - @Override - public boolean inlineBeforeAnalysis() { - return false; - } - - @Override - public boolean enableJni() { - return false; - } - @Override public boolean headless() { return false; @@ -115,11 +100,6 @@ public boolean publishDebugBuildProcessPort() { return false; } - @Override - public boolean cleanupServer() { - return false; - } - @Override public boolean enableIsolates() { return false; @@ -130,11 +110,6 @@ public boolean enableFallbackImages() { return false; } - @Override - public boolean enableServer() { - return false; - } - @Override public boolean autoServiceLoaderRegistration() { return false; @@ -190,11 +165,6 @@ public Optional> monitoring() { return Optional.empty(); } - @Override - public boolean fullStackTraces() { - return false; - } - @Override public boolean enableReports() { return false; From daa004a7a84b419ebd8b10f718e7a39721609e4d Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Mon, 6 Oct 2025 11:51:35 +0300 Subject: [PATCH 2/3] Remove deprecated native config language and country options --- .../quarkus/deployment/pkg/NativeConfig.java | 24 ----------- .../deployment/steps/LocaleProcessor.java | 40 +++---------------- .../steps/NativeImageFeatureStep.java | 10 +---- .../deployment/pkg/TestNativeConfig.java | 10 ----- .../src/test/resources/application.properties | 2 - .../java/io/quarkus/locales/it/LocalesIT.java | 2 +- .../src/test/resources/application.properties | 5 +-- 7 files changed, 8 insertions(+), 85 deletions(-) diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/NativeConfig.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/NativeConfig.java index 243d958168002..1d76936672d6a 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/NativeConfig.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/NativeConfig.java @@ -71,30 +71,6 @@ public interface NativeConfig { @WithDefault("true") boolean headless(); - /** - * Defines the user language used for building the native executable. - * With GraalVM versions prior to GraalVM for JDK 24 it also serves as the default Locale language for the native executable - * application runtime. - * e.g. en or cs as defined by IETF BCP 47 language tags. - *

- * - * @deprecated Use the global quarkus.default-locale. - */ - @Deprecated - Optional<@WithConverter(TrimmedStringConverter.class) String> userLanguage(); - - /** - * Defines the user country used for building the native executable. - * With GraalVM versions prior to GraalVM for JDK 24 it also serves as the default Locale country for the native executable - * application runtime. - * e.g. US or FR as defined by ISO 3166-1 alpha-2 codes. - *

- * - * @deprecated Use the global quarkus.default-locale. - */ - @Deprecated - Optional<@WithConverter(TrimmedStringConverter.class) String> userCountry(); - /** * Defines the file encoding as in {@code -Dfile.encoding=...}. *

diff --git a/core/deployment/src/main/java/io/quarkus/deployment/steps/LocaleProcessor.java b/core/deployment/src/main/java/io/quarkus/deployment/steps/LocaleProcessor.java index b054d085d1585..03528b1a6e97a 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/steps/LocaleProcessor.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/steps/LocaleProcessor.java @@ -28,12 +28,6 @@ public class LocaleProcessor { private static final Logger log = Logger.getLogger(LocaleProcessor.class); - public static final String DEPRECATED_USER_LANGUAGE_WARNING = "Your application is setting the deprecated 'quarkus.native.user-language' configuration property. " - + - "Please, consider using only 'quarkus.default-locale' configuration property instead."; - public static final String DEPRECATED_USER_COUNTRY_WARNING = "Your application is setting the deprecated 'quarkus.native.user-country' configuration property. " - + - "Please, consider using only 'quarkus.default-locale' configuration property instead."; @BuildStep(onlyIf = { NativeBuild.class, NonDefaultLocale.class }) void nativeResources(BuildProducer resources) { @@ -92,14 +86,8 @@ public NonDefaultLocale(NativeConfig nativeConfig, LocalesBuildTimeConfig locale @Override public boolean getAsBoolean() { - return (nativeConfig.userLanguage().isPresent() - && !Locale.getDefault().getLanguage().equals(nativeConfig.userLanguage().get())) - || - (nativeConfig.userCountry().isPresent() - && !Locale.getDefault().getCountry().equals(nativeConfig.userCountry().get())) - || - (localesBuildTimeConfig.defaultLocale().isPresent() && - !Locale.getDefault().equals(localesBuildTimeConfig.defaultLocale().get())) + return (localesBuildTimeConfig.defaultLocale().isPresent() && + !Locale.getDefault().equals(localesBuildTimeConfig.defaultLocale().get())) || localesBuildTimeConfig.locales().stream().anyMatch(l -> !Locale.getDefault().equals(l)); } @@ -110,8 +98,7 @@ public boolean getAsBoolean() { * * @param nativeConfig * @param localesBuildTimeConfig - * @return User language set by 'quarkus.default-locale' or by deprecated 'quarkus.native.user-language' or - * effectively LocalesBuildTimeConfig.DEFAULT_LANGUAGE if none of the aforementioned is set. + * @return User language set by 'quarkus.default-locale' or effectively LocalesBuildTimeConfig.DEFAULT_LANGUAGE if not set. * @Deprecated */ @Deprecated @@ -120,11 +107,6 @@ public static String nativeImageUserLanguage(NativeConfig nativeConfig, LocalesB if (localesBuildTimeConfig.defaultLocale().isPresent()) { language = localesBuildTimeConfig.defaultLocale().get().getLanguage(); } - if (nativeConfig.userLanguage().isPresent()) { - log.warn(DEPRECATED_USER_LANGUAGE_WARNING); - // The deprecated option takes precedence for users who are already using it. - language = nativeConfig.userLanguage().get(); - } return language; } @@ -133,9 +115,7 @@ public static String nativeImageUserLanguage(NativeConfig nativeConfig, LocalesB * * @param nativeConfig * @param localesBuildTimeConfig - * @return User country set by 'quarkus.default-locale' or by deprecated 'quarkus.native.user-country' or - * effectively LocalesBuildTimeConfig.DEFAULT_COUNTRY (could be an empty string) if none of the aforementioned is - * set. + * @return User country set by 'quarkus.default-locale' or effectively LocalesBuildTimeConfig.DEFAULT_COUNTRY if not set. * @Deprecated */ @Deprecated @@ -144,11 +124,6 @@ public static String nativeImageUserCountry(NativeConfig nativeConfig, LocalesBu if (localesBuildTimeConfig.defaultLocale().isPresent()) { country = localesBuildTimeConfig.defaultLocale().get().getCountry(); } - if (nativeConfig.userCountry().isPresent()) { - log.warn(DEPRECATED_USER_COUNTRY_WARNING); - // The deprecated option takes precedence for users who are already using it. - country = nativeConfig.userCountry().get(); - } return country; } @@ -170,12 +145,7 @@ public static String nativeImageIncludeLocales(NativeConfig nativeConfig, Locale // GraalVM for JDK 24 doesn't include the default locale used at build time. We must explicitly include the // specified locales - including the build-time locale if set by the user. - // Note the deprecated options still count and take precedence. - if (nativeConfig.userCountry().isPresent() && nativeConfig.userLanguage().isPresent()) { - additionalLocales.add(new Locale(nativeConfig.userLanguage().get(), nativeConfig.userCountry().get())); - } else if (nativeConfig.userLanguage().isPresent()) { - additionalLocales.add(new Locale(nativeConfig.userLanguage().get())); - } else if (localesBuildTimeConfig.defaultLocale().isPresent()) { + if (localesBuildTimeConfig.defaultLocale().isPresent()) { additionalLocales.add(localesBuildTimeConfig.defaultLocale().get()); } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageFeatureStep.java b/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageFeatureStep.java index 7f9217f093ba2..cba4dfa1ab693 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageFeatureStep.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageFeatureStep.java @@ -95,15 +95,7 @@ public void write(String s, byte[] bytes) { overallCatch.marshalAsArray(String.class, overallCatch.load(""))); // empty string means initialize everything // Set the user.language and user.country system properties to the default locale - // The deprecated option takes precedence for users who are already using it. - if (nativeConfig.userLanguage().isPresent()) { - overallCatch.invokeStaticMethod(REGISTER_RUNTIME_SYSTEM_PROPERTIES, - overallCatch.load("user.language"), overallCatch.load(nativeConfig.userLanguage().get())); - if (nativeConfig.userCountry().isPresent()) { - overallCatch.invokeStaticMethod(REGISTER_RUNTIME_SYSTEM_PROPERTIES, - overallCatch.load("user.country"), overallCatch.load(nativeConfig.userCountry().get())); - } - } else if (localesBuildTimeConfig.defaultLocale().isPresent()) { + if (localesBuildTimeConfig.defaultLocale().isPresent()) { overallCatch.invokeStaticMethod(REGISTER_RUNTIME_SYSTEM_PROPERTIES, overallCatch.load("user.language"), overallCatch.load(localesBuildTimeConfig.defaultLocale().get().getLanguage())); diff --git a/core/deployment/src/test/java/io/quarkus/deployment/pkg/TestNativeConfig.java b/core/deployment/src/test/java/io/quarkus/deployment/pkg/TestNativeConfig.java index dfba88ebbc537..b1229da0c5697 100644 --- a/core/deployment/src/test/java/io/quarkus/deployment/pkg/TestNativeConfig.java +++ b/core/deployment/src/test/java/io/quarkus/deployment/pkg/TestNativeConfig.java @@ -55,16 +55,6 @@ public boolean headless() { return false; } - @Override - public Optional userLanguage() { - return Optional.empty(); - } - - @Override - public Optional userCountry() { - return Optional.empty(); - } - @Override public String fileEncoding() { return null; diff --git a/integration-tests/locales/default/src/test/resources/application.properties b/integration-tests/locales/default/src/test/resources/application.properties index d0d560bcb8336..3b071b389ef03 100644 --- a/integration-tests/locales/default/src/test/resources/application.properties +++ b/integration-tests/locales/default/src/test/resources/application.properties @@ -1,4 +1,2 @@ quarkus.locales=de,fr-FR,ja,uk-UA -# Note that quarkus.native.user-language is deprecated and solely quarkus.default-locale should be -# used in your application properties. This test uses it only to verify compatibility. quarkus.default-locale=mt-MT diff --git a/integration-tests/locales/some/src/test/java/io/quarkus/locales/it/LocalesIT.java b/integration-tests/locales/some/src/test/java/io/quarkus/locales/it/LocalesIT.java index 3f062fcd844ae..4c1bb47c11e8e 100644 --- a/integration-tests/locales/some/src/test/java/io/quarkus/locales/it/LocalesIT.java +++ b/integration-tests/locales/some/src/test/java/io/quarkus/locales/it/LocalesIT.java @@ -93,7 +93,7 @@ public void testDefaultLocalePre24_2() { /* * Prior to GraalVM 24.2, the locale could not be changed at runtime. * "Švýcarsko" is the correct name for Switzerland in Czech language. - * Czech is the default language as per quarkus.native.user-language=cs. + * Czech is the default language as per quarkus.default-locale=cs. */ .body(is("Švýcarsko")) .log().all(); diff --git a/integration-tests/locales/some/src/test/resources/application.properties b/integration-tests/locales/some/src/test/resources/application.properties index d5f80d916383d..785b80af952df 100644 --- a/integration-tests/locales/some/src/test/resources/application.properties +++ b/integration-tests/locales/some/src/test/resources/application.properties @@ -1,7 +1,4 @@ quarkus.locales=de,fr-FR,ja,uk-UA -# Note that quarkus.native.user-language is deprecated and solely quarkus.default-locale should be -# used in your application properties. This test uses it only to verify compatibility. -quarkus.native.user-language=cs -quarkus.default-locale=en-US +quarkus.default-locale=cs-US quarkus.test.arg-line=-Duser.language=de quarkus.test.env.LC_ALL=mt_MT.UTF-8 \ No newline at end of file From 4557b4ab75a9fb639461689a933bb8d7931cbe14 Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Tue, 7 Oct 2025 12:19:59 +0300 Subject: [PATCH 3/3] Remove long deprecated `finalFieldsWritable`-related code --- .../nativeimage/ReflectiveClassBuildItem.java | 19 ---------- ...FinalFieldsWritablePredicateBuildItem.java | 26 ------------- .../steps/ReflectiveHierarchyStep.java | 37 ++++++------------- .../kotlin/deployment/KotlinProcessor.java | 10 ----- 4 files changed, 12 insertions(+), 80 deletions(-) delete mode 100644 core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/ReflectiveClassFinalFieldsWritablePredicateBuildItem.java diff --git a/core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/ReflectiveClassBuildItem.java b/core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/ReflectiveClassBuildItem.java index 895d37601ceac..8099b4b506fce 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/ReflectiveClassBuildItem.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/ReflectiveClassBuildItem.java @@ -8,7 +8,6 @@ import org.jboss.logging.Logger; import io.quarkus.builder.item.MultiBuildItem; -import io.quarkus.runtime.graal.GraalVM; /** * Used to register a class for reflection in native mode @@ -196,15 +195,6 @@ public boolean isQueryConstructors() { return queryConstructors; } - /** - * @deprecated As of GraalVM 21.2 finalFieldsWritable is no longer needed when registering fields for reflection. This will - * be removed in a future version of Quarkus. - */ - @Deprecated - public boolean areFinalFieldsWritable() { - return false; - } - public boolean isWeak() { return weak; } @@ -335,15 +325,6 @@ public Builder classes() { return classes(true); } - /** - * @deprecated As of GraalVM 21.2 finalFieldsWritable is no longer needed when registering fields for reflection. This - * will be removed in a future version of Quarkus. - */ - @Deprecated(forRemoval = true) - public Builder finalFieldsWritable(boolean finalFieldsWritable) { - return this; - } - public Builder weak(boolean weak) { this.weak = weak; return this; diff --git a/core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/ReflectiveClassFinalFieldsWritablePredicateBuildItem.java b/core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/ReflectiveClassFinalFieldsWritablePredicateBuildItem.java deleted file mode 100644 index be61227c0a623..0000000000000 --- a/core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/ReflectiveClassFinalFieldsWritablePredicateBuildItem.java +++ /dev/null @@ -1,26 +0,0 @@ -package io.quarkus.deployment.builditem.nativeimage; - -import java.util.function.Predicate; - -import org.jboss.jandex.ClassInfo; - -import io.quarkus.builder.item.MultiBuildItem; - -/** - * Used by {@code io.quarkus.deployment.steps.ReflectiveHierarchyStep} to determine whether - * the final fields of the class should be writable (which they aren't by default) - * - * If any one of the predicates returns true for a class, then ReflectiveHierarchyStep uses that true value - */ -public final class ReflectiveClassFinalFieldsWritablePredicateBuildItem extends MultiBuildItem { - - private final Predicate predicate; - - public ReflectiveClassFinalFieldsWritablePredicateBuildItem(Predicate predicate) { - this.predicate = predicate; - } - - public Predicate getPredicate() { - return predicate; - } -} diff --git a/core/deployment/src/main/java/io/quarkus/deployment/steps/ReflectiveHierarchyStep.java b/core/deployment/src/main/java/io/quarkus/deployment/steps/ReflectiveHierarchyStep.java index 3ab286eac4fa5..c33ad46a2f0ad 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/steps/ReflectiveHierarchyStep.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/steps/ReflectiveHierarchyStep.java @@ -35,7 +35,6 @@ import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.builditem.CombinedIndexBuildItem; import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; -import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassFinalFieldsWritablePredicateBuildItem; import io.quarkus.deployment.builditem.nativeimage.ReflectiveHierarchyBuildItem; import io.quarkus.deployment.builditem.nativeimage.ReflectiveHierarchyIgnoreWarningBuildItem; import io.quarkus.deployment.util.JandexUtil; @@ -58,21 +57,10 @@ public ReflectiveHierarchyIgnoreWarningBuildItem ignoreJavaClassWarnings() { public void build(CombinedIndexBuildItem combinedIndexBuildItem, Capabilities capabilities, List hierarchy, List ignored, - List finalFieldsWritablePredicates, BuildProducer reflectiveClass) throws Exception { Set processedReflectiveHierarchies = new HashSet<>(); Map> unindexedClasses = new TreeMap<>(); - final Predicate finalFieldsWritable = finalFieldsWritablePredicates.isEmpty() ? - // no need to make final fields writable by default - (c) -> false - : - // create a predicate that returns true if any of the predicates says that final fields need to be writable - finalFieldsWritablePredicates - .stream() - .map(ReflectiveClassFinalFieldsWritablePredicateBuildItem::getPredicate) - .reduce(c -> false, Predicate::or); - // to avoid recursive processing of the hierarchy (which could lead to a StackOverflowError) we are going to be scheduling type visits instead final Deque visits = new ArrayDeque<>(); @@ -83,7 +71,7 @@ public void build(CombinedIndexBuildItem combinedIndexBuildItem, Capabilities ca i.getType(), processedReflectiveHierarchies, unindexedClasses, - finalFieldsWritable, reflectiveClass, visits); + reflectiveClass, visits); } while (!visits.isEmpty()) { @@ -134,7 +122,7 @@ private void removeIgnored(Map> unindexedClasses, private void addReflectiveHierarchy(CombinedIndexBuildItem combinedIndexBuildItem, Capabilities capabilities, ReflectiveHierarchyBuildItem reflectiveHierarchyBuildItem, String source, Type type, Set processedReflectiveHierarchies, Map> unindexedClasses, - Predicate finalFieldsWritable, BuildProducer reflectiveClass, + BuildProducer reflectiveClass, Deque visits) { final String newSource = source + " > " + type.name().toString(); if (type instanceof VoidType || @@ -150,35 +138,35 @@ private void addReflectiveHierarchy(CombinedIndexBuildItem combinedIndexBuildIte addClassTypeHierarchy(combinedIndexBuildItem, capabilities, reflectiveHierarchyBuildItem, newSource, type.name(), type.name(), processedReflectiveHierarchies, unindexedClasses, - finalFieldsWritable, reflectiveClass, visits); + reflectiveClass, visits); for (ClassInfo subclass : combinedIndexBuildItem.getIndex().getAllKnownSubclasses(type.name())) { addClassTypeHierarchy(combinedIndexBuildItem, capabilities, reflectiveHierarchyBuildItem, newSource, subclass.name(), subclass.name(), processedReflectiveHierarchies, - unindexedClasses, finalFieldsWritable, reflectiveClass, visits); + unindexedClasses, reflectiveClass, visits); } for (ClassInfo subclass : combinedIndexBuildItem.getIndex().getAllKnownImplementors(type.name())) { addClassTypeHierarchy(combinedIndexBuildItem, capabilities, reflectiveHierarchyBuildItem, newSource, subclass.name(), subclass.name(), processedReflectiveHierarchies, - unindexedClasses, finalFieldsWritable, reflectiveClass, visits); + unindexedClasses, reflectiveClass, visits); } } else if (type instanceof ArrayType) { visits.addLast(() -> addReflectiveHierarchy(combinedIndexBuildItem, capabilities, reflectiveHierarchyBuildItem, newSource, type.asArrayType().constituent(), processedReflectiveHierarchies, - unindexedClasses, finalFieldsWritable, reflectiveClass, visits)); + unindexedClasses, reflectiveClass, visits)); } else if (type instanceof ParameterizedType) { if (!reflectiveHierarchyBuildItem.getIgnoreTypePredicate().test(type.name())) { addClassTypeHierarchy(combinedIndexBuildItem, capabilities, reflectiveHierarchyBuildItem, newSource, type.name(), type.name(), processedReflectiveHierarchies, - unindexedClasses, finalFieldsWritable, reflectiveClass, visits); + unindexedClasses, reflectiveClass, visits); } final ParameterizedType parameterizedType = (ParameterizedType) type; for (Type typeArgument : parameterizedType.arguments()) { @@ -187,7 +175,7 @@ private void addReflectiveHierarchy(CombinedIndexBuildItem combinedIndexBuildIte newSource, typeArgument, processedReflectiveHierarchies, - unindexedClasses, finalFieldsWritable, reflectiveClass, visits)); + unindexedClasses, reflectiveClass, visits)); } } } @@ -199,7 +187,6 @@ private void addClassTypeHierarchy(CombinedIndexBuildItem combinedIndexBuildItem DotName initialName, Set processedReflectiveHierarchies, Map> unindexedClasses, - Predicate finalFieldsWritable, BuildProducer reflectiveClass, Deque visits) { if (name == null) { @@ -242,7 +229,7 @@ private void addClassTypeHierarchy(CombinedIndexBuildItem combinedIndexBuildItem visits.addLast(() -> addClassTypeHierarchy(combinedIndexBuildItem, capabilities, reflectiveHierarchyBuildItem, source, info.superName(), initialName, processedReflectiveHierarchies, - unindexedClasses, finalFieldsWritable, reflectiveClass, visits)); + unindexedClasses, reflectiveClass, visits)); for (FieldInfo field : info.fields()) { if (reflectiveHierarchyBuildItem.getIgnoreFieldPredicate().test(field) || // skip the static fields (especially loggers) @@ -256,7 +243,7 @@ private void addClassTypeHierarchy(CombinedIndexBuildItem combinedIndexBuildItem () -> addReflectiveHierarchy(combinedIndexBuildItem, capabilities, reflectiveHierarchyBuildItem, source, fieldType, processedReflectiveHierarchies, - unindexedClasses, finalFieldsWritable, reflectiveClass, visits)); + unindexedClasses, reflectiveClass, visits)); } for (MethodInfo method : info.methods()) { if (reflectiveHierarchyBuildItem.getIgnoreMethodPredicate().test(method) || @@ -270,7 +257,7 @@ private void addClassTypeHierarchy(CombinedIndexBuildItem combinedIndexBuildItem reflectiveHierarchyBuildItem, source, method.returnType(), processedReflectiveHierarchies, - unindexedClasses, finalFieldsWritable, reflectiveClass, visits)); + unindexedClasses, reflectiveClass, visits)); } // for Kotlin classes, we need to register the nested classes as well because companion classes are very often necessary at runtime @@ -279,7 +266,7 @@ private void addClassTypeHierarchy(CombinedIndexBuildItem combinedIndexBuildItem for (DotName memberClassName : info.memberClasses()) { addClassTypeHierarchy(combinedIndexBuildItem, capabilities, reflectiveHierarchyBuildItem, source, memberClassName, memberClassName, processedReflectiveHierarchies, unindexedClasses, - finalFieldsWritable, reflectiveClass, visits); + reflectiveClass, visits); } } } diff --git a/extensions/kotlin/deployment/src/main/java/io/quarkus/kotlin/deployment/KotlinProcessor.java b/extensions/kotlin/deployment/src/main/java/io/quarkus/kotlin/deployment/KotlinProcessor.java index 17ceeb5de7cbe..b613332064790 100644 --- a/extensions/kotlin/deployment/src/main/java/io/quarkus/kotlin/deployment/KotlinProcessor.java +++ b/extensions/kotlin/deployment/src/main/java/io/quarkus/kotlin/deployment/KotlinProcessor.java @@ -11,7 +11,6 @@ import io.quarkus.deployment.builditem.FeatureBuildItem; import io.quarkus.deployment.builditem.nativeimage.NativeImageResourcePatternsBuildItem; import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; -import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassFinalFieldsWritablePredicateBuildItem; import io.quarkus.deployment.builditem.nativeimage.ReflectiveHierarchyIgnoreWarningBuildItem; import io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem; import io.quarkus.jackson.spi.ClassPathJacksonModuleBuildItem; @@ -39,15 +38,6 @@ void registerKotlinJacksonModule(BuildProducer classPathJacksonModules.produce(new ClassPathJacksonModuleBuildItem(KOTLIN_JACKSON_MODULE)); } - /** - * Kotlin data classes that have multiple constructors need to have their final fields writable, - * otherwise creating an instance of them with default values fails in native mode. - */ - @BuildStep - ReflectiveClassFinalFieldsWritablePredicateBuildItem dataClassPredicate() { - return new ReflectiveClassFinalFieldsWritablePredicateBuildItem(new IsDataClassWithDefaultValuesPredicate()); - } - /* * Register the Kotlin reflection types if they are present. */