From 7df558a3022d790e11d14caf58bdd1947712c4a9 Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Mon, 29 Nov 2021 16:49:36 +0200 Subject: [PATCH] Export sun.security.internal.spec module for bouncycastle in Java 17 Closes: https://github.com/quarkusio/quarkus/issues/21374 --- .../nativeimage/JPMSExportBuildItem.java | 25 +++++++++++++++++++ .../pkg/steps/NativeImageBuildStep.java | 20 ++++++++++++++- .../deployment/SecurityProcessor.java | 17 +++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/JPMSExportBuildItem.java diff --git a/core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/JPMSExportBuildItem.java b/core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/JPMSExportBuildItem.java new file mode 100644 index 0000000000000..fdba81b6f9724 --- /dev/null +++ b/core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/JPMSExportBuildItem.java @@ -0,0 +1,25 @@ +package io.quarkus.deployment.builditem.nativeimage; + +import io.quarkus.builder.item.MultiBuildItem; + +/** + * A build item that indicates that a Java package should be exported using + * '-J--add-exports' option to become visible to native-image + */ +public final class JPMSExportBuildItem extends MultiBuildItem { + private final String moduleName; + private final String packageName; + + public JPMSExportBuildItem(String moduleName, String packageName) { + this.moduleName = moduleName; + this.packageName = packageName; + } + + public String getPackage() { + return packageName; + } + + public String getModule() { + return moduleName; + } +} 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 4cb38ae1bc341..36f2c84c31766 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 @@ -25,6 +25,7 @@ import io.quarkus.bootstrap.util.IoUtils; import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.builditem.nativeimage.ExcludeConfigBuildItem; +import io.quarkus.deployment.builditem.nativeimage.JPMSExportBuildItem; import io.quarkus.deployment.builditem.nativeimage.NativeImageAllowIncompleteClasspathAggregateBuildItem; import io.quarkus.deployment.builditem.nativeimage.NativeImageSecurityProviderBuildItem; import io.quarkus.deployment.builditem.nativeimage.NativeImageSystemPropertyBuildItem; @@ -86,7 +87,8 @@ ArtifactResultBuildItem nativeSourcesResult(NativeConfig nativeConfig, PackageConfig packageConfig, List nativeImageProperties, List excludeConfigs, - NativeImageAllowIncompleteClasspathAggregateBuildItem incompleteClassPathAllowed) { + NativeImageAllowIncompleteClasspathAggregateBuildItem incompleteClassPathAllowed, + List jpmsExportBuildItems) { Path outputDir; try { @@ -107,6 +109,7 @@ ArtifactResultBuildItem nativeSourcesResult(NativeConfig nativeConfig, .setNativeImageProperties(nativeImageProperties) .setBrokenClasspath(incompleteClassPathAllowed.isAllow()) .setExcludeConfigs(excludeConfigs) + .setJPMSExportBuildItems(jpmsExportBuildItems) .setOutputDir(outputDir) .setRunnerJarName(runnerJar.getFileName().toString()) // the path to native-image is not known now, it is only known at the time the native-sources will be consumed @@ -139,6 +142,7 @@ public NativeImageBuildItem build(NativeConfig nativeConfig, NativeImageSourceJa List excludeConfigs, NativeImageAllowIncompleteClasspathAggregateBuildItem incompleteClassPathAllowed, List nativeImageSecurityProviders, + List jpmsExportBuildItems, Optional processInheritIODisabled) { if (nativeConfig.debug.enabled) { copyJarSourcesToLib(outputTargetBuildItem, curateOutcomeBuildItem); @@ -199,6 +203,7 @@ public NativeImageBuildItem build(NativeConfig nativeConfig, NativeImageSourceJa .setExcludeConfigs(excludeConfigs) .setBrokenClasspath(incompleteClassPathAllowed.isAllow()) .setNativeImageSecurityProviders(nativeImageSecurityProviders) + .setJPMSExportBuildItems(jpmsExportBuildItems) .setOutputDir(outputDir) .setRunnerJarName(runnerJarName) .setNativeImageName(nativeImageName) @@ -473,6 +478,7 @@ static class Builder { private List nativeImageProperties; private List excludeConfigs; private List nativeImageSecurityProviders; + private List jpmsExports; private Path outputDir; private String runnerJarName; private String noPIE = ""; @@ -511,6 +517,11 @@ public Builder setNativeImageSecurityProviders( return this; } + public Builder setJPMSExportBuildItems(List JPMSExportBuildItems) { + this.jpmsExports = JPMSExportBuildItems; + return this; + } + public Builder setOutputDir(Path outputDir) { this.outputDir = outputDir; return this; @@ -723,6 +734,13 @@ public NativeImageInvokerInfo build() { nativeImageArgs.add("-H:AdditionalSecurityProviders=" + additionalSecurityProviders); } + if (jpmsExports != null) { + for (JPMSExportBuildItem jpmsExport : jpmsExports) { + nativeImageArgs.add( + "-J--add-exports=" + jpmsExport.getModule() + "/" + jpmsExport.getPackage() + "=ALL-UNNAMED"); + } + } + for (ExcludeConfigBuildItem excludeConfig : excludeConfigs) { nativeImageArgs.add("--exclude-config"); nativeImageArgs.add(excludeConfig.getJarFile()); diff --git a/extensions/security/deployment/src/main/java/io/quarkus/security/deployment/SecurityProcessor.java b/extensions/security/deployment/src/main/java/io/quarkus/security/deployment/SecurityProcessor.java index 6efddb558842a..657a8f65f898a 100644 --- a/extensions/security/deployment/src/main/java/io/quarkus/security/deployment/SecurityProcessor.java +++ b/extensions/security/deployment/src/main/java/io/quarkus/security/deployment/SecurityProcessor.java @@ -42,6 +42,7 @@ import io.quarkus.deployment.annotations.Record; import io.quarkus.deployment.builditem.ApplicationClassPredicateBuildItem; import io.quarkus.deployment.builditem.FeatureBuildItem; +import io.quarkus.deployment.builditem.nativeimage.JPMSExportBuildItem; import io.quarkus.deployment.builditem.nativeimage.NativeImageSecurityProviderBuildItem; import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; import io.quarkus.deployment.builditem.nativeimage.RuntimeReinitializedClassBuildItem; @@ -242,6 +243,22 @@ void addBouncyCastleProvidersToNativeImage(BuildProducer jpmsExports, + List bouncyCastleProviders, + List bouncyCastleJsseProviders) { + Optional bouncyCastleJsseProvider = getOne(bouncyCastleJsseProviders); + if (bouncyCastleJsseProvider.isPresent() && bouncyCastleJsseProvider.get().isInFipsMode()) { + jpmsExports.produce(new JPMSExportBuildItem("java.base", "sun.security.internal.spec")); + } else { + Optional bouncyCastleProvider = getOne(bouncyCastleProviders); + if (bouncyCastleProvider.isPresent() && bouncyCastleProvider.get().isInFipsMode()) { + jpmsExports.produce(new JPMSExportBuildItem("java.base", "sun.security.internal.spec")); + } + } + } + private Optional getOne(List items) { if (items.size() > 1) { throw new IllegalStateException("Only a single Bouncy Castle registration can be provided.");