Skip to content

Commit 79badc0

Browse files
cushoncopybara-github
authored andcommitted
Add support for packaging JDK files into deploy jars
PiperOrigin-RevId: 447514841
1 parent c2fd564 commit 79badc0

File tree

11 files changed

+174
-19
lines changed

11 files changed

+174
-19
lines changed

src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaSemantics.java

+8-2
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,10 @@ public CustomCommandLine buildSingleJarCommandLine(
568568
OneVersionEnforcementLevel oneVersionEnforcementLevel,
569569
Artifact oneVersionAllowlistArtifact,
570570
Artifact sharedArchive,
571-
boolean multiReleaseDeployJars) {
571+
boolean multiReleaseDeployJars,
572+
PathFragment javaHome,
573+
Artifact libModules,
574+
NestedSet<Artifact> hermeticInputs) {
572575
return DeployArchiveBuilder.defaultSingleJarCommandLineWithoutOneVersion(
573576
output,
574577
mainClass,
@@ -579,7 +582,10 @@ public CustomCommandLine buildSingleJarCommandLine(
579582
includeBuildData,
580583
compression,
581584
launcher,
582-
/* multiReleaseDeployJars= */ multiReleaseDeployJars)
585+
/* multiReleaseDeployJars= */ multiReleaseDeployJars,
586+
javaHome,
587+
libModules,
588+
hermeticInputs)
583589
.build();
584590
}
585591

src/main/java/com/google/devtools/build/lib/rules/java/DeployArchiveBuilder.java

+44-4
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package com.google.devtools.build.lib.rules.java;
1515

1616
import static com.google.common.collect.ImmutableList.toImmutableList;
17+
import static java.util.Objects.requireNonNull;
1718

1819
import com.google.common.base.Function;
1920
import com.google.common.base.Preconditions;
@@ -30,10 +31,12 @@
3031
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
3132
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
3233
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
34+
import com.google.devtools.build.lib.collect.nestedset.Order;
3335
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
3436
import com.google.devtools.build.lib.packages.TargetUtils;
3537
import com.google.devtools.build.lib.rules.cpp.CppHelper;
3638
import com.google.devtools.build.lib.rules.java.JavaConfiguration.OneVersionEnforcementLevel;
39+
import com.google.devtools.build.lib.vfs.PathFragment;
3740
import java.util.HashSet;
3841
import java.util.Set;
3942
import javax.annotation.Nullable;
@@ -70,6 +73,9 @@ public class DeployArchiveBuilder {
7073
@Nullable private Artifact oneVersionAllowlistArtifact;
7174
@Nullable private Artifact sharedArchive;
7275
private boolean multiReleaseDeployJars;
76+
@Nullable private PathFragment javaHome;
77+
@Nullable private Artifact libModules;
78+
private NestedSet<Artifact> hermeticInputs = NestedSetBuilder.emptySet(Order.STABLE_ORDER);
7379

7480
/** Type of compression to apply to output archive. */
7581
public enum Compression {
@@ -180,6 +186,21 @@ public DeployArchiveBuilder setSharedArchive(@Nullable Artifact sharedArchive) {
180186
return this;
181187
}
182188

189+
public DeployArchiveBuilder setJavaHome(PathFragment javaHome) {
190+
this.javaHome = requireNonNull(javaHome);
191+
return this;
192+
}
193+
194+
public DeployArchiveBuilder setLibModules(@Nullable Artifact libModules) {
195+
this.libModules = libModules;
196+
return this;
197+
}
198+
199+
public DeployArchiveBuilder setHermeticInputs(NestedSet<Artifact> hermeticInputs) {
200+
this.hermeticInputs = requireNonNull(hermeticInputs);
201+
return this;
202+
}
203+
183204
public static CustomCommandLine.Builder defaultSingleJarCommandLineWithoutOneVersion(
184205
Artifact outputJar,
185206
String javaMainClass,
@@ -190,7 +211,10 @@ public static CustomCommandLine.Builder defaultSingleJarCommandLineWithoutOneVer
190211
boolean includeBuildData,
191212
Compression compress,
192213
Artifact launcher,
193-
boolean multiReleaseDeployJars) {
214+
boolean multiReleaseDeployJars,
215+
PathFragment javaHome,
216+
Artifact libModules,
217+
NestedSet<Artifact> hermeticInputs) {
194218
return defaultSingleJarCommandLine(
195219
outputJar,
196220
javaMainClass,
@@ -203,7 +227,10 @@ public static CustomCommandLine.Builder defaultSingleJarCommandLineWithoutOneVer
203227
launcher,
204228
OneVersionEnforcementLevel.OFF,
205229
null,
206-
/* multiReleaseDeployJars= */ multiReleaseDeployJars);
230+
/* multiReleaseDeployJars= */ multiReleaseDeployJars,
231+
javaHome,
232+
libModules,
233+
hermeticInputs);
207234
}
208235

209236
public static CustomCommandLine.Builder defaultSingleJarCommandLine(
@@ -218,7 +245,10 @@ public static CustomCommandLine.Builder defaultSingleJarCommandLine(
218245
Artifact launcher,
219246
OneVersionEnforcementLevel oneVersionEnforcementLevel,
220247
@Nullable Artifact oneVersionAllowlistArtifact,
221-
boolean multiReleaseDeployJars) {
248+
boolean multiReleaseDeployJars,
249+
PathFragment javaHome,
250+
Artifact libModules,
251+
NestedSet<Artifact> hermeticInputs) {
222252

223253
CustomCommandLine.Builder args = CustomCommandLine.builder();
224254
args.addExecPath("--output", outputJar);
@@ -265,6 +295,9 @@ public static CustomCommandLine.Builder defaultSingleJarCommandLine(
265295
if (multiReleaseDeployJars) {
266296
args.add("--multi_release");
267297
}
298+
args.addPath("--hermetic_java_home", javaHome);
299+
args.addExecPath("--jdk_lib_modules", libModules);
300+
args.addExecPaths("--resources", hermeticInputs);
268301
return args;
269302
}
270303

@@ -347,6 +380,10 @@ public void build() throws InterruptedException {
347380
if (sharedArchive != null) {
348381
inputs.add(sharedArchive);
349382
}
383+
inputs.addTransitive(hermeticInputs);
384+
if (libModules != null) {
385+
inputs.add(libModules);
386+
}
350387

351388
Artifact singlejar = JavaToolchainProvider.from(ruleContext).getSingleJar();
352389

@@ -374,7 +411,10 @@ public void build() throws InterruptedException {
374411
oneVersionEnforcementLevel,
375412
oneVersionAllowlistArtifact,
376413
sharedArchive,
377-
/* multiReleaseDeployJars= */ multiReleaseDeployJars);
414+
/* multiReleaseDeployJars= */ multiReleaseDeployJars,
415+
javaHome,
416+
libModules,
417+
hermeticInputs);
378418
if (checkDesugarDeps) {
379419
commandLine = CommandLine.concat(commandLine, ImmutableList.of("--check_desugar_deps"));
380420
}

src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java

+17
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import static com.google.common.collect.ImmutableList.toImmutableList;
1717
import static com.google.devtools.build.lib.collect.nestedset.Order.STABLE_ORDER;
18+
import static com.google.devtools.build.lib.packages.Type.BOOLEAN;
1819
import static com.google.devtools.build.lib.rules.cpp.CppRuleClasses.JAVA_LAUNCHER_LINK;
1920
import static com.google.devtools.build.lib.rules.cpp.CppRuleClasses.STATIC_LINKING_MODE;
2021
import static com.google.devtools.build.lib.rules.java.DeployArchiveBuilder.Compression.COMPRESSED;
@@ -386,6 +387,22 @@ public ConfiguredTarget create(RuleContext ruleContext)
386387

387388
Artifact jsa = createSharedArchive(ruleContext, javaArtifacts, attributes);
388389

390+
if (ruleContext.isAttrDefined("hermetic", BOOLEAN)
391+
&& ruleContext.attributes().get("hermetic", BOOLEAN)) {
392+
if (!createExecutable) {
393+
ruleContext.ruleError("hermetic specified but create_executable is false");
394+
}
395+
JavaRuntimeInfo javaRuntime = JavaRuntimeInfo.from(ruleContext);
396+
if (javaRuntime.libModules() == null) {
397+
ruleContext.attributeError(
398+
"hermetic", "hermetic specified but java_runtime.lib_modules is absent");
399+
}
400+
deployArchiveBuilder
401+
.setJavaHome(javaRuntime.javaHomePathFragment())
402+
.setLibModules(javaRuntime.libModules())
403+
.setHermeticInputs(javaRuntime.hermeticInputs());
404+
}
405+
389406
deployArchiveBuilder
390407
.setOutputJar(deployJar)
391408
.setJavaStartClass(mainClass)

src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntime.java

+9-1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@ public ConfiguredTarget create(RuleContext ruleContext)
8686
PathFragment javaHomeRunfilesPath =
8787
javaBinaryRunfilesPath.getParentDirectory().getParentDirectory();
8888

89+
NestedSet<Artifact> hermeticInputs =
90+
PrerequisiteArtifacts.nestedSet(ruleContext, "hermetic_srcs");
91+
filesBuilder.addTransitive(hermeticInputs);
92+
93+
Artifact libModules = ruleContext.getPrerequisiteArtifact("lib_modules");
94+
8995
NestedSet<Artifact> filesToBuild = filesBuilder.build();
9096

9197
// TODO(cushon): clean up uses of java_runtime in data deps and remove this
@@ -100,7 +106,9 @@ public ConfiguredTarget create(RuleContext ruleContext)
100106
javaHome,
101107
javaBinaryExecPath,
102108
javaHomeRunfilesPath,
103-
javaBinaryRunfilesPath);
109+
javaBinaryRunfilesPath,
110+
hermeticInputs,
111+
libModules);
104112

105113
TemplateVariableInfo templateVariableInfo =
106114
new TemplateVariableInfo(

src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeInfo.java

+29-3
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,17 @@ public static JavaRuntimeInfo create(
4343
PathFragment javaHome,
4444
PathFragment javaBinaryExecPath,
4545
PathFragment javaHomeRunfilesPath,
46-
PathFragment javaBinaryRunfilesPath) {
46+
PathFragment javaBinaryRunfilesPath,
47+
NestedSet<Artifact> hermeticInputs,
48+
@Nullable Artifact libModules) {
4749
return new JavaRuntimeInfo(
4850
javaBaseInputs,
4951
javaHome,
5052
javaBinaryExecPath,
5153
javaHomeRunfilesPath,
52-
javaBinaryRunfilesPath);
54+
javaBinaryRunfilesPath,
55+
hermeticInputs,
56+
libModules);
5357
}
5458

5559
@Override
@@ -98,18 +102,24 @@ public static JavaRuntimeInfo from(RuleContext ruleContext, String attributeName
98102
private final PathFragment javaBinaryExecPath;
99103
private final PathFragment javaHomeRunfilesPath;
100104
private final PathFragment javaBinaryRunfilesPath;
105+
private final NestedSet<Artifact> hermeticInputs;
106+
@Nullable private final Artifact libModules;
101107

102108
private JavaRuntimeInfo(
103109
NestedSet<Artifact> javaBaseInputs,
104110
PathFragment javaHome,
105111
PathFragment javaBinaryExecPath,
106112
PathFragment javaHomeRunfilesPath,
107-
PathFragment javaBinaryRunfilesPath) {
113+
PathFragment javaBinaryRunfilesPath,
114+
NestedSet<Artifact> hermeticInputs,
115+
@Nullable Artifact libModules) {
108116
this.javaBaseInputs = javaBaseInputs;
109117
this.javaHome = javaHome;
110118
this.javaBinaryExecPath = javaBinaryExecPath;
111119
this.javaHomeRunfilesPath = javaHomeRunfilesPath;
112120
this.javaBinaryRunfilesPath = javaBinaryRunfilesPath;
121+
this.hermeticInputs = hermeticInputs;
122+
this.libModules = libModules;
113123
}
114124

115125
/** All input artifacts in the javabase. */
@@ -153,6 +163,22 @@ public PathFragment javaBinaryRunfilesPathFragment() {
153163
return javaBinaryRunfilesPath;
154164
}
155165

166+
/** Input artifacts required for hermetic deployments. */
167+
public NestedSet<Artifact> hermeticInputs() {
168+
return hermeticInputs;
169+
}
170+
171+
@Override
172+
public Depset starlarkHermeticInputs() {
173+
return Depset.of(Artifact.TYPE, hermeticInputs());
174+
}
175+
176+
@Override
177+
@Nullable
178+
public Artifact libModules() {
179+
return libModules;
180+
}
181+
156182
@Override
157183
public Depset starlarkJavaBaseInputs() {
158184
return Depset.of(Artifact.TYPE, javaBaseInputs());

src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeRule.java

+12
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,18 @@ public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env)
4242
All files in the runtime.
4343
<!-- #END_BLAZE_RULE.ATTRIBUTE --> */
4444
.add(attr("srcs", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE))
45+
/* <!-- #BLAZE_RULE(java_runtime).ATTRIBUTE(hermetic_srcs) -->
46+
Files in the runtime needed for hermetic deployments.
47+
<!-- #END_BLAZE_RULE.ATTRIBUTE --> */
48+
.add(attr("hermetic_srcs", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE))
49+
/* <!-- #BLAZE_RULE(java_runtime).ATTRIBUTE(lib_modules) -->
50+
The lib/modules file needed for hermetic deployments.
51+
<!-- #END_BLAZE_RULE.ATTRIBUTE --> */
52+
.add(
53+
attr("lib_modules", LABEL)
54+
.singleArtifact()
55+
.allowedFileTypes(FileTypeSet.ANY_FILE)
56+
.exec())
4557
/* <!-- #BLAZE_RULE(java_runtime).ATTRIBUTE(java) -->
4658
The path to the java executable.
4759
<!-- #END_BLAZE_RULE.ATTRIBUTE --> */

src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,10 @@ CustomCommandLine buildSingleJarCommandLine(
280280
OneVersionEnforcementLevel oneVersionEnforcementLevel,
281281
Artifact oneVersionAllowlistArtifact,
282282
Artifact sharedArchive,
283-
boolean multiReleaseDeployJars);
283+
boolean multiReleaseDeployJars,
284+
PathFragment javaHome,
285+
Artifact libModules,
286+
NestedSet<Artifact> hermeticInputs);
284287

285288
/**
286289
* Creates the action that writes the Java executable stub script.

src/main/java/com/google/devtools/build/lib/starlarkbuildapi/java/JavaRuntimeInfoApi.java

+18
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616

1717
import com.google.devtools.build.docgen.annot.DocCategory;
1818
import com.google.devtools.build.lib.collect.nestedset.Depset;
19+
import com.google.devtools.build.lib.starlarkbuildapi.FileApi;
1920
import com.google.devtools.build.lib.starlarkbuildapi.core.StructApi;
21+
import javax.annotation.Nullable;
2022
import net.starlark.java.annot.StarlarkBuiltin;
2123
import net.starlark.java.annot.StarlarkMethod;
2224

@@ -68,4 +70,20 @@ public interface JavaRuntimeInfoApi extends StructApi {
6870
doc = "Returns the files in the Java runtime.",
6971
structField = true)
7072
Depset starlarkJavaBaseInputs();
73+
74+
/** The files in the Java runtime needed for hermetic deployments. */
75+
@StarlarkMethod(
76+
name = "hermetic_files",
77+
doc = "Returns the files in the Java runtime needed for hermetic deployments.",
78+
structField = true)
79+
Depset starlarkHermeticInputs();
80+
81+
/** The lib/modules file. */
82+
@StarlarkMethod(
83+
name = "lib_modules",
84+
doc = "Returns the lib/modules file.",
85+
structField = true,
86+
allowReturnNones = true)
87+
@Nullable
88+
FileApi libModules();
7189
}

src/test/java/com/google/devtools/build/lib/rules/java/JavaRuntimeInfoTest.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,18 @@ public void equalityIsObjectIdentity() {
3333
PathFragment.create(""),
3434
PathFragment.create(""),
3535
PathFragment.create(""),
36-
PathFragment.create(""));
36+
PathFragment.create(""),
37+
NestedSetBuilder.emptySet(Order.STABLE_ORDER),
38+
null);
3739
JavaRuntimeInfo b =
3840
JavaRuntimeInfo.create(
3941
NestedSetBuilder.emptySet(Order.STABLE_ORDER),
4042
PathFragment.create(""),
4143
PathFragment.create(""),
4244
PathFragment.create(""),
43-
PathFragment.create(""));
45+
PathFragment.create(""),
46+
NestedSetBuilder.emptySet(Order.STABLE_ORDER),
47+
null);
4448

4549
new EqualsTester().addEqualityGroup(a).addEqualityGroup(b).testEquals();
4650
}

src/test/java/com/google/devtools/build/lib/view/java/BUILD

+1
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ java_test(
113113
deps = [
114114
"//src/main/java/com/google/devtools/build/lib/actions",
115115
"//src/main/java/com/google/devtools/build/lib/actions:artifacts",
116+
"//src/main/java/com/google/devtools/build/lib/collect/nestedset",
116117
"//src/main/java/com/google/devtools/build/lib/rules/java:java-compilation",
117118
"//src/main/java/com/google/devtools/build/lib/vfs",
118119
"//src/main/java/com/google/devtools/build/lib/vfs:pathfragment",

0 commit comments

Comments
 (0)