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