def METHOD_NAME(ctx):
    _check_non_empty(ctx.attr.root_packages, "root_packages")
    inputs = depset()
    if ctx.attr.source_jar:
        inputs = depset(transitive = [dep[JavaInfo].transitive_source_jars for dep in ctx.attr.deps])
    else:
        inputs = depset(transitive = [dep[JavaInfo].transitive_runtime_jars for dep in ctx.attr.deps])
    args = ctx.actions.args()
    args.add_all("--sources", inputs)
    args.use_param_file(
        "@%s",
        use_always = True,
    )
    args.set_param_file_format("multiline")
    args.add("--output", ctx.outputs.jar)
    args.add("--normalize")
    resource_files = depset(
        transitive = [resource.files for resource in ctx.attr.resources],
    ).to_list()
    args.add("--resources")
    for resource_file in resource_files:
        if not resource_file.path.startswith("src/main/resources"):
            fail("resource %s must be stored in src/main/resources/" % resource_file.path)
        relative_path = resource_file.path.replace("src/main/resources/", "")
        # Map src/main/resources/a/b/c.txt to a/b/c.txt.
        args.add(resource_file.path, format = "%s:" + relative_path)
    # Maybe compress code.
    if not ctx.attr.source_jar:
        # Deal with limitation of singlejar flags: tool's default behavior is
        # "no", but you get that behavior only by absence of compression flags.
        if ctx.attr.compress == "preserve":
            args.add("--dont_change_compression")
        elif ctx.attr.compress == "yes":
            args.add("--compression")
        elif ctx.attr.compress == "no":
            pass
        else:
            fail("\"compress\" attribute (%s) must be: yes, no, preserve." % ctx.attr.compress)
    # Each package prefix has to be specified in its own --include_prefixes arg.
    for p in ctx.attr.root_packages:
        args.add("--include_prefixes", p.replace(".", "/"))
    if ctx.attr.exclude_build_data:
        args.add("--exclude_build_data")
    args.add_all("--deploy_manifest_lines", ctx.attr.manifest_lines, format_each = "\"%s\"")
    ctx.actions.run(
        inputs = inputs.to_list() + resource_files,
        outputs = [ctx.outputs.jar],
        arguments = [args],
        progress_message = "Merging into %s" % ctx.outputs.jar.short_path,
        mnemonic = "JavaSingleJar",
        executable = ctx.executable._singlejar,
    )