• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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