# 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(), 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) 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, 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, 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 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 default_cds = runtime.default_cds 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 default_cds: input_files.append(default_cds) args.add("--cds_archive", default_cds) 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, )