1#!/usr/bin/env python3 2# 3# Copyright 2014 The Chromium Authors 4# Use of this source code is governed by a BSD-style license that can be 5# found in the LICENSE file. 6 7"""Creates a simple script to run a java "binary". 8 9This creates a script that sets up the java command line for running a java 10jar. This includes correctly setting the classpath and the main class. 11""" 12 13import argparse 14import os 15import sys 16 17from util import build_utils 18import action_helpers # build_utils adds //build to sys.path. 19 20# The java command must be executed in the current directory because there may 21# be user-supplied paths in the args. The script receives the classpath relative 22# to the directory that the script is written in and then, when run, must 23# recalculate the paths relative to the current directory. 24script_template = """\ 25#!/usr/bin/env python3 26# 27# This file was generated by build/android/gyp/create_java_binary_script.py 28 29import argparse 30import os 31import sys 32 33self_dir = os.path.dirname(__file__) 34classpath = [{classpath}] 35extra_program_args = {extra_program_args} 36java_path = {java_path} 37if os.getcwd() != self_dir: 38 offset = os.path.relpath(self_dir, os.getcwd()) 39 fix_path = lambda p: os.path.normpath(os.path.join(offset, p)) 40 classpath = [fix_path(p) for p in classpath] 41 java_path = fix_path(java_path) 42java_cmd = [java_path] 43 44# https://github.com/iBotPeaches/Apktool/issues/3174 45# https://chromium-review.googlesource.com/c/chromium/src/+/4697557/3 46java_cmd += ['-Djdk.util.zip.disableZip64ExtraFieldValidation=true'] 47 48# This is a simple argparser for jvm, jar, and classpath arguments. 49parser = argparse.ArgumentParser(add_help=False) 50parser.add_argument('--jar-args') 51parser.add_argument('--jvm-args') 52parser.add_argument('--classpath') 53# Test_runner parses the classpath for sharding junit tests. 54known_args, unknown_args = parser.parse_known_args(sys.argv[1:]) 55 56if known_args.jvm_args: 57 jvm_arguments = known_args.jvm_args.strip('"').split() 58 java_cmd.extend(jvm_arguments) 59if known_args.jar_args: 60 jar_arguments = known_args.jar_args.strip('"').split() 61 if unknown_args: 62 raise Exception('There are unknown arguments') 63else: 64 jar_arguments = unknown_args 65 66if known_args.classpath: 67 classpath += [known_args.classpath] 68 69{extra_flags} 70java_cmd.extend( 71 ['-classpath', ':'.join(classpath), '-enableassertions', \"{main_class}\"]) 72java_cmd.extend(extra_program_args) 73java_cmd.extend(jar_arguments) 74os.execvp(java_cmd[0], java_cmd) 75""" 76 77def main(argv): 78 argv = build_utils.ExpandFileArgs(argv) 79 parser = argparse.ArgumentParser() 80 parser.add_argument('--output', 81 required=True, 82 help='Output path for executable script.') 83 parser.add_argument( 84 '--main-class', 85 required=True, 86 help='Name of the java class with the "main" entry point.') 87 parser.add_argument('--max-heap-size', 88 required=True, 89 help='Argument for -Xmx') 90 parser.add_argument('--classpath', 91 action='append', 92 default=[], 93 help='Classpath for running the jar.') 94 parser.add_argument('--tiered-stop-at-level-one', 95 action='store_true', 96 help='JVM flag: -XX:TieredStopAtLevel=1.') 97 parser.add_argument('extra_program_args', 98 nargs='*', 99 help='This captures all ' 100 'args after "--" to pass as extra args to the java cmd.') 101 102 args = parser.parse_args(argv) 103 104 extra_flags = [f'java_cmd.append("-Xmx{args.max_heap_size}")'] 105 if args.tiered_stop_at_level_one: 106 extra_flags.append('java_cmd.append("-XX:TieredStopAtLevel=1")') 107 108 classpath = [] 109 for cp_arg in args.classpath: 110 classpath += action_helpers.parse_gn_list(cp_arg) 111 112 run_dir = os.path.dirname(args.output) 113 classpath = [os.path.relpath(p, run_dir) for p in classpath] 114 115 java_path = os.path.relpath( 116 os.path.join(build_utils.JAVA_HOME, 'bin', 'java'), run_dir) 117 118 with action_helpers.atomic_output(args.output, mode='w') as script: 119 script.write( 120 script_template.format(classpath=('"%s"' % '", "'.join(classpath)), 121 java_path=repr(java_path), 122 main_class=args.main_class, 123 extra_program_args=repr(args.extra_program_args), 124 extra_flags='\n'.join(extra_flags))) 125 126 os.chmod(args.output, 0o750) 127 128 129if __name__ == '__main__': 130 sys.exit(main(sys.argv[1:])) 131