Skip to content

Commit 54439b9

Browse files
cushonrules_java Copybara
authored andcommitted
Fix java_single_jar to propagate full transitive classpath and use shell param file format
`java_single_jar` previously set `runtime_classpath = inputs` in `JavaRuntimeClasspathInfo`, which only included the filtered outputs rather than the full transitive runtime dependencies (`all_inputs`). When `java_single_jar` targets were used in `deploy_env` of other deploy JAR rules, dependencies excluded from the inner JAR were not properly excluded from the outer JAR. Also configure `args.set_param_file_format("shell")` (matching `java_binary_deploy_jar.bzl`) so arguments in `deploy_manifest_lines` containing whitespace or embedded newlines are properly quoted in param files. Add unit tests for `deploy_manifest_lines`, transitive `deploy_env` exclusion, and `java_binary` consuming `java_single_jar` via `deploy_env`. PiperOrigin-RevId: 971365057 Change-Id: I47df6dbe444d1e5d29fabc730ee4d68555332a25
1 parent 3b9d0f2 commit 54439b9

2 files changed

Lines changed: 124 additions & 5 deletions

File tree

java/common/rules/java_single_jar.bzl

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ def _single_jar_inputs(deps, deploy_env):
3737
fail("unexpected file type in java_single_jar.deps: %s" % f.path)
3838
files.append(f)
3939
transitive_inputs.append(depset(files))
40-
inputs = depset(transitive = transitive_inputs)
40+
all_inputs = depset(transitive = transitive_inputs)
41+
inputs = all_inputs
4142

4243
if hasattr(java_common, "JavaRuntimeClasspathInfo"):
4344
deploy_env_jars = depset(transitive = [
@@ -47,15 +48,15 @@ def _single_jar_inputs(deps, deploy_env):
4748
excluded_jars = {jar: None for jar in deploy_env_jars.to_list()}
4849
if excluded_jars:
4950
inputs = depset([jar for jar in inputs.to_list() if jar not in excluded_jars])
50-
return inputs
51+
return inputs, all_inputs
5152

5253
def _bazel_java_single_jar_impl(ctx):
53-
inputs = _single_jar_inputs(ctx.attr.deps, ctx.attr.deploy_env)
54+
inputs, all_inputs = _single_jar_inputs(ctx.attr.deps, ctx.attr.deploy_env)
5455

5556
args = ctx.actions.args()
5657
args.add_all("--sources", inputs)
5758
args.use_param_file("@%s")
58-
args.set_param_file_format("multiline")
59+
args.set_param_file_format("shell")
5960
args.add_all("--deploy_manifest_lines", ctx.attr.deploy_manifest_lines)
6061
args.add("--output", ctx.outputs.output)
6162
args.add("--normalize")
@@ -102,7 +103,7 @@ def _bazel_java_single_jar_impl(ctx):
102103
runfiles = ctx.runfiles(transitive_files = files),
103104
)]
104105
if hasattr(java_common, "JavaRuntimeClasspathInfo"):
105-
providers.append(java_common.JavaRuntimeClasspathInfo(runtime_classpath = inputs))
106+
providers.append(java_common.JavaRuntimeClasspathInfo(runtime_classpath = all_inputs))
106107
return providers
107108

108109
bazel_java_single_jar = rule(

test/java/common/rules/java_single_jar_tests.bzl

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
load("@rules_testing//lib:analysis_test.bzl", "analysis_test", "test_suite")
44
load("@rules_testing//lib:truth.bzl", "matching")
55
load("@rules_testing//lib:util.bzl", "util")
6+
load("//java:java_binary.bzl", "java_binary")
7+
load("//java:java_library.bzl", "java_library")
68
load("//java:java_single_jar.bzl", "java_single_jar")
79
load("//java/common:java_semantics.bzl", "semantics")
810

@@ -155,15 +157,131 @@ def _test_java_single_jar_stamp_attr_auto_stamp_flag_disabled_impl(env, targets)
155157
for f in targets.build_info[OutputGroupInfo].redacted_build_info_files.to_list()
156158
])
157159

160+
def _test_java_single_jar_deploy_manifest_lines(name):
161+
util.helper_target(
162+
java_single_jar,
163+
name = name + "/jar",
164+
deps = ["1.jar"],
165+
deploy_manifest_lines = [
166+
"Manifest-Entry-A: valueA",
167+
"Manifest-Entry-B: line1,\n line2",
168+
],
169+
)
170+
171+
analysis_test(
172+
name = name,
173+
impl = _test_java_single_jar_deploy_manifest_lines_impl,
174+
target = name + "/jar",
175+
)
176+
177+
def _test_java_single_jar_deploy_manifest_lines_impl(env, target):
178+
assert_that_action = env.expect.that_target(target).action_named("JavaSingleJar")
179+
assert_that_action.argv().contains_at_least([
180+
"--deploy_manifest_lines",
181+
"Manifest-Entry-A: valueA",
182+
"Manifest-Entry-B: line1,\n line2",
183+
])
184+
185+
def _test_java_single_jar_transitive_deploy_env(name):
186+
util.helper_target(
187+
java_library,
188+
name = name + "_lib_a",
189+
srcs = ["A.java"],
190+
)
191+
util.helper_target(
192+
java_library,
193+
name = name + "_lib_b",
194+
srcs = ["B.java"],
195+
)
196+
util.helper_target(
197+
java_library,
198+
name = name + "_lib_c",
199+
srcs = ["C.java"],
200+
)
201+
util.helper_target(
202+
java_single_jar,
203+
name = name + "_env1",
204+
deps = [name + "_lib_a"],
205+
)
206+
util.helper_target(
207+
java_single_jar,
208+
name = name + "_inner",
209+
deps = [name + "_lib_a", name + "_lib_b"],
210+
deploy_env = [name + "_env1"],
211+
)
212+
util.helper_target(
213+
java_single_jar,
214+
name = name + "_outer",
215+
deps = [name + "_lib_a", name + "_lib_b", name + "_lib_c"],
216+
deploy_env = [name + "_inner"],
217+
)
218+
219+
analysis_test(
220+
name = name,
221+
impl = _test_java_single_jar_transitive_deploy_env_impl,
222+
target = name + "_outer",
223+
)
224+
225+
def _test_java_single_jar_transitive_deploy_env_impl(env, target):
226+
assert_that_action = env.expect.that_target(target).action_named("JavaSingleJar")
227+
assert_that_action.argv().contains_at_least([
228+
"--sources",
229+
"{bindir}/{package}/lib{test_name}_lib_c.jar",
230+
"--output",
231+
])
232+
assert_that_action.argv().not_contains("{bindir}/{package}/lib{test_name}_lib_a.jar")
233+
assert_that_action.argv().not_contains("{bindir}/{package}/lib{test_name}_lib_b.jar")
234+
235+
def _test_java_binary_deploy_env_with_java_single_jar(name):
236+
util.helper_target(
237+
java_library,
238+
name = name + "_lib_a",
239+
srcs = ["A.java"],
240+
)
241+
util.helper_target(
242+
java_library,
243+
name = name + "_lib_b",
244+
srcs = ["B.java"],
245+
)
246+
util.helper_target(
247+
java_single_jar,
248+
name = name + "_single_jar",
249+
deps = [name + "_lib_a"],
250+
)
251+
util.helper_target(
252+
java_binary,
253+
name = name + "_bin",
254+
main_class = "Main",
255+
runtime_deps = [name + "_lib_a", name + "_lib_b"],
256+
deploy_env = [name + "_single_jar"],
257+
)
258+
259+
analysis_test(
260+
name = name,
261+
attr_values = {"tags": ["min_bazel_8"]}, # the deploy jar was created by a separate rule in Bazel 7
262+
impl = _test_java_binary_deploy_env_with_java_single_jar_impl,
263+
target = name + "_bin",
264+
)
265+
266+
def _test_java_binary_deploy_env_with_java_single_jar_impl(env, target):
267+
assert_that_action = env.expect.that_target(target).action_named("JavaDeployJar")
268+
assert_that_action.inputs().contains_at_least([
269+
"{package}/lib{test_name}_lib_b.jar",
270+
])
271+
assert_that_action.inputs().not_contains("{package}/lib{test_name}_lib_a.jar")
272+
158273
def java_single_jar_tests(name):
159274
test_suite(
160275
name = name,
161276
tests = [
162277
_test_java_single_jar_basic,
278+
_test_java_single_jar_deploy_manifest_lines,
163279
_test_java_single_jar_force_enable_stamping,
164280
_test_java_single_jar_force_disable_stamping,
165281
_test_java_single_jar_stamping_enabled_build_data_excluded_fails,
166282
_test_java_single_jar_stamp_attr_auto_stamp_flag_enabled,
167283
_test_java_single_jar_stamp_attr_auto_stamp_flag_disabled,
284+
_test_java_single_jar_transitive_deploy_env,
285+
_test_java_binary_deploy_env_with_java_single_jar,
168286
],
169287
)

0 commit comments

Comments
 (0)