#!/usr/bin/env python3 # # Copyright 2014 The Chromium Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """Creates a simple script to run a java "binary". This creates a script that sets up the java command line for running a java jar. This includes correctly setting the classpath and the main class. """ import argparse import os import sys from util import build_utils import action_helpers # build_utils adds //build to sys.path. # The java command must be executed in the current directory because there may # be user-supplied paths in the args. The script receives the classpath relative # to the directory that the script is written in and then, when run, must # recalculate the paths relative to the current directory. script_template = """\ #!/usr/bin/env python3 # # This file was generated by build/android/gyp/create_java_binary_script.py import argparse import os import sys self_dir = os.path.dirname(__file__) classpath = [{classpath}] extra_program_args = {extra_program_args} java_path = {java_path} if os.getcwd() != self_dir: offset = os.path.relpath(self_dir, os.getcwd()) fix_path = lambda p: os.path.normpath(os.path.join(offset, p)) classpath = [fix_path(p) for p in classpath] java_path = fix_path(java_path) java_cmd = [java_path] # https://github.com/iBotPeaches/Apktool/issues/3174 # https://chromium-review.googlesource.com/c/chromium/src/+/4697557/3 java_cmd += ['-Djdk.util.zip.disableZip64ExtraFieldValidation=true'] # This is a simple argparser for jvm, jar, and classpath arguments. parser = argparse.ArgumentParser(add_help=False) parser.add_argument('--jar-args') parser.add_argument('--jvm-args') parser.add_argument('--classpath') # Test_runner parses the classpath for sharding junit tests. known_args, unknown_args = parser.parse_known_args(sys.argv[1:]) if known_args.jvm_args: jvm_arguments = known_args.jvm_args.strip('"').split() java_cmd.extend(jvm_arguments) if known_args.jar_args: jar_arguments = known_args.jar_args.strip('"').split() if unknown_args: raise Exception('There are unknown arguments') else: jar_arguments = unknown_args if known_args.classpath: classpath += [known_args.classpath] {extra_flags} java_cmd += ['-classpath', ':'.join(classpath), \"{main_class}\"] java_cmd.extend(extra_program_args) java_cmd.extend(jar_arguments) os.execvp(java_cmd[0], java_cmd) """ def main(argv): argv = build_utils.ExpandFileArgs(argv) parser = argparse.ArgumentParser() parser.add_argument('--output', required=True, help='Output path for executable script.') parser.add_argument( '--main-class', required=True, help='Name of the java class with the "main" entry point.') parser.add_argument('--max-heap-size', required=True, help='Argument for -Xmx') parser.add_argument('--classpath', action='append', default=[], help='Classpath for running the jar.') parser.add_argument('--enable-asserts', action='store_true', help='Enable Java assert statements') parser.add_argument('--tiered-stop-at-level-one', action='store_true', help='JVM flag: -XX:TieredStopAtLevel=1.') parser.add_argument('extra_program_args', nargs='*', help='This captures all ' 'args after "--" to pass as extra args to the java cmd.') args = parser.parse_args(argv) extra_flags = [f'java_cmd.append("-Xmx{args.max_heap_size}")'] if args.enable_asserts: extra_flags.append('java_cmd.append("-enableassertions")') if args.tiered_stop_at_level_one: extra_flags.append('java_cmd.append("-XX:TieredStopAtLevel=1")') classpath = [] for cp_arg in args.classpath: classpath += action_helpers.parse_gn_list(cp_arg) run_dir = os.path.dirname(args.output) classpath = [os.path.relpath(p, run_dir) for p in classpath] java_path = os.path.relpath( os.path.join(build_utils.JAVA_HOME, 'bin', 'java'), run_dir) with action_helpers.atomic_output(args.output, mode='w') as script: script.write( script_template.format(classpath=('"%s"' % '", "'.join(classpath)), java_path=repr(java_path), main_class=args.main_class, extra_program_args=repr(args.extra_program_args), extra_flags='\n'.join(extra_flags))) os.chmod(args.output, 0o750) if __name__ == '__main__': sys.exit(main(sys.argv[1:]))