1# Copyright 2022 The Bazel Authors. All rights reserved. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15"""Auxiliary rule to create the deploy archives for java_binary""" 16 17load("//java/common:java_semantics.bzl", "semantics") 18load(":java_helper.bzl", "helper") 19 20# copybara: default visibility 21 22def _get_build_info(ctx, stamp): 23 if helper.is_stamping_enabled(ctx, stamp): 24 # Makes the target depend on BUILD_INFO_KEY, which helps to discover stamped targets 25 # See b/326620485 for more details. 26 ctx.version_file # buildifier: disable=no-effect 27 return ctx.attr._build_info_translator[OutputGroupInfo].non_redacted_build_info_files.to_list() 28 else: 29 return ctx.attr._build_info_translator[OutputGroupInfo].redacted_build_info_files.to_list() 30 31def create_deploy_archives( 32 ctx, 33 java_attrs, 34 launcher_info, 35 main_class, 36 coverage_main_class, 37 strip_as_default, 38 hermetic = False, 39 add_exports = depset(), 40 add_opens = depset(), 41 one_version_level = "OFF", 42 one_version_allowlist = None, 43 extra_args = [], 44 extra_manifest_lines = []): 45 """ Registers actions for _deploy.jar and _deploy.jar.unstripped 46 47 Args: 48 ctx: (RuleContext) The rule context 49 java_attrs: (Struct) Struct of (classpath_resources, runtime_jars, runtime_classpath_for_archive, resources) 50 launcher_info: (Struct) Struct of (runtime_jars, launcher, unstripped_launcher) 51 main_class: (String) FQN of the entry point for execution 52 coverage_main_class: (String) FQN of the entry point for coverage collection 53 strip_as_default: (bool) Whether to create unstripped deploy jar 54 hermetic: (bool) 55 add_exports: (depset) 56 add_opens: (depset) 57 one_version_level: (String) Optional one version check level, default OFF 58 one_version_allowlist: (File) Optional allowlist for one version check 59 extra_args: (list[Args]) Optional arguments for the deploy jar action 60 extra_manifest_lines: (list[String]) Optional lines added to the jar manifest 61 """ 62 classpath_resources = java_attrs.classpath_resources 63 64 runtime_classpath = depset( 65 direct = launcher_info.runtime_jars, 66 transitive = [ 67 java_attrs.runtime_jars, 68 java_attrs.runtime_classpath_for_archive, 69 ], 70 order = "preorder", 71 ) 72 multi_release = ctx.fragments.java.multi_release_deploy_jars 73 build_info_files = _get_build_info(ctx, ctx.attr.stamp) 74 build_target = str(ctx.label) 75 manifest_lines = ctx.attr.deploy_manifest_lines + extra_manifest_lines 76 create_deploy_archive( 77 ctx, 78 launcher_info.launcher, 79 main_class, 80 coverage_main_class, 81 java_attrs.resources, 82 classpath_resources, 83 runtime_classpath, 84 manifest_lines, 85 build_info_files, 86 build_target, 87 output = ctx.outputs.deployjar, 88 one_version_level = one_version_level, 89 one_version_allowlist = one_version_allowlist, 90 multi_release = multi_release, 91 hermetic = hermetic, 92 add_exports = add_exports, 93 add_opens = add_opens, 94 extra_args = extra_args, 95 ) 96 97 if strip_as_default: 98 create_deploy_archive( 99 ctx, 100 launcher_info.unstripped_launcher, 101 main_class, 102 coverage_main_class, 103 java_attrs.resources, 104 classpath_resources, 105 runtime_classpath, 106 manifest_lines, 107 build_info_files, 108 build_target, 109 output = ctx.outputs.unstrippeddeployjar, 110 multi_release = multi_release, 111 hermetic = hermetic, 112 add_exports = add_exports, 113 add_opens = add_opens, 114 extra_args = extra_args, 115 ) 116 else: 117 ctx.actions.write(ctx.outputs.unstrippeddeployjar, "") 118 119def create_deploy_archive( 120 ctx, 121 launcher, 122 main_class, 123 coverage_main_class, 124 resources, 125 classpath_resources, 126 runtime_classpath, 127 manifest_lines, 128 build_info_files, 129 build_target, 130 output, 131 one_version_level = "OFF", 132 one_version_allowlist = None, 133 multi_release = False, 134 hermetic = False, 135 add_exports = [], 136 add_opens = [], 137 extra_args = []): 138 """ Creates a deploy jar 139 140 Requires a Java runtime toolchain if and only if hermetic is True. 141 142 Args: 143 ctx: (RuleContext) The rule context 144 launcher: (File) the launcher artifact 145 main_class: (String) FQN of the entry point for execution 146 coverage_main_class: (String) FQN of the entry point for coverage collection 147 resources: (Depset) resource inputs 148 classpath_resources: (Depset) classpath resource inputs 149 runtime_classpath: (Depset) source files to add to the jar 150 build_target: (String) Name of the build target for stamping 151 manifest_lines: (list[String]) Optional lines added to the jar manifest 152 build_info_files: (list[File]) build info files for stamping 153 build_target: (String) the owner build target label name string 154 output: (File) the output jar artifact 155 one_version_level: (String) Optional one version check level, default OFF 156 one_version_allowlist: (File) Optional allowlist for one version check 157 multi_release: (bool) 158 hermetic: (bool) 159 add_exports: (depset) 160 add_opens: (depset) 161 extra_args: (list[Args]) Optional arguments for the deploy jar action 162 """ 163 input_files = [] 164 input_files.extend(build_info_files) 165 166 transitive_input_files = [ 167 resources, 168 classpath_resources, 169 runtime_classpath, 170 ] 171 172 single_jar = semantics.find_java_toolchain(ctx).single_jar 173 174 manifest_lines = list(manifest_lines) 175 if ctx.configuration.coverage_enabled: 176 manifest_lines.append("Coverage-Main-Class: %s" % coverage_main_class) 177 178 args = ctx.actions.args() 179 args.set_param_file_format("shell").use_param_file("@%s", use_always = True) 180 181 args.add("--output", output) 182 args.add("--build_target", build_target) 183 args.add("--normalize") 184 args.add("--compression") 185 if main_class: 186 args.add("--main_class", main_class) 187 args.add_all("--deploy_manifest_lines", manifest_lines) 188 args.add_all(build_info_files, before_each = "--build_info_file") 189 if launcher: 190 input_files.append(launcher) 191 args.add("--java_launcher", launcher) 192 args.add_all("--classpath_resources", classpath_resources) 193 args.add_all( 194 "--sources", 195 runtime_classpath, 196 map_each = helper.jar_and_target_arg_mapper, 197 ) 198 199 if one_version_level != "OFF" and one_version_allowlist: 200 input_files.append(one_version_allowlist) 201 args.add("--enforce_one_version") 202 args.add("--one_version_allowlist", one_version_allowlist) 203 if one_version_level == "WARNING": 204 args.add("--succeed_on_found_violations") 205 206 if multi_release: 207 args.add("--multi_release") 208 209 if hermetic: 210 runtime = ctx.toolchains["@//tools/jdk/hermetic:hermetic_runtime_toolchain_type"].java_runtime 211 if runtime.lib_modules != None: 212 java_home = runtime.java_home 213 lib_modules = runtime.lib_modules 214 hermetic_files = runtime.hermetic_files 215 default_cds = runtime.default_cds 216 args.add("--hermetic_java_home", java_home) 217 args.add("--jdk_lib_modules", lib_modules) 218 args.add_all("--resources", hermetic_files) 219 input_files.append(lib_modules) 220 transitive_input_files.append(hermetic_files) 221 if default_cds: 222 input_files.append(default_cds) 223 args.add("--cds_archive", default_cds) 224 225 args.add_all("--add_exports", add_exports) 226 args.add_all("--add_opens", add_opens) 227 228 inputs = depset(input_files, transitive = transitive_input_files) 229 230 ctx.actions.run( 231 mnemonic = "JavaDeployJar", 232 progress_message = "Building deploy jar %s" % output.short_path, 233 executable = single_jar, 234 inputs = inputs, 235 tools = [single_jar], 236 outputs = [output], 237 arguments = [args] + extra_args, 238 use_default_shell_env = True, 239 toolchain = semantics.JAVA_TOOLCHAIN_TYPE, 240 ) 241