blob: 6df08cbf2417f08feac77e47c722f2465f229555 [file] [log] [blame]
# Copyright 2022 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Auxiliary rule to create the deploy archives for java_binary"""
load("//java/common:java_semantics.bzl", "semantics")
load(":java_helper.bzl", "helper")
# copybara: default visibility
def _get_build_info(ctx, stamp):
if helper.is_stamping_enabled(ctx, stamp):
# Makes the target depend on BUILD_INFO_KEY, which helps to discover stamped targets
# See b/326620485 for more details.
ctx.version_file # buildifier: disable=no-effect
return ctx.attr._build_info_translator[OutputGroupInfo].non_redacted_build_info_files.to_list()
else:
return ctx.attr._build_info_translator[OutputGroupInfo].redacted_build_info_files.to_list()
def create_deploy_archives(
ctx,
java_attrs,
launcher_info,
main_class,
coverage_main_class,
strip_as_default,
hermetic = False,
add_exports = depset(),
add_opens = depset(),
shared_archive = None,
one_version_level = "OFF",
one_version_allowlist = None,
extra_args = [],
extra_manifest_lines = []):
""" Registers actions for _deploy.jar and _deploy.jar.unstripped
Args:
ctx: (RuleContext) The rule context
java_attrs: (Struct) Struct of (classpath_resources, runtime_jars, runtime_classpath_for_archive, resources)
launcher_info: (Struct) Struct of (runtime_jars, launcher, unstripped_launcher)
main_class: (String) FQN of the entry point for execution
coverage_main_class: (String) FQN of the entry point for coverage collection
strip_as_default: (bool) Whether to create unstripped deploy jar
hermetic: (bool)
add_exports: (depset)
add_opens: (depset)
shared_archive: (File) Optional .jsa artifact
one_version_level: (String) Optional one version check level, default OFF
one_version_allowlist: (File) Optional allowlist for one version check
extra_args: (list[Args]) Optional arguments for the deploy jar action
extra_manifest_lines: (list[String]) Optional lines added to the jar manifest
"""
classpath_resources = java_attrs.classpath_resources
runtime_classpath = depset(
direct = launcher_info.runtime_jars,
transitive = [
java_attrs.runtime_jars,
java_attrs.runtime_classpath_for_archive,
],
order = "preorder",
)
multi_release = ctx.fragments.java.multi_release_deploy_jars
build_info_files = _get_build_info(ctx, ctx.attr.stamp)
build_target = str(ctx.label)
manifest_lines = ctx.attr.deploy_manifest_lines + extra_manifest_lines
create_deploy_archive(
ctx,
launcher_info.launcher,
main_class,
coverage_main_class,
java_attrs.resources,
classpath_resources,
runtime_classpath,
manifest_lines,
build_info_files,
build_target,
output = ctx.outputs.deployjar,
shared_archive = shared_archive,
one_version_level = one_version_level,
one_version_allowlist = one_version_allowlist,
multi_release = multi_release,
hermetic = hermetic,
add_exports = add_exports,
add_opens = add_opens,
extra_args = extra_args,
)
if strip_as_default:
create_deploy_archive(
ctx,
launcher_info.unstripped_launcher,
main_class,
coverage_main_class,
java_attrs.resources,
classpath_resources,
runtime_classpath,
manifest_lines,
build_info_files,
build_target,
output = ctx.outputs.unstrippeddeployjar,
multi_release = multi_release,
hermetic = hermetic,
add_exports = add_exports,
add_opens = add_opens,
extra_args = extra_args,
)
else:
ctx.actions.write(ctx.outputs.unstrippeddeployjar, "")
def create_deploy_archive(
ctx,
launcher,
main_class,
coverage_main_class,
resources,
classpath_resources,
runtime_classpath,
manifest_lines,
build_info_files,
build_target,
output,
shared_archive = None,
one_version_level = "OFF",
one_version_allowlist = None,
multi_release = False,
hermetic = False,
add_exports = [],
add_opens = [],
extra_args = []):
""" Creates a deploy jar
Requires a Java runtime toolchain if and only if hermetic is True.
Args:
ctx: (RuleContext) The rule context
launcher: (File) the launcher artifact
main_class: (String) FQN of the entry point for execution
coverage_main_class: (String) FQN of the entry point for coverage collection
resources: (Depset) resource inputs
classpath_resources: (Depset) classpath resource inputs
runtime_classpath: (Depset) source files to add to the jar
build_target: (String) Name of the build target for stamping
manifest_lines: (list[String]) Optional lines added to the jar manifest
build_info_files: (list[File]) build info files for stamping
build_target: (String) the owner build target label name string
output: (File) the output jar artifact
shared_archive: (File) Optional .jsa artifact
one_version_level: (String) Optional one version check level, default OFF
one_version_allowlist: (File) Optional allowlist for one version check
multi_release: (bool)
hermetic: (bool)
add_exports: (depset)
add_opens: (depset)
extra_args: (list[Args]) Optional arguments for the deploy jar action
"""
input_files = []
input_files.extend(build_info_files)
transitive_input_files = [
resources,
classpath_resources,
runtime_classpath,
]
single_jar = semantics.find_java_toolchain(ctx).single_jar
manifest_lines = list(manifest_lines)
if ctx.configuration.coverage_enabled:
manifest_lines.append("Coverage-Main-Class: %s" % coverage_main_class)
args = ctx.actions.args()
args.set_param_file_format("shell").use_param_file("@%s", use_always = True)
args.add("--output", output)
args.add("--build_target", build_target)
args.add("--normalize")
args.add("--compression")
if main_class:
args.add("--main_class", main_class)
args.add_all("--deploy_manifest_lines", manifest_lines)
args.add_all(build_info_files, before_each = "--build_info_file")
if launcher:
input_files.append(launcher)
args.add("--java_launcher", launcher)
args.add_all("--classpath_resources", classpath_resources)
args.add_all(
"--sources",
runtime_classpath,
map_each = helper.jar_and_target_arg_mapper,
)
if one_version_level != "OFF" and one_version_allowlist:
input_files.append(one_version_allowlist)
args.add("--enforce_one_version")
args.add("--one_version_allowlist", one_version_allowlist)
if one_version_level == "WARNING":
args.add("--succeed_on_found_violations")
if multi_release:
args.add("--multi_release")
if hermetic:
runtime = ctx.toolchains["@//tools/jdk/hermetic:hermetic_runtime_toolchain_type"].java_runtime
if runtime.lib_modules != None:
java_home = runtime.java_home
lib_modules = runtime.lib_modules
hermetic_files = runtime.hermetic_files
args.add("--hermetic_java_home", java_home)
args.add("--jdk_lib_modules", lib_modules)
args.add_all("--resources", hermetic_files)
input_files.append(lib_modules)
transitive_input_files.append(hermetic_files)
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)
inputs = depset(input_files, transitive = transitive_input_files)
ctx.actions.run(
mnemonic = "JavaDeployJar",
progress_message = "Building deploy jar %s" % output.short_path,
executable = single_jar,
inputs = inputs,
tools = [single_jar],
outputs = [output],
arguments = [args] + extra_args,
use_default_shell_env = True,
toolchain = semantics.JAVA_TOOLCHAIN_TYPE,
)