Skip to content

Commit 7556e11

Browse files
benjaminpcopybara-github
authored andcommitted
Add version to JavaRuntimeInfo.
1. As suggested in #6354 (comment), add a JDK version attribute to the java_runtime rule. This will allow changing behavior based on the Java runtime's version. 2. As an application of the above, pass -Djava.security.manager=allow to Java tests on JDK 17+. This makes the Bazel Java test runner to work on JDK 19. Fixes #14502. 3. To make the above generally useful, the remote_java_repository and local_java_repository must set the new version attribute in the java_runtime rules that they create. This means the old static jdk.BUILD file no longer suffices. Move the contents of jdk.BUILD into a Starlark file, so the version can be interpolated in by JDK repository rules and macros. (This isn't the nicest, but local_java_repository is not a repository rule, so the template cannot be in a non-Starlark file.) Closes #17775. PiperOrigin-RevId: 518860040 Change-Id: I8223b6407dd09528a4e5a6bf12354e5fc68278c6
1 parent bcf309b commit 7556e11

File tree

18 files changed

+133
-18
lines changed

18 files changed

+133
-18
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import com.google.devtools.build.lib.rules.java.JavaConfiguration.OneVersionEnforcementLevel;
5858
import com.google.devtools.build.lib.rules.java.JavaHelper;
5959
import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider;
60+
import com.google.devtools.build.lib.rules.java.JavaRuntimeInfo;
6061
import com.google.devtools.build.lib.rules.java.JavaSemantics;
6162
import com.google.devtools.build.lib.rules.java.JavaSourceJarsProvider;
6263
import com.google.devtools.build.lib.rules.java.JavaTargetAttributes;
@@ -548,6 +549,9 @@ public Iterable<String> getJvmFlags(
548549
if (testClass == null) {
549550
ruleContext.ruleError("cannot determine test class");
550551
} else {
552+
if (JavaRuntimeInfo.from(ruleContext).version() >= 17) {
553+
jvmFlags.add("-Djava.security.manager=allow");
554+
}
551555
// Always run junit tests with -ea (enable assertion)
552556
jvmFlags.add("-ea");
553557
// "suite" is a misnomer.

src/main/java/com/google/devtools/build/lib/bazel/rules/java/jdk.WORKSPACE.tmpl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
# External dependencies for the java_* rules.
22
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
33
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
4+
load("@bazel_tools//tools/jdk:jdk_build_file.bzl", "JDK_BUILD_TEMPLATE")
45
load("@bazel_tools//tools/jdk:local_java_repository.bzl", "local_java_repository")
56
load("@bazel_tools//tools/jdk:remote_java_repository.bzl", "remote_java_repository")
67

78
maybe(
89
local_java_repository,
910
name = "local_jdk",
1011
java_home = DEFAULT_SYSTEM_JAVABASE,
11-
build_file = "@bazel_tools//tools/jdk:jdk.BUILD",
12+
build_file_content = JDK_BUILD_TEMPLATE,
1213
)
1314

1415
# OpenJDK distributions that should only be downloaded on demand (e.g. when

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package com.google.devtools.build.lib.rules.java;
1616

1717
import static com.google.common.base.Preconditions.checkNotNull;
18+
import static com.google.devtools.build.lib.packages.Type.INTEGER;
1819

1920
import com.google.common.collect.ImmutableList;
2021
import com.google.common.collect.ImmutableMap;
@@ -129,7 +130,8 @@ public ConfiguredTarget create(RuleContext ruleContext)
129130
hermeticInputs,
130131
libModules,
131132
defaultCDS,
132-
hermeticStaticLibs);
133+
hermeticStaticLibs,
134+
ruleContext.attributes().get("version", INTEGER).toIntUnchecked());
133135

134136
TemplateVariableInfo templateVariableInfo =
135137
new TemplateVariableInfo(

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

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ public static JavaRuntimeInfo create(
5252
NestedSet<Artifact> hermeticInputs,
5353
@Nullable Artifact libModules,
5454
@Nullable Artifact defaultCDS,
55-
ImmutableList<CcInfo> hermeticStaticLibs) {
55+
ImmutableList<CcInfo> hermeticStaticLibs,
56+
int version) {
5657
return new JavaRuntimeInfo(
5758
javaBaseInputs,
5859
javaHome,
@@ -62,7 +63,8 @@ public static JavaRuntimeInfo create(
6263
hermeticInputs,
6364
libModules,
6465
defaultCDS,
65-
hermeticStaticLibs);
66+
hermeticStaticLibs,
67+
version);
6668
}
6769

6870
@Override
@@ -125,6 +127,7 @@ private static JavaRuntimeInfo from(RuleContext ruleContext, ToolchainInfo toolc
125127
@Nullable private final Artifact libModules;
126128
@Nullable private final Artifact defaultCDS;
127129
private final ImmutableList<CcInfo> hermeticStaticLibs;
130+
private final int version;
128131

129132
private JavaRuntimeInfo(
130133
NestedSet<Artifact> javaBaseInputs,
@@ -135,7 +138,8 @@ private JavaRuntimeInfo(
135138
NestedSet<Artifact> hermeticInputs,
136139
@Nullable Artifact libModules,
137140
@Nullable Artifact defaultCDS,
138-
ImmutableList<CcInfo> hermeticStaticLibs) {
141+
ImmutableList<CcInfo> hermeticStaticLibs,
142+
int version) {
139143
this.javaBaseInputs = javaBaseInputs;
140144
this.javaHome = javaHome;
141145
this.javaBinaryExecPath = javaBinaryExecPath;
@@ -145,6 +149,7 @@ private JavaRuntimeInfo(
145149
this.libModules = libModules;
146150
this.defaultCDS = defaultCDS;
147151
this.hermeticStaticLibs = hermeticStaticLibs;
152+
this.version = version;
148153
}
149154

150155
/** All input artifacts in the javabase. */
@@ -232,6 +237,11 @@ public Depset starlarkJavaBaseInputs() {
232237
return Depset.of(Artifact.class, javaBaseInputs());
233238
}
234239

240+
@Override
241+
public int version() {
242+
return version;
243+
}
244+
235245
@Override
236246
public com.google.devtools.build.lib.packages.Provider getProvider() {
237247
return PROVIDER;

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import static com.google.devtools.build.lib.packages.BuildType.LABEL;
1919
import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
2020
import static com.google.devtools.build.lib.packages.BuildType.LICENSE;
21+
import static com.google.devtools.build.lib.packages.Type.INTEGER;
2122
import static com.google.devtools.build.lib.packages.Type.STRING;
2223

2324
import com.google.devtools.build.lib.analysis.BaseRuleClasses;
@@ -83,6 +84,11 @@ public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env)
8384
<!-- #END_BLAZE_RULE.ATTRIBUTE --> */
8485
.add(attr("java_home", STRING))
8586
.add(attr("output_licenses", LICENSE))
87+
/* <!-- #BLAZE_RULE(java_runtime).ATTRIBUTE(version) -->
88+
The feature version of the Java runtime. I.e., the integer returned by
89+
<code>Runtime.version().feature()</code>.
90+
<!-- #END_BLAZE_RULE.ATTRIBUTE --> */
91+
.add(attr("version", INTEGER))
8692
.build();
8793
}
8894

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,4 +104,11 @@ public interface JavaRuntimeInfoApi extends StructApi {
104104
doc = "Returns the JDK static libraries.",
105105
structField = true)
106106
Sequence<CcInfo> starlarkHermeticStaticLibs();
107+
108+
/** The Java feature version of the runtime. This is 0 if the version is unknown. */
109+
@StarlarkMethod(
110+
name = "version",
111+
doc = "The Java feature version of the runtime. This is 0 if the version is unknown.",
112+
structField = true)
113+
int version();
107114
}

src/main/starlark/builtins_bzl/bazel/java/bazel_java_binary.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ def _bazel_java_binary_impl(ctx):
5454
)
5555

5656
if ctx.attr.use_testrunner:
57+
if semantics.find_java_runtime_toolchain(ctx).version >= 17:
58+
jvm_flags.append("-Djava.security.manager=allow")
5759
test_class = ctx.attr.test_class if hasattr(ctx.attr, "test_class") else ""
5860
if test_class == "":
5961
test_class = helper.primary_class(ctx)

src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,7 @@ public void setupMockToolsRepository(MockToolsConfig config) throws IOException
580580
"",
581581
"def http_jar(**kwargs):",
582582
" pass");
583+
config.create("embedded_tools/tools/jdk/jdk_build_file.bzl", "JDK_BUILD_TEMPLATE = ''");
583584
config.create(
584585
"embedded_tools/tools/jdk/local_java_repository.bzl",
585586
"def local_java_repository(**kwargs):",

src/test/java/com/google/devtools/build/lib/bazel/rules/java/BUILD

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,14 @@ java_library(
1717
name = "JavaTests_lib",
1818
srcs = glob(["*.java"]),
1919
deps = [
20+
"//src/main/java/com/google/devtools/build/lib/analysis:actions/template_expansion_action",
2021
"//src/main/java/com/google/devtools/build/lib/analysis:configured_target",
2122
"//src/main/java/com/google/devtools/build/lib/bazel/rules/java:bazel_java_semantics",
2223
"//src/main/java/com/google/devtools/build/lib/packages",
24+
"//src/main/java/com/google/devtools/build/lib/util:os",
2325
"//src/main/java/com/google/devtools/build/lib/vfs:pathfragment",
2426
"//src/test/java/com/google/devtools/build/lib/analysis/util",
27+
"//src/test/java/com/google/devtools/build/lib/testutil:TestConstants",
2528
"//third_party:guava",
2629
"//third_party:junit4",
2730
"//third_party:truth",

src/test/java/com/google/devtools/build/lib/bazel/rules/java/JavaConfiguredTargetsTest.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,18 @@
1414

1515
package com.google.devtools.build.lib.bazel.rules.java;
1616

17+
import static com.google.common.collect.ImmutableList.toImmutableList;
18+
import static com.google.common.collect.MoreCollectors.onlyElement;
1719
import static com.google.common.truth.Truth.assertThat;
20+
import static com.google.devtools.build.lib.testutil.TestConstants.TOOLS_REPOSITORY;
1821

1922
import com.google.common.base.Joiner;
2023
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
24+
import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction;
2125
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
26+
import com.google.devtools.build.lib.util.OS;
27+
import java.util.Arrays;
28+
import java.util.Objects;
2229
import org.junit.Test;
2330
import org.junit.runner.RunWith;
2431
import org.junit.runners.JUnit4;
@@ -46,4 +53,44 @@ public void testResourceStripPrefix() throws Exception {
4653
Joiner.on(" ").join(getGeneratingSpawnActionArgs(getBinArtifact("bin.jar", target)));
4754
assertThat(resourceJarArgs).contains("--resources a/path/to/strip/bar.props:bar.props");
4855
}
56+
57+
@Test
58+
public void javaTestSetsSecurityManagerPropertyOnVersion17() throws Exception {
59+
scratch.file(
60+
"a/BUILD",
61+
"java_runtime(",
62+
" name = 'jvm',",
63+
" java = 'java_home/bin/java',",
64+
" version = 17,",
65+
")",
66+
"toolchain(",
67+
" name = 'java_runtime_toolchain',",
68+
" toolchain = ':jvm',",
69+
" toolchain_type = '" + TOOLS_REPOSITORY + "//tools/jdk:runtime_toolchain_type',",
70+
")",
71+
"java_test(",
72+
" name = 'test',",
73+
" srcs = ['FooTest.java'],",
74+
" test_class = 'FooTest',",
75+
")");
76+
useConfiguration("--extra_toolchains=//a:java_runtime_toolchain");
77+
var ct = getConfiguredTarget("//a:test");
78+
var executable = getExecutable(ct);
79+
if (OS.getCurrent() == OS.WINDOWS) {
80+
var jvmFlags =
81+
getGeneratingSpawnActionArgs(executable).stream()
82+
.filter(a -> a.startsWith("jvm_flags="))
83+
.flatMap(a -> Arrays.stream(a.substring("jvm_flags=".length()).split("\t")))
84+
.collect(toImmutableList());
85+
assertThat(jvmFlags).contains("-Djava.security.manager=allow");
86+
} else {
87+
var jvmFlags =
88+
((TemplateExpansionAction) getGeneratingAction(executable))
89+
.getSubstitutions().stream()
90+
.filter(s -> Objects.equals(s.getKey(), "%jvm_flags%"))
91+
.collect(onlyElement())
92+
.getValue();
93+
assertThat(jvmFlags).contains("-Djava.security.manager=allow");
94+
}
95+
}
4996
}

0 commit comments

Comments
 (0)