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 += ['-classpath', ':'.join(classpath), \"{main_class}\"] 71java_cmd.extend(extra_program_args) 72java_cmd.extend(jar_arguments) 73os.execvp(java_cmd[0], java_cmd) 74""" 75 76def main(argv): 77 argv = build_utils.ExpandFileArgs(argv) 78 parser = argparse.ArgumentParser() 79 parser.add_argument('--output', 80 required=True, 81 help='Output path for executable script.') 82 parser.add_argument( 83 '--main-class', 84 required=True, 85 help='Name of the java class with the "main" entry point.') 86 parser.add_argument('--max-heap-size', 87 required=True, 88 help='Argument for -Xmx') 89 parser.add_argument('--classpath', 90 action='append', 91 default=[], 92 help='Classpath for running the jar.') 93 parser.add_argument('--enable-asserts', 94 action='store_true', 95 help='Enable Java assert statements') 96 parser.add_argument('--tiered-stop-at-level-one', 97 action='store_true', 98 help='JVM flag: -XX:TieredStopAtLevel=1.') 99 parser.add_argument('extra_program_args', 100 nargs='*', 101 help='This captures all ' 102 'args after "--" to pass as extra args to the java cmd.') 103 104 args = parser.parse_args(argv) 105 106 extra_flags = [f'java_cmd.append("-Xmx{args.max_heap_size}")'] 107 if args.enable_asserts: 108 extra_flags.append('java_cmd.append("-enableassertions")') 109 if args.tiered_stop_at_level_one: 110 extra_flags.append('java_cmd.append("-XX:TieredStopAtLevel=1")') 111 112 classpath = [] 113 for cp_arg in args.classpath: 114 classpath += action_helpers.parse_gn_list(cp_arg) 115 116 run_dir = os.path.dirname(args.output) 117 classpath = [os.path.relpath(p, run_dir) for p in classpath] 118 119 java_path = os.path.relpath( 120 os.path.join(build_utils.JAVA_HOME, 'bin', 'java'), run_dir) 121 122 with action_helpers.atomic_output(args.output, mode='w') as script: 123 script.write( 124 script_template.format(classpath=('"%s"' % '", "'.join(classpath)), 125 java_path=repr(java_path), 126 main_class=args.main_class, 127 extra_program_args=repr(args.extra_program_args), 128 extra_flags='\n'.join(extra_flags))) 129 130 os.chmod(args.output, 0o750) 131 132 133if __name__ == '__main__': 134 sys.exit(main(sys.argv[1:])) 135