|
| 1 | +#!/usr/bin/env bash |
| 2 | +# Copyright 2014 The Bazel Authors. All rights reserved. |
| 3 | +# |
| 4 | +# Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | +# you may not use this file except in compliance with the License. |
| 6 | +# You may obtain a copy of the License at |
| 7 | +# |
| 8 | +# http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | +# |
| 10 | +# Unless required by applicable law or agreed to in writing, software |
| 11 | +# distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | +# See the License for the specific language governing permissions and |
| 14 | +# limitations under the License. |
| 15 | +# |
| 16 | +# This script was generated from java_stub_template.txt. Please |
| 17 | +# don't edit it directly. |
| 18 | +# |
| 19 | +# If present, these flags should either be at the beginning of the command |
| 20 | +# line, or they should be wrapped in a --wrapper_script_flag=FLAG argument. |
| 21 | +# |
| 22 | +# --debug Launch the JVM in remote debugging mode listening |
| 23 | +# --debug=<port> to the specified port or the port set in the |
| 24 | +# DEFAULT_JVM_DEBUG_PORT environment variable (e.g. |
| 25 | +# 'export DEFAULT_JVM_DEBUG_PORT=8000') or else the |
| 26 | +# default port of 5005. The JVM starts suspended |
| 27 | +# unless the DEFAULT_JVM_DEBUG_SUSPEND environment |
| 28 | +# variable is set to 'n'. |
| 29 | +# --main_advice=<class> Run an alternate main class with the usual main |
| 30 | +# program and arguments appended as arguments. |
| 31 | +# --main_advice_classpath=<classpath> |
| 32 | +# Prepend additional class path entries. |
| 33 | +# --jvm_flag=<flag> Pass <flag> to the "java" command itself. |
| 34 | +# <flag> may contain spaces. Can be used multiple times. |
| 35 | +# --jvm_flags=<flags> Pass space-separated flags to the "java" command |
| 36 | +# itself. Can be used multiple times. |
| 37 | +# --singlejar Start the program from the packed-up deployment |
| 38 | +# jar rather than from the classpath. |
| 39 | +# --print_javabin Print the location of java executable binary and exit. |
| 40 | +# --classpath_limit=<length> |
| 41 | +# Specify the maximum classpath length. If the classpath |
| 42 | +# is shorter, this script passes it to Java as a command |
| 43 | +# line flag, otherwise it creates a classpath jar. |
| 44 | +# |
| 45 | +# The remainder of the command line is passed to the program. |
| 46 | + |
| 47 | +set -o posix |
| 48 | + |
| 49 | +# Make it easy to insert 'set -x' or similar commands when debugging problems with this script. |
| 50 | +eval "$JAVA_STUB_DEBUG" |
| 51 | + |
| 52 | +# Prevent problems where the caller has exported CLASSPATH, causing our |
| 53 | +# computed value to be copied into the environment and double-counted |
| 54 | +# against the argv limit. |
| 55 | +unset CLASSPATH |
| 56 | + |
| 57 | +JVM_FLAGS_CMDLINE=() |
| 58 | + |
| 59 | +# Processes an argument for the wrapper. Returns 0 if the given argument |
| 60 | +# was recognized as an argument for this wrapper, and 1 if it was not. |
| 61 | +function process_wrapper_argument() { |
| 62 | + case "$1" in |
| 63 | + --debug) JVM_DEBUG_PORT="${DEFAULT_JVM_DEBUG_PORT:-5005}" ;; |
| 64 | + --debug=*) JVM_DEBUG_PORT="${1#--debug=}" ;; |
| 65 | + --main_advice=*) MAIN_ADVICE="${1#--main_advice=}" ;; |
| 66 | + --main_advice_classpath=*) MAIN_ADVICE_CLASSPATH="${1#--main_advice_classpath=}" ;; |
| 67 | + --jvm_flag=*) JVM_FLAGS_CMDLINE+=( "${1#--jvm_flag=}" ) ;; |
| 68 | + --jvm_flags=*) JVM_FLAGS_CMDLINE+=( ${1#--jvm_flags=} ) ;; |
| 69 | + --singlejar) SINGLEJAR=1 ;; |
| 70 | + --print_javabin) PRINT_JAVABIN=1 ;; |
| 71 | + --classpath_limit=*) |
| 72 | + CLASSPATH_LIMIT="${1#--classpath_limit=}" |
| 73 | + echo "$CLASSPATH_LIMIT" | grep -q '^[0-9]\+$' || \ |
| 74 | + die "ERROR: $self failed, --classpath_limit is not a number" |
| 75 | + ;; |
| 76 | + *) |
| 77 | + return 1 ;; |
| 78 | + esac |
| 79 | + return 0 |
| 80 | +} |
| 81 | + |
| 82 | +die() { |
| 83 | + printf "%s: $1\n" "$0" "${@:2}" >&2 |
| 84 | + exit 1 |
| 85 | +} |
| 86 | + |
| 87 | +# Windows |
| 88 | +function is_windows() { |
| 89 | + [[ "${OSTYPE}" =~ msys* ]] || [[ "${OSTYPE}" =~ cygwin* ]] |
| 90 | +} |
| 91 | + |
| 92 | +# macOS |
| 93 | +function is_macos() { |
| 94 | + [[ "${OSTYPE}" =~ darwin* ]] |
| 95 | +} |
| 96 | + |
| 97 | +# Parse arguments sequentially until the first unrecognized arg is encountered. |
| 98 | +# Scan the remaining args for --wrapper_script_flag=X options and process them. |
| 99 | +ARGS=() |
| 100 | +for ARG in "$@"; do |
| 101 | + if [[ "$ARG" == --wrapper_script_flag=* ]]; then |
| 102 | + process_wrapper_argument "${ARG#--wrapper_script_flag=}" \ |
| 103 | + || die "invalid wrapper argument '%s'" "$ARG" |
| 104 | + elif [[ "${#ARGS}" -gt 0 ]] || ! process_wrapper_argument "$ARG"; then |
| 105 | + ARGS+=( "$ARG" ) |
| 106 | + fi |
| 107 | +done |
| 108 | + |
| 109 | +# Find our runfiles tree. We need this to construct the classpath |
| 110 | +# (unless --singlejar was passed). |
| 111 | +# |
| 112 | +# Call this program X. X was generated by a java_binary or java_test rule. |
| 113 | +# X may be invoked in many ways: |
| 114 | +# 1a) directly by a user, with $0 in the output tree |
| 115 | +# 1b) via 'bazel run' (similar to case 1a) |
| 116 | +# 2) directly by a user, with $0 in X's runfiles tree |
| 117 | +# 3) by another program Y which has a data dependency on X, with $0 in Y's runfiles tree |
| 118 | +# 4) via 'bazel test' |
| 119 | +# 5) by a genrule cmd, with $0 in the output tree |
| 120 | +# 6) case 3 in the context of a genrule |
| 121 | +# |
| 122 | +# For case 1, $0 will be a regular file, and the runfiles tree will be |
| 123 | +# at $0.runfiles. |
| 124 | +# For case 2, $0 will be a symlink to the file seen in case 1. |
| 125 | +# For case 3, we use Y's runfiles tree, which will be a superset of X's. |
| 126 | +# For case 4, $JAVA_RUNFILES and $TEST_SRCDIR should already be set. |
| 127 | +# Case 5 is handled like case 1. |
| 128 | +# Case 6 is handled like case 3. |
| 129 | + |
| 130 | +# If we are running on Windows, convert the windows style path |
| 131 | +# to unix style for detecting runfiles path. |
| 132 | +if is_windows; then |
| 133 | + self=$(cygpath --unix "$0") |
| 134 | +else |
| 135 | + self="$0" |
| 136 | +fi |
| 137 | + |
| 138 | +if [[ "$self" != /* ]]; then |
| 139 | + self="$PWD/$self" |
| 140 | +fi |
| 141 | + |
| 142 | +if [[ "$SINGLEJAR" != 1 || "%needs_runfiles%" == 1 ]]; then |
| 143 | + if [[ -z "$JAVA_RUNFILES" ]]; then |
| 144 | + while true; do |
| 145 | + if [[ -e "$self.runfiles" ]]; then |
| 146 | + JAVA_RUNFILES="$self.runfiles" |
| 147 | + break |
| 148 | + fi |
| 149 | + if [[ $self == *.runfiles/* ]]; then |
| 150 | + JAVA_RUNFILES="${self%.runfiles/*}.runfiles" |
| 151 | + break |
| 152 | + fi |
| 153 | + if [[ ! -L "$self" ]]; then |
| 154 | + break |
| 155 | + fi |
| 156 | + readlink="$(readlink "$self")" |
| 157 | + if [[ "$readlink" = /* ]]; then |
| 158 | + self="$readlink" |
| 159 | + else |
| 160 | + # resolve relative symlink |
| 161 | + self="${self%/*}/$readlink" |
| 162 | + fi |
| 163 | + done |
| 164 | + if [[ -n "$JAVA_RUNFILES" ]]; then |
| 165 | + export TEST_SRCDIR=${TEST_SRCDIR:-$JAVA_RUNFILES} |
| 166 | + elif [[ -f "${self}_deploy.jar" && "%needs_runfiles%" == 0 ]]; then |
| 167 | + SINGLEJAR=1; |
| 168 | + else |
| 169 | + die 'Cannot locate runfiles directory. (Set $JAVA_RUNFILES to inhibit searching.)' |
| 170 | + fi |
| 171 | + fi |
| 172 | +fi |
| 173 | + |
| 174 | +# If we are running on Windows, we need a windows style runfiles path for constructing CLASSPATH |
| 175 | +if is_windows; then |
| 176 | + JAVA_RUNFILES=$(cygpath --windows "$JAVA_RUNFILES") |
| 177 | +fi |
| 178 | + |
| 179 | +export JAVA_RUNFILES |
| 180 | +export RUNFILES_MANIFEST_FILE="${JAVA_RUNFILES}/MANIFEST" |
| 181 | +export RUNFILES_MANIFEST_ONLY=%runfiles_manifest_only% |
| 182 | + |
| 183 | +if [ -z "$RUNFILES_MANIFEST_ONLY" ]; then |
| 184 | + function rlocation() { |
| 185 | + if [[ "$1" = /* ]]; then |
| 186 | + echo $1 |
| 187 | + else |
| 188 | + echo "$(dirname $RUNFILES_MANIFEST_FILE)/$1" |
| 189 | + fi |
| 190 | + } |
| 191 | +else |
| 192 | + if ! is_macos; then |
| 193 | + # Read file into my_array |
| 194 | + oifs=$IFS |
| 195 | + IFS=$'\n' |
| 196 | + my_array=( $(sed -e 's/\r//g' "$RUNFILES_MANIFEST_FILE") ) |
| 197 | + IFS=$oifs |
| 198 | + |
| 199 | + # Process each runfile line into a [key,value] entry in runfiles_array |
| 200 | + # declare -A is not supported on macOS because an old version of bash is used. |
| 201 | + declare -A runfiles_array |
| 202 | + for line in "${my_array[@]}" |
| 203 | + do |
| 204 | + line_split=($line) |
| 205 | + runfiles_array[${line_split[0]}]=${line_split[@]:1} |
| 206 | + done |
| 207 | + fi |
| 208 | + |
| 209 | + function rlocation() { |
| 210 | + if [[ "$1" = /* ]]; then |
| 211 | + echo $1 |
| 212 | + else |
| 213 | + if is_macos; then |
| 214 | + # Print the rest of line after the first space |
| 215 | + # First, set the first column to empty and print rest of the line |
| 216 | + # Second, use a trick of awk to remove leading and trailing spaces. |
| 217 | + echo $(grep "^$1 " $RUNFILES_MANIFEST_FILE | awk '{ $1=""; print }' | awk '{ $1=$1; print }') |
| 218 | + else |
| 219 | + echo ${runfiles_array[$1]} |
| 220 | + fi |
| 221 | + fi |
| 222 | + } |
| 223 | +fi |
| 224 | + |
| 225 | +if is_macos || [[ ${OSTYPE} == "freebsd" ]]; then |
| 226 | + function md5func() { md5 -q $@ ; } |
| 227 | +else |
| 228 | + function md5func() { md5sum $@ | awk '{print $1}' ; } |
| 229 | +fi |
| 230 | + |
| 231 | +# Set JAVABIN to the path to the JVM launcher. |
| 232 | +%javabin% |
| 233 | + |
| 234 | +if [[ "$PRINT_JAVABIN" == 1 || "%java_start_class%" == "--print_javabin" ]]; then |
| 235 | + echo -n "$JAVABIN" |
| 236 | + exit 0 |
| 237 | +fi |
| 238 | + |
| 239 | +if [[ "$SINGLEJAR" == 1 ]]; then |
| 240 | + CLASSPATH="${self}_deploy.jar" |
| 241 | + # Check for the deploy jar now. If it doesn't exist, we can print a |
| 242 | + # more helpful error message than the JVM. |
| 243 | + [[ -r "$CLASSPATH" ]] \ |
| 244 | + || die "Option --singlejar was passed, but %s does not exist.\n (You may need to build it explicitly.)" "$CLASSPATH" |
| 245 | +else |
| 246 | + # Create the shortest classpath we can, by making it relative if possible. |
| 247 | + RUNPATH="${JAVA_RUNFILES}/%workspace_prefix%" |
| 248 | + RUNPATH="${RUNPATH#$PWD/}" |
| 249 | + CLASSPATH=%classpath% |
| 250 | +fi |
| 251 | + |
| 252 | +# Export the locations which will be used to find the location of the classes from the classpath file. |
| 253 | +export SELF_LOCATION="$self" |
| 254 | +export CLASSLOADER_PREFIX_PATH="${RUNPATH}" |
| 255 | + |
| 256 | +# If using Jacoco in offline instrumentation mode, the CLASSPATH contains instrumented files. |
| 257 | +# We need to make the metadata jar with uninstrumented classes available for generating |
| 258 | +# the lcov-compatible coverage report, and we don't want it on the classpath. |
| 259 | +%set_jacoco_metadata% |
| 260 | +%set_jacoco_main_class% |
| 261 | +%set_jacoco_java_runfiles_root% |
| 262 | +%set_java_coverage_new_implementation% |
| 263 | + |
| 264 | +if [[ -n "$JVM_DEBUG_PORT" ]]; then |
| 265 | + JVM_DEBUG_SUSPEND=${DEFAULT_JVM_DEBUG_SUSPEND:-"y"} |
| 266 | + JVM_DEBUG_FLAGS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=${JVM_DEBUG_SUSPEND},address=${JVM_DEBUG_PORT}" |
| 267 | + |
| 268 | + if [[ "$PERSISTENT_TEST_RUNNER" == "true" ]]; then |
| 269 | + JVM_DEBUG_FLAGS+=",quiet=y" |
| 270 | + fi |
| 271 | +fi |
| 272 | + |
| 273 | +if [[ -n "$MAIN_ADVICE_CLASSPATH" ]]; then |
| 274 | + CLASSPATH="${MAIN_ADVICE_CLASSPATH}:${CLASSPATH}" |
| 275 | +fi |
| 276 | + |
| 277 | +# Check if TEST_TMPDIR is available to use for scratch. |
| 278 | +if [[ -n "$TEST_TMPDIR" && -d "$TEST_TMPDIR" ]]; then |
| 279 | + JVM_FLAGS+=" -Djava.io.tmpdir=$TEST_TMPDIR" |
| 280 | +fi |
| 281 | + |
| 282 | +ARGS=( |
| 283 | + ${JVM_DEBUG_FLAGS} |
| 284 | + ${JVM_FLAGS} |
| 285 | + %jvm_flags% |
| 286 | + "${JVM_FLAGS_CMDLINE[@]}" |
| 287 | + ${MAIN_ADVICE} |
| 288 | + %java_start_class% |
| 289 | + "${ARGS[@]}") |
| 290 | + |
| 291 | + |
| 292 | +function create_and_run_classpath_jar() { |
| 293 | + # Build class path as one single string separated by spaces |
| 294 | + MANIFEST_CLASSPATH="" |
| 295 | + if is_windows; then |
| 296 | + IFS=';' |
| 297 | + URI_PREFIX="file:/" # e.g. "file:/C:/temp/foo.jar" |
| 298 | + else |
| 299 | + IFS=':' |
| 300 | + URI_PREFIX="file:$(pwd)/" # e.g. "file:/usr/local/foo.jar" |
| 301 | + fi |
| 302 | + for x in $CLASSPATH; do |
| 303 | + # Add file:/ prefix and escaped space characters, it should be a URI. |
| 304 | + x="${URI_PREFIX}${x// /%20}" |
| 305 | + MANIFEST_CLASSPATH="$MANIFEST_CLASSPATH $x" |
| 306 | + done |
| 307 | + unset IFS |
| 308 | + |
| 309 | + # Create manifest file |
| 310 | + MANIFEST_FILE="$(mktemp -t XXXXXXXX.jar_manifest)" |
| 311 | + |
| 312 | + ( |
| 313 | + echo "Manifest-Version: 1.0" |
| 314 | + CLASSPATH_LINE="Class-Path:$MANIFEST_CLASSPATH" |
| 315 | + # No line in the MANIFEST.MF file may be longer than 72 bytes. |
| 316 | + # A space prefix indicates the line is still the content of the last attribute. |
| 317 | + for ((i = 0; i < "${#CLASSPATH_LINE}"; i += 71)); do |
| 318 | + PREFIX=" " |
| 319 | + if ((i == 0)); then |
| 320 | + PREFIX="" |
| 321 | + fi |
| 322 | + echo "$PREFIX${CLASSPATH_LINE:$i:71}" |
| 323 | + done |
| 324 | + echo "Created-By: Bazel" |
| 325 | + ) >$MANIFEST_FILE |
| 326 | + |
| 327 | + # Create classpath JAR file |
| 328 | + MANIFEST_JAR_FILE="$(mktemp -t XXXXXXXX-classpath.jar)" |
| 329 | + if is_windows; then |
| 330 | + MANIFEST_JAR_FILE="$(cygpath --windows "$MANIFEST_JAR_FILE")" |
| 331 | + MANIFEST_FILE="$(cygpath --windows "$MANIFEST_FILE")" |
| 332 | + fi |
| 333 | + JARBIN="${JARBIN:-$(rlocation "$1")}" |
| 334 | + $JARBIN cvfm "$MANIFEST_JAR_FILE" "$MANIFEST_FILE" >/dev/null || \ |
| 335 | + die "ERROR: $self failed because $JARBIN failed" |
| 336 | + |
| 337 | + # Execute JAVA command |
| 338 | + $JAVABIN -classpath "$MANIFEST_JAR_FILE" "${ARGS[@]}" |
| 339 | + exit_code=$? |
| 340 | + rm -f "$MANIFEST_FILE" |
| 341 | + rm -f "$MANIFEST_JAR_FILE" |
| 342 | + exit $exit_code |
| 343 | +} |
| 344 | + |
| 345 | +# If the user didn't specify a --classpath_limit, use the default value. |
| 346 | +if [ -z "$CLASSPATH_LIMIT" ]; then |
| 347 | + # Windows per-arg limit MAX_ARG_STRLEN == 8k |
| 348 | + # Linux per-arg limit MAX_ARG_STRLEN == 128k |
| 349 | + is_windows && CLASSPATH_LIMIT=7000 || CLASSPATH_LIMIT=120000 |
| 350 | +fi |
| 351 | + |
| 352 | +#Difference from https://github.com/bazelbuild/bazel/blob/68c7e5a3c679be51f750d44aae146007f0f04b4d/src/main/java/com/google/devtools/build/lib/bazel/rules/java/java_stub_template.txt |
| 353 | +local JARBIN="%jarbin%" |
| 354 | +local PERCENTAGE_LITERAL="%" |
| 355 | +local JARBIN_LITERAL="${PERCENTAGE_LITERAL}jarbin${PERCENTAGE_LITERAL}" |
| 356 | +# if jarbin is evaluated to empty string or not substituted fallback to previous behavior |
| 357 | +# for backwards compatibility |
| 358 | +if [ -z "$JARBIN" ] || [ "$JARBIN" == "$JARBIN_LITERAL" ] ; then |
| 359 | + JARBIN="local_jdk/bin/jar" |
| 360 | +fi |
| 361 | +#Difference ends |
| 362 | + |
| 363 | +if is_windows && (("${#CLASSPATH}" > ${CLASSPATH_LIMIT} )); then |
| 364 | + create_and_run_classpath_jar "${JARBIN}.exe" |
| 365 | +elif (("${#CLASSPATH}" > ${CLASSPATH_LIMIT})); then |
| 366 | + create_and_run_classpath_jar "$JARBIN" |
| 367 | +else |
| 368 | + exec $JAVABIN -classpath $CLASSPATH "${ARGS[@]}" |
| 369 | +fi |
0 commit comments