diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java index aa91b1f495c7e6..1034f43099fa7e 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java @@ -411,6 +411,7 @@ public ConfiguredTarget create(RuleContext ruleContext) ImmutableList deployManifestLines = getDeployManifestLines(ruleContext, originalMainClass); + // Create the java_binary target specific CDS archive. Artifact jsa = createSharedArchive(ruleContext, javaArtifacts, attributes); if (ruleContext.isAttrDefined("hermetic", BOOLEAN) @@ -428,6 +429,13 @@ public ConfiguredTarget create(RuleContext ruleContext) .setLibModules(javaRuntime.libModules()) .setHermeticInputs(javaRuntime.hermeticInputs()); } + + if (jsa == null) { + // Use the JDK default CDS specified by the JavaRuntime if the + // java_binary target specific CDS archive is null, when building + // a hermetic deploy JAR. + jsa = javaRuntime.defaultCDS(); + } } deployArchiveBuilder diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntime.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntime.java index 467d772e6c7ebf..183bb35bd3c670 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntime.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntime.java @@ -99,6 +99,10 @@ public ConfiguredTarget create(RuleContext ruleContext) ImmutableList hermeticStaticLibs = ImmutableList.copyOf(ruleContext.getPrerequisites("hermetic_static_libs", CcInfo.PROVIDER)); + // If a runtime does not set default_cds in hermetic mode, it is not fatal. + // We can skip the default CDS in the check below. + Artifact defaultCDS = ruleContext.getPrerequisiteArtifact("default_cds"); + if ((!hermeticInputs.isEmpty() || libModules != null || !hermeticStaticLibs.isEmpty()) && (hermeticInputs.isEmpty() || libModules == null || hermeticStaticLibs.isEmpty())) { ruleContext.attributeError( @@ -124,6 +128,7 @@ public ConfiguredTarget create(RuleContext ruleContext) javaBinaryRunfilesPath, hermeticInputs, libModules, + defaultCDS, hermeticStaticLibs); TemplateVariableInfo templateVariableInfo = diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeInfo.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeInfo.java index 43e693d1dfde15..5d0cd11f1a9efc 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeInfo.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeInfo.java @@ -51,6 +51,7 @@ public static JavaRuntimeInfo create( PathFragment javaBinaryRunfilesPath, NestedSet hermeticInputs, @Nullable Artifact libModules, + @Nullable Artifact defaultCDS, ImmutableList hermeticStaticLibs) { return new JavaRuntimeInfo( javaBaseInputs, @@ -60,6 +61,7 @@ public static JavaRuntimeInfo create( javaBinaryRunfilesPath, hermeticInputs, libModules, + defaultCDS, hermeticStaticLibs); } @@ -121,6 +123,7 @@ private static JavaRuntimeInfo from(RuleContext ruleContext, ToolchainInfo toolc private final PathFragment javaBinaryRunfilesPath; private final NestedSet hermeticInputs; @Nullable private final Artifact libModules; + @Nullable private final Artifact defaultCDS; private final ImmutableList hermeticStaticLibs; private JavaRuntimeInfo( @@ -131,6 +134,7 @@ private JavaRuntimeInfo( PathFragment javaBinaryRunfilesPath, NestedSet hermeticInputs, @Nullable Artifact libModules, + @Nullable Artifact defaultCDS, ImmutableList hermeticStaticLibs) { this.javaBaseInputs = javaBaseInputs; this.javaHome = javaHome; @@ -139,6 +143,7 @@ private JavaRuntimeInfo( this.javaBinaryRunfilesPath = javaBinaryRunfilesPath; this.hermeticInputs = hermeticInputs; this.libModules = libModules; + this.defaultCDS = defaultCDS; this.hermeticStaticLibs = hermeticStaticLibs; } @@ -199,6 +204,12 @@ public Artifact libModules() { return libModules; } + @Override + @Nullable + public Artifact defaultCDS() { + return defaultCDS; + } + public ImmutableList hermeticStaticLibs() { return hermeticStaticLibs; } diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeRule.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeRule.java index 3d3c49ed3217aa..50a6e5c7fa34b1 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeRule.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeRule.java @@ -55,6 +55,18 @@ public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) .singleArtifact() .allowedFileTypes(FileTypeSet.ANY_FILE) .exec()) + /* + Default CDS archive for hermetic java_runtime. When hermetic + is enabled for a java_binary target and if the target does not + provide its own CDS archive by specifying the + classlist attribute, + the java_runtime default CDS is packaged in the hermetic deploy JAR. + */ + .add( + attr("default_cds", LABEL) + .singleArtifact() + .allowedFileTypes(FileTypeSet.ANY_FILE) + .exec()) .add( attr("hermetic_static_libs", LABEL_LIST) .mandatoryProviders(StarlarkProviderIdentifier.forKey(CcInfo.PROVIDER.getKey())) diff --git a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/java/JavaRuntimeInfoApi.java b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/java/JavaRuntimeInfoApi.java index aa195cfe367238..73c791dfb921db 100644 --- a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/java/JavaRuntimeInfoApi.java +++ b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/java/JavaRuntimeInfoApi.java @@ -89,6 +89,15 @@ public interface JavaRuntimeInfoApi extends StructApi { @Nullable FileApi libModules(); + /** The JDK default CDS. */ + @StarlarkMethod( + name = "default_cds", + doc = "Returns the JDK default CDS archive.", + structField = true, + allowReturnNones = true) + @Nullable + FileApi defaultCDS(); + /** The JDK static libraries needed for hermetic deployments. */ @StarlarkMethod( name = "hermetic_static_libs", diff --git a/src/main/starlark/builtins_bzl/common/java/java_binary_deploy_jar.bzl b/src/main/starlark/builtins_bzl/common/java/java_binary_deploy_jar.bzl index cf0e98d29d2ee3..6751616c1e9831 100644 --- a/src/main/starlark/builtins_bzl/common/java/java_binary_deploy_jar.bzl +++ b/src/main/starlark/builtins_bzl/common/java/java_binary_deploy_jar.bzl @@ -181,10 +181,6 @@ def _create_deploy_archive( if one_version_level == "WARNING": args.add("--succeed_on_found_violations") - if shared_archive: - input_files.append(shared_archive) - args.add("--cds_archive", shared_archive) - if multi_release: args.add("--multi_release") @@ -197,6 +193,13 @@ def _create_deploy_archive( args.add_all("--resources", hermetic_files) input_files.append(lib_modules) + if shared_archive == None: + shared_archive = runtime.default_cds + + if shared_archive: + input_files.append(shared_archive) + args.add("--cds_archive", shared_archive) + args.add_all("--add_exports", add_exports) args.add_all("--add_opens", add_opens) diff --git a/src/test/java/com/google/devtools/build/lib/rules/java/JavaRuntimeInfoTest.java b/src/test/java/com/google/devtools/build/lib/rules/java/JavaRuntimeInfoTest.java index 509f7b50d3b1e5..60cf66d994585d 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/java/JavaRuntimeInfoTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/java/JavaRuntimeInfoTest.java @@ -37,6 +37,7 @@ public void equalityIsObjectIdentity() { PathFragment.create(""), NestedSetBuilder.emptySet(Order.STABLE_ORDER), null, + null, ImmutableList.of()); JavaRuntimeInfo b = JavaRuntimeInfo.create( @@ -47,6 +48,7 @@ public void equalityIsObjectIdentity() { PathFragment.create(""), NestedSetBuilder.emptySet(Order.STABLE_ORDER), null, + null, ImmutableList.of()); new EqualsTester().addEqualityGroup(a).addEqualityGroup(b).testEquals();