From 4914d08055219b95162ca327409a5328ed8409f1 Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Fri, 31 Mar 2023 11:56:10 +0300 Subject: [PATCH] Port NativeConfig to @ConfigMapping --- .../quarkus/deployment/pkg/NativeConfig.java | 194 ++++++++--------- .../NativeImageBuildContainerRunner.java | 6 +- ...NativeImageBuildRemoteContainerRunner.java | 2 +- .../pkg/steps/NativeImageBuildStep.java | 74 +++---- .../pkg/steps/UpxCompressionBuildStep.java | 12 +- .../deployment/steps/LocaleProcessor.java | 24 +- .../steps/NativeImageResourcesStep.java | 4 +- .../deployment/pkg/NativeConfigTest.java | 6 +- .../deployment/pkg/TestNativeConfig.java | 206 ++++++++++++++++++ .../NativeImageBuildContainerRunnerTest.java | 11 +- 10 files changed, 365 insertions(+), 174 deletions(-) create mode 100644 core/deployment/src/test/java/io/quarkus/deployment/pkg/TestNativeConfig.java 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 d971fdfc9122ab..8403c010b874ba 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 @@ -5,16 +5,19 @@ import java.util.Optional; import java.util.OptionalInt; +import io.quarkus.runtime.annotations.ConfigDocDefault; import io.quarkus.runtime.annotations.ConfigGroup; -import io.quarkus.runtime.annotations.ConfigItem; import io.quarkus.runtime.annotations.ConfigPhase; import io.quarkus.runtime.annotations.ConfigRoot; -import io.quarkus.runtime.annotations.ConvertWith; import io.quarkus.runtime.configuration.TrimmedStringConverter; import io.quarkus.runtime.util.ContainerRuntimeUtil; +import io.smallrye.config.ConfigMapping; +import io.smallrye.config.WithConverter; +import io.smallrye.config.WithDefault; @ConfigRoot(phase = ConfigPhase.BUILD_TIME) -public class NativeConfig { +@ConfigMapping(prefix = "quarkus.native") +public interface NativeConfig { public static final String DEFAULT_GRAALVM_BUILDER_IMAGE = "quay.io/quarkus/ubi-quarkus-graalvmce-builder-image:22.3-java17"; public static final String DEFAULT_MANDREL_BUILDER_IMAGE = "quay.io/quarkus/ubi-quarkus-mandrel-builder-image:22.3-java17"; @@ -23,29 +26,28 @@ public class NativeConfig { * Comma-separated, additional arguments to pass to the build process. * If an argument includes the {@code ,} symbol, it needs to be escaped, e.g. {@code \\,} */ - @ConfigItem - public Optional> additionalBuildArgs; + Optional> additionalBuildArgs(); /** * If the HTTP url handler should be enabled, allowing you to do URL.openConnection() for HTTP URLs */ - @ConfigItem(defaultValue = "true") - public boolean enableHttpUrlHandler; + @WithDefault("true") + boolean enableHttpUrlHandler(); /** * If the HTTPS url handler should be enabled, allowing you to do URL.openConnection() for HTTPS URLs */ - @ConfigItem - public boolean enableHttpsUrlHandler; + @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 */ - @ConfigItem + @WithDefault("false") @Deprecated - public boolean enableAllSecurityServices; + boolean enableAllSecurityServices(); /** * If {@code -H:+InlineBeforeAnalysis} flag will be added to the native-image run @@ -53,22 +55,22 @@ public class NativeConfig { * @deprecated inlineBeforeAnalysis is always enabled starting from GraalVM 21.3. */ @Deprecated - @ConfigItem(defaultValue = "true") - public boolean inlineBeforeAnalysis; + @WithDefault("true") + boolean inlineBeforeAnalysis(); /** * @deprecated JNI is always enabled starting from GraalVM 19.3.1. */ @Deprecated - @ConfigItem(defaultValue = "true") - public boolean enableJni; + @WithDefault("true") + boolean enableJni(); /** * The default value for java.awt.headless JVM option. * Switching this option affects linking of awt libraries. */ - @ConfigItem(defaultValue = "true") - public boolean headless; + @WithDefault("true") + boolean headless(); /** * Defines the user language used for building the native executable. @@ -78,10 +80,9 @@ public class NativeConfig { * * @deprecated Use the global quarkus.default-locale. */ - @ConfigItem - @ConvertWith(TrimmedStringConverter.class) + @WithConverter(TrimmedStringConverter.class) @Deprecated - public Optional userLanguage; + Optional userLanguage(); /** * Defines the user country used for building the native executable. @@ -91,10 +92,9 @@ public class NativeConfig { * * @deprecated Use the global quarkus.default-locale. */ - @ConfigItem - @ConvertWith(TrimmedStringConverter.class) + @WithConverter(TrimmedStringConverter.class) @Deprecated - public Optional userCountry; + Optional userCountry(); /** * Defines the file encoding as in {@code -Dfile.encoding=...}. @@ -104,46 +104,45 @@ public class NativeConfig { * defaults to be picked up which can then result in inconsistent behavior in the * generated native executable. */ - @ConfigItem(defaultValue = "UTF-8") - @ConvertWith(TrimmedStringConverter.class) - public String fileEncoding; + @WithDefault("UTF-8") + @WithConverter(TrimmedStringConverter.class) + String fileEncoding(); /** * If all character sets should be added to the native image. This increases image size */ - @ConfigItem - public boolean addAllCharsets; + @WithDefault("false") + boolean addAllCharsets(); /** * The location of the Graal distribution */ - @ConfigItem(defaultValue = "${GRAALVM_HOME:}") - public Optional graalvmHome; + @WithDefault("${GRAALVM_HOME:}") + Optional graalvmHome(); /** * The location of the JDK */ - @ConfigItem(defaultValue = "${java.home}") - public File javaHome; + @WithDefault("${java.home}") + File javaHome(); /** * The maximum Java heap to be used during the native image generation */ - @ConfigItem - public Optional nativeImageXmx; + Optional nativeImageXmx(); /** * If the native image build should wait for a debugger to be attached before running. This is an advanced option * and is generally only intended for those familiar with GraalVM internals */ - @ConfigItem - public boolean debugBuildProcess; + @WithDefault("false") + boolean debugBuildProcess(); /** * If the debug port should be published when building with docker and debug-build-process is true */ - @ConfigItem(defaultValue = "true") - public boolean publishDebugBuildProcessPort; + @WithDefault("true") + boolean publishDebugBuildProcessPort(); /** * If the native image server should be restarted. @@ -152,21 +151,21 @@ public class NativeConfig { * default. */ @Deprecated - @ConfigItem - public boolean cleanupServer; + @WithDefault("false") + boolean cleanupServer(); /** * If isolates should be enabled */ - @ConfigItem(defaultValue = "true") - public boolean enableIsolates; + @WithDefault("true") + boolean enableIsolates(); /** * If a JVM based 'fallback image' should be created if native image fails. This is not recommended, as this is * functionally the same as just running the application in a JVM */ - @ConfigItem - public boolean enableFallbackImages; + @WithDefault("false") + boolean enableFallbackImages(); /** * If the native image server should be used. This can speed up compilation but can result in changes not always @@ -177,53 +176,53 @@ public class NativeConfig { * feature. */ @Deprecated - @ConfigItem - public boolean enableServer; + @WithDefault("false") + boolean enableServer(); /** * If all META-INF/services entries should be automatically registered */ - @ConfigItem - public boolean autoServiceLoaderRegistration; + @WithDefault("false") + boolean autoServiceLoaderRegistration(); /** * If the bytecode of all proxies should be dumped for inspection */ - @ConfigItem - public boolean dumpProxies; + @WithDefault("false") + boolean dumpProxies(); /** * If this build should be done using a container runtime. Unless container-runtime is also set, docker will be * used by default. If docker is not available or is an alias to podman, podman will be used instead as the default. */ - @ConfigItem - public Optional containerBuild; + Optional containerBuild(); /** * If this build is done using a remote docker daemon. */ - @ConfigItem - public boolean remoteContainerBuild; + @WithDefault("false") + boolean remoteContainerBuild(); - public boolean isContainerBuild() { - return containerBuild.orElse(containerRuntime.isPresent() || remoteContainerBuild); + default boolean isContainerBuild() { + return containerBuild().orElse(containerRuntime().isPresent() || remoteContainerBuild()); } /** * The docker image to use to do the image build. It can be one of `graalvm`, `mandrel`, or the full image path, e.g. * {@code quay.io/quarkus/ubi-quarkus-mandrel-builder-image:22.3-java17}. */ - @ConfigItem(defaultValue = "${platform.quarkus.native.builder-image}", defaultValueDocumentation = "mandrel") - public String builderImage; + @WithDefault("${platform.quarkus.native.builder-image}") + @ConfigDocDefault("mandrel") + String builderImage(); - public String getEffectiveBuilderImage() { - final String builderImageName = this.builderImage.toUpperCase(); + default String getEffectiveBuilderImage() { + final String builderImageName = this.builderImage().toUpperCase(); if (builderImageName.equals(BuilderImageProvider.GRAALVM.name())) { return DEFAULT_GRAALVM_BUILDER_IMAGE; } else if (builderImageName.equals(BuilderImageProvider.MANDREL.name())) { return DEFAULT_MANDREL_BUILDER_IMAGE; } else { - return this.builderImage; + return this.builderImage(); } } @@ -231,55 +230,52 @@ public String getEffectiveBuilderImage() { * The container runtime (e.g. docker) that is used to do an image based build. If this is set then * a container build is always done. */ - @ConfigItem - public Optional containerRuntime; + Optional containerRuntime(); /** * Options to pass to the container runtime */ - @ConfigItem - public Optional> containerRuntimeOptions; + Optional> containerRuntimeOptions(); /** * If the resulting image should allow VM introspection. * * @deprecated Use {@code quarkus.native.monitoring} instead. */ - @ConfigItem + @WithDefault("false") @Deprecated - public boolean enableVmInspection; + boolean enableVmInspection(); /** * Enable monitoring options that allow the VM to be inspected at run time. */ - @ConfigItem - public Optional> monitoring; + Optional> monitoring(); /** * If full stack traces are enabled in the resulting image */ - @ConfigItem(defaultValue = "true") - public boolean fullStackTraces; + @WithDefault("true") + boolean fullStackTraces(); /** * If the reports on call paths and included packages/classes/methods should be generated */ - @ConfigItem - public boolean enableReports; + @WithDefault("false") + boolean enableReports(); /** * If exceptions should be reported with a full stack trace */ - @ConfigItem(defaultValue = "true") - public boolean reportExceptionStackTraces; + @WithDefault("true") + boolean reportExceptionStackTraces(); /** * If errors should be reported at runtime. This is a more relaxed setting, however it is not recommended as it * means * your application may fail at runtime if an unsupported feature is used by accident. */ - @ConfigItem - public boolean reportErrorsAtRuntime; + @WithDefault("false") + boolean reportErrorsAtRuntime(); /** * Don't build a native image if it already exists. @@ -289,17 +285,15 @@ public String getEffectiveBuilderImage() { * Note that this is not able to detect if the existing image is outdated, if you have modified source * or config and want a new image you must not use this flag. */ - @ConfigItem(defaultValue = "false") - public boolean reuseExisting; + @WithDefault("false") + boolean reuseExisting(); /** * Build time configuration options for resources inclusion in the native executable. */ - @ConfigItem - public ResourcesConfig resources; + ResourcesConfig resources(); - @ConfigGroup - public static class ResourcesConfig { + interface ResourcesConfig { /** * A comma separated list of globs to match resource paths that should be added to the native image. @@ -376,8 +370,7 @@ public static class ResourcesConfig { * Note that Quarkus extensions typically include the resources they require by themselves. This option is * useful in situations when the built-in functionality is not sufficient. */ - @ConfigItem - public Optional> includes; + Optional> includes(); /** * A comma separated list of globs to match resource paths that should not be added to the native image. @@ -400,48 +393,44 @@ public static class ResourcesConfig { * the resource {@code red.png} will be available in the native image while the resources {@code foo/green.png} * and {@code bar/blue.png} will not be available in the native image. */ - @ConfigItem - public Optional> excludes; + Optional> excludes(); } /** * Debugging options. */ - @ConfigItem - public Debug debug; + Debug debug(); @ConfigGroup - public static class Debug { + interface Debug { /** * If debug is enabled and debug symbols are generated. * The symbols will be generated in a separate .debug file. */ - @ConfigItem - public boolean enabled; + @WithDefault("false") + boolean enabled(); } /** * Generate the report files for GraalVM Dashboard. */ - @ConfigItem - public boolean enableDashboardDump; + @WithDefault("false") + boolean enableDashboardDump(); /** * Configure native executable compression using UPX. */ - @ConfigItem - public Compression compression; + Compression compression(); @ConfigGroup - public static class Compression { + interface Compression { /** * The compression level in [1, 10]. * 10 means best * * Higher compression level requires more time to compress the executable. */ - @ConfigItem - public OptionalInt level; + OptionalInt level(); /** * Allows passing extra arguments to the UPX command line (like --brute). @@ -450,19 +439,18 @@ public static class Compression { * The exhaustive list of parameters can be found in * https://github.com/upx/upx/blob/devel/doc/upx.pod. */ - @ConfigItem - public Optional> additionalArgs; + Optional> additionalArgs(); } /** * Supported Builder Image providers/distributions */ - public static enum BuilderImageProvider { + enum BuilderImageProvider { GRAALVM, MANDREL; } - public enum MonitoringOption { + enum MonitoringOption { HEAPDUMP, JVMSTAT, JFR, diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildContainerRunner.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildContainerRunner.java index a07ad75490fa75..a3b02f74494a59 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildContainerRunner.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildContainerRunner.java @@ -29,7 +29,7 @@ public abstract class NativeImageBuildContainerRunner extends NativeImageBuildRu public NativeImageBuildContainerRunner(NativeConfig nativeConfig, Path outputDir) { this.nativeConfig = nativeConfig; - containerRuntime = nativeConfig.containerRuntime.orElseGet(ContainerRuntimeUtil::detectContainerRuntime); + containerRuntime = nativeConfig.containerRuntime().orElseGet(ContainerRuntimeUtil::detectContainerRuntime); log.infof("Using %s to run the native image builder", containerRuntime.getExecutableName()); this.baseContainerRuntimeArgs = new String[] { "--env", "LANG=C", "--rm" }; @@ -109,8 +109,8 @@ public void addShutdownHook(Process process) { protected List getContainerRuntimeBuildArgs() { List containerRuntimeArgs = new ArrayList<>(); - nativeConfig.containerRuntimeOptions.ifPresent(containerRuntimeArgs::addAll); - if (nativeConfig.debugBuildProcess && nativeConfig.publishDebugBuildProcessPort) { + nativeConfig.containerRuntimeOptions().ifPresent(containerRuntimeArgs::addAll); + if (nativeConfig.debugBuildProcess() && nativeConfig.publishDebugBuildProcessPort()) { // publish the debug port onto the host if asked for containerRuntimeArgs.add("--publish=" + NativeImageBuildStep.DEBUG_BUILD_PROCESS_PORT + ":" + NativeImageBuildStep.DEBUG_BUILD_PROCESS_PORT); diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildRemoteContainerRunner.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildRemoteContainerRunner.java index f427ca4c5268b2..12001521834e4c 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildRemoteContainerRunner.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildRemoteContainerRunner.java @@ -61,7 +61,7 @@ private String runCommandAndReadOutput(String[] command, String errorMsg) throws @Override protected void postBuild() { copyFromContainerVolume(resultingExecutableName, "Failed to copy native image from container volume back to the host."); - if (nativeConfig.debug.enabled) { + if (nativeConfig.debug().enabled()) { copyFromContainerVolume("sources", "Failed to copy sources from container volume back to the host."); String symbols = String.format("%s.debug", nativeImageName); copyFromContainerVolume(symbols, "Failed to copy debug symbols from container volume back to the host."); 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 396e3adf003e17..6dd31056752a39 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 @@ -176,7 +176,7 @@ public NativeImageBuildItem build(NativeConfig nativeConfig, LocalesBuildTimeCon Optional processInheritIODisabled, Optional processInheritIODisabledBuildItem, List nativeImageFeatures) { - if (nativeConfig.debug.enabled) { + if (nativeConfig.debug().enabled()) { copyJarSourcesToLib(outputTargetBuildItem, curateOutcomeBuildItem); copySourcesToSourceCache(outputTargetBuildItem); } @@ -198,7 +198,7 @@ public NativeImageBuildItem build(NativeConfig nativeConfig, LocalesBuildTimeCon String resultingExecutableName = getResultingExecutableName(nativeImageName, isContainerBuild); Path generatedExecutablePath = outputDir.resolve(resultingExecutableName); Path finalExecutablePath = outputTargetBuildItem.getOutputDirectory().resolve(resultingExecutableName); - if (nativeConfig.reuseExisting) { + if (nativeConfig.reuseExisting()) { if (Files.exists(finalExecutablePath)) { return new NativeImageBuildItem(finalExecutablePath, NativeImageBuildItem.GraalVMVersion.unknown()); @@ -217,7 +217,7 @@ public NativeImageBuildItem build(NativeConfig nativeConfig, LocalesBuildTimeCon } try { - if (nativeConfig.cleanupServer) { + 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" @@ -249,14 +249,14 @@ public NativeImageBuildItem build(NativeConfig nativeConfig, LocalesBuildTimeCon NativeImageBuildRunner.Result buildNativeResult = buildRunner.build(nativeImageArgs, nativeImageName, resultingExecutableName, outputDir, - graalVMVersion, nativeConfig.debug.enabled, + graalVMVersion, nativeConfig.debug().enabled(), processInheritIODisabled.isPresent() || processInheritIODisabledBuildItem.isPresent()); if (buildNativeResult.getExitCode() != 0) { throw imageGenerationFailed(buildNativeResult.getExitCode(), nativeConfig.isContainerBuild()); } IoUtils.copy(generatedExecutablePath, finalExecutablePath); Files.delete(generatedExecutablePath); - if (nativeConfig.debug.enabled) { + if (nativeConfig.debug().enabled()) { final String symbolsName = String.format("%s.debug", nativeImageName); Path generatedSymbols = outputDir.resolve(symbolsName); if (generatedSymbols.toFile().exists()) { @@ -277,7 +277,7 @@ public NativeImageBuildItem build(NativeConfig nativeConfig, LocalesBuildTimeCon } catch (Exception e) { throw new RuntimeException("Failed to build native image", e); } finally { - if (nativeConfig.debug.enabled) { + if (nativeConfig.debug().enabled()) { removeJarSourcesFromLib(outputTargetBuildItem); IoUtils.recursiveDelete(outputDir.resolve(Paths.get(APP_SOURCES))); } @@ -312,7 +312,7 @@ private static NativeImageBuildRunner getNativeImageBuildRunner(NativeConfig nat } log.warn(errorMessage + " Attempting to fall back to container build."); } - if (nativeConfig.remoteContainerBuild) { + if (nativeConfig.remoteContainerBuild()) { return new NativeImageBuildRemoteContainerRunner(nativeConfig, outputDir, nativeImageName, resultingExecutableName); } @@ -426,14 +426,14 @@ private void checkGraalVMVersion(GraalVM.Version version) { private static NativeImageBuildLocalRunner getNativeImageBuildLocalRunner(NativeConfig nativeConfig, File outputDir) { String executableName = getNativeImageExecutableName(); - if (nativeConfig.graalvmHome.isPresent()) { - File file = Paths.get(nativeConfig.graalvmHome.get(), "bin", executableName).toFile(); + if (nativeConfig.graalvmHome().isPresent()) { + File file = Paths.get(nativeConfig.graalvmHome().get(), "bin", executableName).toFile(); if (file.exists()) { return new NativeImageBuildLocalRunner(file.getAbsolutePath(), outputDir); } } - File javaHome = nativeConfig.javaHome; + File javaHome = nativeConfig.javaHome(); if (javaHome == null) { // try system property first - it will be the JAVA_HOME used by the current JVM String home = System.getProperty(JAVA_HOME_SYS); @@ -620,9 +620,9 @@ public Builder setNativeImageName(String nativeImageName) { public NativeImageInvokerInfo build() { List nativeImageArgs = new ArrayList<>(); boolean enableSslNative = false; - boolean inlineBeforeAnalysis = nativeConfig.inlineBeforeAnalysis; - boolean addAllCharsets = nativeConfig.addAllCharsets; - boolean enableHttpsUrlHandler = nativeConfig.enableHttpsUrlHandler; + boolean inlineBeforeAnalysis = nativeConfig.inlineBeforeAnalysis(); + boolean addAllCharsets = nativeConfig.addAllCharsets(); + boolean enableHttpsUrlHandler = nativeConfig.enableHttpsUrlHandler(); for (NativeImageSystemPropertyBuildItem prop : nativeImageProperties) { //todo: this should be specific build items if (prop.getKey().equals("quarkus.ssl.native") && prop.getValue() != null) { @@ -663,7 +663,7 @@ public NativeImageInvokerInfo build() { nativeImageArgs.add("-H:IncludeLocales=" + includeLocales); } - nativeImageArgs.add("-J-Dfile.encoding=" + nativeConfig.fileEncoding); + nativeImageArgs.add("-J-Dfile.encoding=" + nativeConfig.fileEncoding()); if (enableSslNative) { enableHttpsUrlHandler = true; @@ -694,7 +694,7 @@ public NativeImageInvokerInfo build() { nativeImageArgs.add("-H:-ParseOnce"); } - if (nativeConfig.debug.enabled && graalVMVersion.compareTo(GraalVM.Version.VERSION_23_0_0) >= 0) { + if (nativeConfig.debug().enabled() && graalVMVersion.compareTo(GraalVM.Version.VERSION_23_0_0) >= 0) { /* * Instruct GraalVM / Mandrel to keep more accurate information about source locations when generating * debug info for debugging and monitoring tools. This parameter may break compatibility with Truffle. @@ -724,7 +724,7 @@ public NativeImageInvokerInfo build() { // required by camel-quarkus-xstream nativeImageArgs.add("-J--add-opens=java.base/java.util=ALL-UNNAMED"); - if (nativeConfig.enableReports) { + if (nativeConfig.enableReports()) { nativeImageArgs.add("-H:PrintAnalysisCallTreeType=CSV"); } @@ -749,11 +749,11 @@ public NativeImageInvokerInfo build() { nativeImageArgs.add("-H:+AllowFoldMethods"); - if (nativeConfig.headless) { + if (nativeConfig.headless()) { nativeImageArgs.add("-J-Djava.awt.headless=true"); } - if (nativeConfig.enableFallbackImages) { + if (nativeConfig.enableFallbackImages()) { nativeImageArgs.add("--auto-fallback"); } else { //Default: be strict as those fallback images aren't very useful @@ -765,17 +765,17 @@ public NativeImageInvokerInfo build() { nativeImageArgs.add("--link-at-build-time"); } - if (nativeConfig.reportErrorsAtRuntime) { + if (nativeConfig.reportErrorsAtRuntime()) { nativeImageArgs.add("--report-unsupported-elements-at-runtime"); } - if (nativeConfig.reportExceptionStackTraces) { + if (nativeConfig.reportExceptionStackTraces()) { nativeImageArgs.add("-H:+ReportExceptionStackTraces"); } - if (nativeConfig.debug.enabled) { + if (nativeConfig.debug().enabled()) { nativeImageArgs.add("-g"); nativeImageArgs.add("-H:DebugInfoSourceSearchPath=" + APP_SOURCES); } - if (nativeConfig.debugBuildProcess) { + if (nativeConfig.debugBuildProcess()) { String debugBuildProcessHost; if (nativeConfig.isContainerBuild()) { debugBuildProcessHost = "0.0.0.0"; @@ -786,14 +786,14 @@ public NativeImageInvokerInfo build() { .add("-J-Xrunjdwp:transport=dt_socket,address=" + debugBuildProcessHost + ":" + DEBUG_BUILD_PROCESS_PORT + ",server=y,suspend=y"); } - if (nativeConfig.dumpProxies) { + if (nativeConfig.dumpProxies()) { nativeImageArgs.add("-Dsun.misc.ProxyGenerator.saveGeneratedFiles=true"); } - if (nativeConfig.nativeImageXmx.isPresent()) { - nativeImageArgs.add("-J-Xmx" + nativeConfig.nativeImageXmx.get()); + if (nativeConfig.nativeImageXmx().isPresent()) { + nativeImageArgs.add("-J-Xmx" + nativeConfig.nativeImageXmx().get()); } List protocols = new ArrayList<>(2); - if (nativeConfig.enableHttpUrlHandler) { + if (nativeConfig.enableHttpUrlHandler()) { protocols.add("http"); } if (enableHttpsUrlHandler) { @@ -814,47 +814,47 @@ public NativeImageInvokerInfo build() { nativeImageArgs.add("-H:NativeLinkerOption=" + noPIE); } - if (!nativeConfig.enableIsolates) { + if (!nativeConfig.enableIsolates()) { nativeImageArgs.add("-H:-SpawnIsolates"); } - if (!nativeConfig.enableJni) { + 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) { + 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) { + if (nativeConfig.enableVmInspection()) { nativeImageArgs.add("-H:+AllowVMInspection"); } - if (nativeConfig.monitoring.isPresent()) { - List monitoringOptions = nativeConfig.monitoring.get(); + if (nativeConfig.monitoring().isPresent()) { + List monitoringOptions = nativeConfig.monitoring().get(); if (!monitoringOptions.isEmpty()) { nativeImageArgs.add("--enable-monitoring=" + monitoringOptions.stream() .map(o -> o.name().toLowerCase(Locale.ROOT)).collect(Collectors.joining(","))); } } - if (nativeConfig.autoServiceLoaderRegistration) { + if (nativeConfig.autoServiceLoaderRegistration()) { nativeImageArgs.add("-H:+UseServiceLoaderFeature"); //When enabling, at least print what exactly is being added: nativeImageArgs.add("-H:+TraceServiceLoaderFeature"); } else { nativeImageArgs.add("-H:-UseServiceLoaderFeature"); } - if (nativeConfig.fullStackTraces) { + if (nativeConfig.fullStackTraces()) { nativeImageArgs.add("-H:+StackTrace"); } else { nativeImageArgs.add("-H:-StackTrace"); } - if (nativeConfig.enableDashboardDump) { + if (nativeConfig.enableDashboardDump()) { nativeImageArgs.add("-H:DashboardDump=" + outputTargetBuildItem.getBaseName() + "_dashboard.dump"); nativeImageArgs.add("-H:+DashboardAll"); } @@ -922,8 +922,8 @@ public NativeImageInvokerInfo build() { } private void handleAdditionalProperties(List command) { - if (nativeConfig.additionalBuildArgs.isPresent()) { - List strings = nativeConfig.additionalBuildArgs.get(); + if (nativeConfig.additionalBuildArgs().isPresent()) { + List strings = nativeConfig.additionalBuildArgs().get(); for (String buildArg : strings) { String trimmedBuildArg = buildArg.trim(); if (trimmedBuildArg.contains(TRUST_STORE_SYSTEM_PROPERTY_MARKER) && nativeConfig.isContainerBuild()) { diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/UpxCompressionBuildStep.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/UpxCompressionBuildStep.java index ebaa5e4586c5da..e9622d840ae55c 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/UpxCompressionBuildStep.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/UpxCompressionBuildStep.java @@ -37,7 +37,7 @@ public class UpxCompressionBuildStep { public void compress(NativeConfig nativeConfig, NativeImageBuildItem image, BuildProducer upxCompressedProducer, BuildProducer artifactResultProducer) { - if (nativeConfig.compression.level.isEmpty()) { + if (nativeConfig.compression().level().isEmpty()) { log.debug("UPX compression disabled"); return; } @@ -64,8 +64,8 @@ public void compress(NativeConfig nativeConfig, NativeImageBuildItem image, } private boolean runUpxFromHost(File upx, File executable, NativeConfig nativeConfig) { - String level = getCompressionLevel(nativeConfig.compression.level.getAsInt()); - List extraArgs = nativeConfig.compression.additionalArgs.orElse(Collections.emptyList()); + String level = getCompressionLevel(nativeConfig.compression().level().getAsInt()); + List extraArgs = nativeConfig.compression().additionalArgs().orElse(Collections.emptyList()); List args = Stream.concat( Stream.concat(Stream.of(upx.getAbsolutePath(), level), extraArgs.stream()), Stream.of(executable.getAbsolutePath())) @@ -98,11 +98,11 @@ private boolean runUpxFromHost(File upx, File executable, NativeConfig nativeCon private boolean runUpxInContainer(NativeImageBuildItem nativeImage, NativeConfig nativeConfig, String effectiveBuilderImage) { - String level = getCompressionLevel(nativeConfig.compression.level.getAsInt()); - List extraArgs = nativeConfig.compression.additionalArgs.orElse(Collections.emptyList()); + String level = getCompressionLevel(nativeConfig.compression().level().getAsInt()); + List extraArgs = nativeConfig.compression().additionalArgs().orElse(Collections.emptyList()); List commandLine = new ArrayList<>(); - ContainerRuntimeUtil.ContainerRuntime containerRuntime = nativeConfig.containerRuntime + ContainerRuntimeUtil.ContainerRuntime containerRuntime = nativeConfig.containerRuntime() .orElseGet(ContainerRuntimeUtil::detectContainerRuntime); commandLine.add(containerRuntime.getExecutableName()); 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 6fadf47324a847..14d9e85ed373b0 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 @@ -74,11 +74,11 @@ public NonDefaultLocale(NativeConfig nativeConfig, LocalesBuildTimeConfig locale @Override public boolean getAsBoolean() { - return (nativeConfig.userLanguage.isPresent() - && !Locale.getDefault().getLanguage().equals(nativeConfig.userLanguage.get())) + return (nativeConfig.userLanguage().isPresent() + && !Locale.getDefault().getLanguage().equals(nativeConfig.userLanguage().get())) || - (nativeConfig.userCountry.isPresent() - && !Locale.getDefault().getCountry().equals(nativeConfig.userCountry.get())) + (nativeConfig.userCountry().isPresent() + && !Locale.getDefault().getCountry().equals(nativeConfig.userCountry().get())) || !Locale.getDefault().equals(localesBuildTimeConfig.defaultLocale) || @@ -96,10 +96,10 @@ public boolean getAsBoolean() { */ public static String nativeImageUserLanguage(NativeConfig nativeConfig, LocalesBuildTimeConfig localesBuildTimeConfig) { String language = localesBuildTimeConfig.defaultLocale.getLanguage(); - if (nativeConfig.userLanguage.isPresent()) { + 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(); + language = nativeConfig.userLanguage().get(); } return language; } @@ -115,10 +115,10 @@ public static String nativeImageUserLanguage(NativeConfig nativeConfig, LocalesB */ public static String nativeImageUserCountry(NativeConfig nativeConfig, LocalesBuildTimeConfig localesBuildTimeConfig) { String country = localesBuildTimeConfig.defaultLocale.getCountry(); - if (nativeConfig.userCountry.isPresent()) { + 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(); + country = nativeConfig.userCountry().get(); } return country; } @@ -136,10 +136,10 @@ public static String nativeImageIncludeLocales(NativeConfig nativeConfig, Locale // We subtract what we already declare for native-image's user.language or user.country. // Note the deprecated options still count. additionalLocales.remove(localesBuildTimeConfig.defaultLocale); - if (nativeConfig.userCountry.isPresent() && nativeConfig.userLanguage.isPresent()) { - additionalLocales.remove(new Locale(nativeConfig.userLanguage.get(), nativeConfig.userCountry.get())); - } else if (nativeConfig.userLanguage.isPresent()) { - additionalLocales.remove(new Locale(nativeConfig.userLanguage.get())); + if (nativeConfig.userCountry().isPresent() && nativeConfig.userLanguage().isPresent()) { + additionalLocales.remove(new Locale(nativeConfig.userLanguage().get(), nativeConfig.userCountry().get())); + } else if (nativeConfig.userLanguage().isPresent()) { + additionalLocales.remove(new Locale(nativeConfig.userLanguage().get())); } return additionalLocales.stream() diff --git a/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageResourcesStep.java b/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageResourcesStep.java index c04a6530167284..f711bc33f42bfd 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageResourcesStep.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageResourcesStep.java @@ -53,8 +53,8 @@ void forwardResourcePatternConfigToBuildItem( NativeConfig nativeConfig, BuildProducer nativeImageResourcePatterns) { - final Optional> includes = nativeConfig.resources.includes; - final Optional> excludes = nativeConfig.resources.excludes; + final Optional> includes = nativeConfig.resources().includes(); + final Optional> excludes = nativeConfig.resources().excludes(); if (includes.isPresent() || excludes.isPresent()) { final Builder builder = NativeImageResourcePatternsBuildItem.builder(); includes.ifPresent(builder::includeGlobs); diff --git a/core/deployment/src/test/java/io/quarkus/deployment/pkg/NativeConfigTest.java b/core/deployment/src/test/java/io/quarkus/deployment/pkg/NativeConfigTest.java index c4b208f6decaa7..4d7456cc786f44 100644 --- a/core/deployment/src/test/java/io/quarkus/deployment/pkg/NativeConfigTest.java +++ b/core/deployment/src/test/java/io/quarkus/deployment/pkg/NativeConfigTest.java @@ -27,9 +27,7 @@ public void testBuilderImageProperlyDetected() { assertThat(createConfig("aRandomString").getEffectiveBuilderImage()).isEqualTo("aRandomString"); } - private NativeConfig createConfig(String configValue) { - NativeConfig nativeConfig = new NativeConfig(); - nativeConfig.builderImage = configValue; - return nativeConfig; + private NativeConfig createConfig(String builderImage) { + return new TestNativeConfig(builderImage); } } 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 new file mode 100644 index 00000000000000..a5e96d95005807 --- /dev/null +++ b/core/deployment/src/test/java/io/quarkus/deployment/pkg/TestNativeConfig.java @@ -0,0 +1,206 @@ +package io.quarkus.deployment.pkg; + +import java.io.File; +import java.util.List; +import java.util.Optional; + +import io.quarkus.runtime.util.ContainerRuntimeUtil; + +public class TestNativeConfig implements NativeConfig { + + private final String builderImage; + + public TestNativeConfig(String builderImage) { + this.builderImage = builderImage; + } + + @Override + public Optional> additionalBuildArgs() { + return Optional.empty(); + } + + @Override + public boolean enableHttpUrlHandler() { + return false; + } + + @Override + 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; + } + + @Override + public Optional userLanguage() { + return Optional.empty(); + } + + @Override + public Optional userCountry() { + return Optional.empty(); + } + + @Override + public String fileEncoding() { + return null; + } + + @Override + public boolean addAllCharsets() { + return false; + } + + @Override + public Optional graalvmHome() { + return Optional.empty(); + } + + @Override + public File javaHome() { + return null; + } + + @Override + public Optional nativeImageXmx() { + return Optional.empty(); + } + + @Override + public boolean debugBuildProcess() { + return false; + } + + @Override + public boolean publishDebugBuildProcessPort() { + return false; + } + + @Override + public boolean cleanupServer() { + return false; + } + + @Override + public boolean enableIsolates() { + return false; + } + + @Override + public boolean enableFallbackImages() { + return false; + } + + @Override + public boolean enableServer() { + return false; + } + + @Override + public boolean autoServiceLoaderRegistration() { + return false; + } + + @Override + public boolean dumpProxies() { + return false; + } + + @Override + public Optional containerBuild() { + return Optional.empty(); + } + + @Override + public boolean remoteContainerBuild() { + return false; + } + + @Override + public String builderImage() { + return builderImage; + } + + @Override + public Optional containerRuntime() { + return Optional.empty(); + } + + @Override + public Optional> containerRuntimeOptions() { + return Optional.empty(); + } + + @Override + public boolean enableVmInspection() { + return false; + } + + @Override + public Optional> monitoring() { + return Optional.empty(); + } + + @Override + public boolean fullStackTraces() { + return false; + } + + @Override + public boolean enableReports() { + return false; + } + + @Override + public boolean reportExceptionStackTraces() { + return false; + } + + @Override + public boolean reportErrorsAtRuntime() { + return false; + } + + @Override + public boolean reuseExisting() { + return false; + } + + @Override + public ResourcesConfig resources() { + return null; + } + + @Override + public Debug debug() { + return null; + } + + @Override + public boolean enableDashboardDump() { + return false; + } + + @Override + public Compression compression() { + return null; + } +} diff --git a/core/deployment/src/test/java/io/quarkus/deployment/pkg/steps/NativeImageBuildContainerRunnerTest.java b/core/deployment/src/test/java/io/quarkus/deployment/pkg/steps/NativeImageBuildContainerRunnerTest.java index 498130d4b71acf..f0a674d26cc5a2 100644 --- a/core/deployment/src/test/java/io/quarkus/deployment/pkg/steps/NativeImageBuildContainerRunnerTest.java +++ b/core/deployment/src/test/java/io/quarkus/deployment/pkg/steps/NativeImageBuildContainerRunnerTest.java @@ -4,12 +4,12 @@ import java.nio.file.Path; import java.util.Collections; -import java.util.Optional; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledIfSystemProperty; import io.quarkus.deployment.pkg.NativeConfig; +import io.quarkus.deployment.pkg.TestNativeConfig; import io.quarkus.runtime.util.ContainerRuntimeUtil; class NativeImageBuildContainerRunnerTest { @@ -20,13 +20,11 @@ class NativeImageBuildContainerRunnerTest { void testBuilderImageBeingPickedUp() { ContainerRuntimeUtil.ContainerRuntime containerRuntime = ContainerRuntimeUtil.detectContainerRuntime(true); - NativeConfig nativeConfig = new NativeConfig(); - nativeConfig.containerRuntime = Optional.empty(); + NativeConfig nativeConfig = new TestNativeConfig("graalvm"); boolean found; NativeImageBuildLocalContainerRunner localRunner; String[] command; - nativeConfig.builderImage = "graalvm"; localRunner = new NativeImageBuildLocalContainerRunner(nativeConfig, Path.of("/tmp")); command = localRunner.buildCommand(containerRuntime.getExecutableName(), Collections.emptyList(), Collections.emptyList()); @@ -39,7 +37,7 @@ void testBuilderImageBeingPickedUp() { } assertThat(found).isTrue(); - nativeConfig.builderImage = "mandrel"; + nativeConfig = new TestNativeConfig("mandrel"); localRunner = new NativeImageBuildLocalContainerRunner(nativeConfig, Path.of("/tmp")); command = localRunner.buildCommand(containerRuntime.getExecutableName(), Collections.emptyList(), Collections.emptyList()); @@ -52,7 +50,7 @@ void testBuilderImageBeingPickedUp() { } assertThat(found).isTrue(); - nativeConfig.builderImage = "RandomString"; + nativeConfig = new TestNativeConfig("RandomString"); localRunner = new NativeImageBuildLocalContainerRunner(nativeConfig, Path.of("/tmp")); command = localRunner.buildCommand(containerRuntime.getExecutableName(), Collections.emptyList(), Collections.emptyList()); @@ -65,4 +63,5 @@ void testBuilderImageBeingPickedUp() { } assertThat(found).isTrue(); } + }