|
|
#!/usr/bin/env bash
|
||
|
|
# Copyright 2014 The Bazel Authors. All rights reserved.
|
||
|
|
#
|
||
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
|
# you may not use this file except in compliance with the License.
|
||
|
|
# You may obtain a copy of the License at
|
||
|
|
#
|
||
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||
|
|
#
|
||
|
|
# Unless required by applicable law or agreed to in writing, software
|
||
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
|
# See the License for the specific language governing permissions and
|
||
|
|
# limitations under the License.
|
||
|
|
#
|
||
|
|
# This script was generated from java_stub_template.txt. Please
|
||
|
|
# don't edit it directly.
|
||
|
|
#
|
||
|
|
# If present, these flags should either be at the beginning of the command
|
||
|
|
# line, or they should be wrapped in a --wrapper_script_flag=FLAG argument.
|
||
|
|
#
|
||
|
|
# --debug Launch the JVM in remote debugging mode listening
|
||
|
|
# --debug=<port> to the specified port or the port set in the
|
||
|
|
# DEFAULT_JVM_DEBUG_PORT environment variable (e.g.
|
||
|
|
# 'export DEFAULT_JVM_DEBUG_PORT=8000') or else the
|
||
|
|
# default port of 5005. The JVM starts suspended
|
||
|
|
# unless the DEFAULT_JVM_DEBUG_SUSPEND environment
|
||
|
|
# variable is set to 'n'.
|
||
|
|
# --main_advice=<class> Run an alternate main class with the usual main
|
||
|
|
# program and arguments appended as arguments.
|
||
|
|
# --main_advice_classpath=<classpath>
|
||
|
|
# Prepend additional class path entries.
|
||
|
|
# --jvm_flag=<flag> Pass <flag> to the "java" command itself.
|
||
|
|
# <flag> may contain spaces. Can be used multiple times.
|
||
|
|
# --jvm_flags=<flags> Pass space-separated flags to the "java" command
|
||
|
|
# itself. Can be used multiple times.
|
||
|
|
# --singlejar Start the program from the packed-up deployment
|
||
|
|
# jar rather than from the classpath.
|
||
|
|
# --print_javabin Print the location of java executable binary and exit.
|
||
|
|
# --classpath_limit=<length>
|
||
|
|
# Specify the maximum classpath length. If the classpath
|
||
|
|
# is shorter, this script passes it to Java as a command
|
||
|
|
# line flag, otherwise it creates a classpath jar.
|
||
|
|
#
|
||
|
|
# The remainder of the command line is passed to the program.
|
||
|
|
|
||
|
|
set -o posix
|
||
|
|
|
||
|
|
# Make it easy to insert 'set -x' or similar commands when debugging problems with this script.
|
||
|
|
eval "$JAVA_STUB_DEBUG"
|
||
|
|
|
||
|
|
# Prevent problems where the caller has exported CLASSPATH, causing our
|
||
|
|
# computed value to be copied into the environment and double-counted
|
||
|
|
# against the argv limit.
|
||
|
|
unset CLASSPATH
|
||
|
|
|
||
|
|
JVM_FLAGS_CMDLINE=()
|
||
|
|
|
||
|
|
# Processes an argument for the wrapper. Returns 0 if the given argument
|
||
|
|
# was recognized as an argument for this wrapper, and 1 if it was not.
|
||
|
|
function process_wrapper_argument() {
|
||
|
|
case "$1" in
|
||
|
|
--debug) JVM_DEBUG_PORT="${DEFAULT_JVM_DEBUG_PORT:-5005}" ;;
|
||
|
|
--debug=*) JVM_DEBUG_PORT="${1#--debug=}" ;;
|
||
|
|
--main_advice=*) MAIN_ADVICE="${1#--main_advice=}" ;;
|
||
|
|
--main_advice_classpath=*) MAIN_ADVICE_CLASSPATH="${1#--main_advice_classpath=}" ;;
|
||
|
|
--jvm_flag=*) JVM_FLAGS_CMDLINE+=( "${1#--jvm_flag=}" ) ;;
|
||
|
|
--jvm_flags=*) JVM_FLAGS_CMDLINE+=( ${1#--jvm_flags=} ) ;;
|
||
|
|
--singlejar) SINGLEJAR=1 ;;
|
||
|
|
--print_javabin) PRINT_JAVABIN=1 ;;
|
||
|
|
--classpath_limit=*)
|
||
|
|
CLASSPATH_LIMIT="${1#--classpath_limit=}"
|
||
|
|
echo "$CLASSPATH_LIMIT" | grep -q '^[0-9]\+$' || \
|
||
|
|
die "ERROR: $self failed, --classpath_limit is not a number"
|
||
|
|
;;
|
||
|
|
*)
|
||
|
|
return 1 ;;
|
||
|
|
esac
|
||
|
|
return 0
|
||
|
|
}
|
||
|
|
|
||
|
|
die() {
|
||
|
|
printf "%s: $1\n" "$0" "${@:2}" >&2
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
|
||
|
|
# Windows
|
||
|
|
function is_windows() {
|
||
|
|
[[ "${OSTYPE}" =~ msys* ]] || [[ "${OSTYPE}" =~ cygwin* ]]
|
||
|
|
}
|
||
|
|
|
||
|
|
# macOS
|
||
|
|
function is_macos() {
|
||
|
|
[[ "${OSTYPE}" =~ darwin* ]]
|
||
|
|
}
|
||
|
|
|
||
|
|
# Parse arguments sequentially until the first unrecognized arg is encountered.
|
||
|
|
# Scan the remaining args for --wrapper_script_flag=X options and process them.
|
||
|
|
ARGS=()
|
||
|
|
for ARG in "$@"; do
|
||
|
|
if [[ "$ARG" == --wrapper_script_flag=* ]]; then
|
||
|
|
process_wrapper_argument "${ARG#--wrapper_script_flag=}" \
|
||
|
|
|| die "invalid wrapper argument '%s'" "$ARG"
|
||
|
|
elif [[ "${#ARGS}" -gt 0 ]] || ! process_wrapper_argument "$ARG"; then
|
||
|
|
ARGS+=( "$ARG" )
|
||
|
|
fi
|
||
|
|
done
|
||
|
|
|
||
|
|
# Find our runfiles tree. We need this to construct the classpath
|
||
|
|
# (unless --singlejar was passed).
|
||
|
|
#
|
||
|
|
# Call this program X. X was generated by a java_binary or java_test rule.
|
||
|
|
# X may be invoked in many ways:
|
||
|
|
# 1a) directly by a user, with $0 in the output tree
|
||
|
|
# 1b) via 'bazel run' (similar to case 1a)
|
||
|
|
# 2) directly by a user, with $0 in X's runfiles tree
|
||
|
|
# 3) by another program Y which has a data dependency on X, with $0 in Y's runfiles tree
|
||
|
|
# 4) via 'bazel test'
|
||
|
|
# 5) by a genrule cmd, with $0 in the output tree
|
||
|
|
# 6) case 3 in the context of a genrule
|
||
|
|
#
|
||
|
|
# For case 1, $0 will be a regular file, and the runfiles tree will be
|
||
|
|
# at $0.runfiles.
|
||
|
|
# For case 2, $0 will be a symlink to the file seen in case 1.
|
||
|
|
# For case 3, we use Y's runfiles tree, which will be a superset of X's.
|
||
|
|
# For case 4, $JAVA_RUNFILES and $TEST_SRCDIR should already be set.
|
||
|
|
# Case 5 is handled like case 1.
|
||
|
|
# Case 6 is handled like case 3.
|
||
|
|
|
||
|
|
# If we are running on Windows, convert the windows style path
|
||
|
|
# to unix style for detecting runfiles path.
|
||
|
|
if is_windows; then
|
||
|
|
self=$(cygpath --unix "$0")
|
||
|
|
else
|
||
|
|
self="$0"
|
||
|
|
fi
|
||
|
|
|
||
|
|
if [[ "$self" != /* ]]; then
|
||
|
|
self="$PWD/$self"
|
||
|
|
fi
|
||
|
|
|
||
|
|
if [[ "$SINGLEJAR" != 1 || "%needs_runfiles%" == 1 ]]; then
|
||
|
|
if [[ -z "$JAVA_RUNFILES" ]]; then
|
||
|
|
while true; do
|
||
|
|
if [[ -e "$self.runfiles" ]]; then
|
||
|
|
JAVA_RUNFILES="$self.runfiles"
|
||
|
|
break
|
||
|
|
fi
|
||
|
|
if [[ $self == *.runfiles/* ]]; then
|
||
|
|
JAVA_RUNFILES="${self%.runfiles/*}.runfiles"
|
||
|
|
break
|
||
|
|
fi
|
||
|
|
if [[ ! -L "$self" ]]; then
|
||
|
|
break
|
||
|
|
fi
|
||
|
|
readlink="$(readlink "$self")"
|
||
|
|
if [[ "$readlink" = /* ]]; then
|
||
|
|
self="$readlink"
|
||
|
|
else
|
||
|
|
# resolve relative symlink
|
||
|
|
self="${self%/*}/$readlink"
|
||
|
|
fi
|
||
|
|
done
|
||
|
|
if [[ -n "$JAVA_RUNFILES" ]]; then
|
||
|
|
export TEST_SRCDIR=${TEST_SRCDIR:-$JAVA_RUNFILES}
|
||
|
|
elif [[ -f "${self}_deploy.jar" && "%needs_runfiles%" == 0 ]]; then
|
||
|
|
SINGLEJAR=1;
|
||
|
|
else
|
||
|
|
die 'Cannot locate runfiles directory. (Set $JAVA_RUNFILES to inhibit searching.)'
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
|
||
|
|
# If we are running on Windows, we need a windows style runfiles path for constructing CLASSPATH
|
||
|
|
if is_windows; then
|
||
|
|
JAVA_RUNFILES=$(cygpath --windows "$JAVA_RUNFILES")
|
||
|
|
fi
|
||
|
|
|
||
|
|
export JAVA_RUNFILES
|
||
|
|
export RUNFILES_MANIFEST_FILE="${JAVA_RUNFILES}/MANIFEST"
|
||
|
|
export RUNFILES_MANIFEST_ONLY=%runfiles_manifest_only%
|
||
|
|
|
||
|
|
if [ -z "$RUNFILES_MANIFEST_ONLY" ]; then
|
||
|
|
function rlocation() {
|
||
|
|
if [[ "$1" = /* ]]; then
|
||
|
|
echo $1
|
||
|
|
else
|
||
|
|
echo "$(dirname $RUNFILES_MANIFEST_FILE)/$1"
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
else
|
||
|
|
if ! is_macos; then
|
||
|
|
# Read file into my_array
|
||
|
|
oifs=$IFS
|
||
|
|
IFS=$'\n'
|
||
|
|
my_array=( $(sed -e 's/\r//g' "$RUNFILES_MANIFEST_FILE") )
|
||
|
|
IFS=$oifs
|
||
|
|
|
||
|
|
# Process each runfile line into a [key,value] entry in runfiles_array
|
||
|
|
# declare -A is not supported on macOS because an old version of bash is used.
|
||
|
|
declare -A runfiles_array
|
||
|
|
for line in "${my_array[@]}"
|
||
|
|
do
|
||
|
|
line_split=($line)
|
||
|
|
runfiles_array[${line_split[0]}]=${line_split[@]:1}
|
||
|
|
done
|
||
|
|
fi
|
||
|
|
|
||
|
|
function rlocation() {
|
||
|
|
if [[ "$1" = /* ]]; then
|
||
|
|
echo $1
|
||
|
|
else
|
||
|
|
if is_macos; then
|
||
|
|
# Print the rest of line after the first space
|
||
|
|
# First, set the first column to empty and print rest of the line
|
||
|
|
# Second, use a trick of awk to remove leading and trailing spaces.
|
||
|
|
echo $(grep "^$1 " $RUNFILES_MANIFEST_FILE | awk '{ $1=""; print }' | awk '{ $1=$1; print }')
|
||
|
|
else
|
||
|
|
echo ${runfiles_array[$1]}
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
fi
|
||
|
|
|
||
|
|
if is_macos || [[ ${OSTYPE} == "freebsd" ]]; then
|
||
|
|
function md5func() { md5 -q $@ ; }
|
||
|
|
else
|
||
|
|
function md5func() { md5sum $@ | awk '{print $1}' ; }
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Set JAVABIN to the path to the JVM launcher.
|
||
|
|
%javabin%
|
||
|
|
|
||
|
|
if [[ "$PRINT_JAVABIN" == 1 || "%java_start_class%" == "--print_javabin" ]]; then
|
||
|
|
echo -n "$JAVABIN"
|
||
|
|
exit 0
|
||
|
|
fi
|
||
|
|
|
||
|
|
if [[ "$SINGLEJAR" == 1 ]]; then
|
||
|
|
CLASSPATH="${self}_deploy.jar"
|
||
|
|
# Check for the deploy jar now. If it doesn't exist, we can print a
|
||
|
|
# more helpful error message than the JVM.
|
||
|
|
[[ -r "$CLASSPATH" ]] \
|
||
|
|
|| die "Option --singlejar was passed, but %s does not exist.\n (You may need to build it explicitly.)" "$CLASSPATH"
|
||
|
|
else
|
||
|
|
# Create the shortest classpath we can, by making it relative if possible.
|
||
|
|
RUNPATH="${JAVA_RUNFILES}/%workspace_prefix%"
|
||
|
|
RUNPATH="${RUNPATH#$PWD/}"
|
||
|
|
CLASSPATH=%classpath%
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Export the locations which will be used to find the location of the classes from the classpath file.
|
||
|
|
export SELF_LOCATION="$self"
|
||
|
|
export CLASSLOADER_PREFIX_PATH="${RUNPATH}"
|
||
|
|
|
||
|
|
# If using Jacoco in offline instrumentation mode, the CLASSPATH contains instrumented files.
|
||
|
|
# We need to make the metadata jar with uninstrumented classes available for generating
|
||
|
|
# the lcov-compatible coverage report, and we don't want it on the classpath.
|
||
|
|
%set_jacoco_metadata%
|
||
|
|
%set_jacoco_main_class%
|
||
|
|
%set_jacoco_java_runfiles_root%
|
||
|
|
|
||
|
|
if [[ -n "$JVM_DEBUG_PORT" ]]; then
|
||
|
|
JVM_DEBUG_SUSPEND=${DEFAULT_JVM_DEBUG_SUSPEND:-"y"}
|
||
|
|
JVM_DEBUG_FLAGS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=${JVM_DEBUG_SUSPEND},address=${JVM_DEBUG_PORT}"
|
||
|
|
|
||
|
|
if [[ "$PERSISTENT_TEST_RUNNER" == "true" ]]; then
|
||
|
|
JVM_DEBUG_FLAGS+=",quiet=y"
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
|
||
|
|
if [[ -n "$MAIN_ADVICE_CLASSPATH" ]]; then
|
||
|
|
CLASSPATH="${MAIN_ADVICE_CLASSPATH}:${CLASSPATH}"
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Check if TEST_TMPDIR is available to use for scratch.
|
||
|
|
if [[ -n "$TEST_TMPDIR" && -d "$TEST_TMPDIR" ]]; then
|
||
|
|
JVM_FLAGS+=" -Djava.io.tmpdir=$TEST_TMPDIR"
|
||
|
|
fi
|
||
|
|
|
||
|
|
ARGS=(
|
||
|
|
${JVM_DEBUG_FLAGS}
|
||
|
|
${JVM_FLAGS}
|
||
|
|
%jvm_flags%
|
||
|
|
"${JVM_FLAGS_CMDLINE[@]}"
|
||
|
|
${MAIN_ADVICE}
|
||
|
|
%java_start_class%
|
||
|
|
"${ARGS[@]}")
|
||
|
|
|
||
|
|
|
||
|
|
function create_and_run_classpath_jar() {
|
||
|
|
# Build class path as one single string separated by spaces
|
||
|
|
MANIFEST_CLASSPATH=""
|
||
|
|
if is_windows; then
|
||
|
|
IFS=';'
|
||
|
|
URI_PREFIX="file:/" # e.g. "file:/C:/temp/foo.jar"
|
||
|
|
else
|
||
|
|
IFS=':'
|
||
|
|
URI_PREFIX="file:$(pwd)/" # e.g. "file:/usr/local/foo.jar"
|
||
|
|
fi
|
||
|
|
for x in $CLASSPATH; do
|
||
|
|
# Add file:/ prefix and escaped space characters, it should be a URI.
|
||
|
|
x="${URI_PREFIX}${x// /%20}"
|
||
|
|
MANIFEST_CLASSPATH="$MANIFEST_CLASSPATH $x"
|
||
|
|
done
|
||
|
|
unset IFS
|
||
|
|
|
||
|
|
# Create manifest file
|
||
|
|
MANIFEST_FILE="$(mktemp -t XXXXXXXX.jar_manifest)"
|
||
|
|
|
||
|
|
(
|
||
|
|
echo "Manifest-Version: 1.0"
|
||
|
|
CLASSPATH_LINE="Class-Path:$MANIFEST_CLASSPATH"
|
||
|
|
# No line in the MANIFEST.MF file may be longer than 72 bytes.
|
||
|
|
# A space prefix indicates the line is still the content of the last attribute.
|
||
|
|
for ((i = 0; i < "${#CLASSPATH_LINE}"; i += 71)); do
|
||
|
|
PREFIX=" "
|
||
|
|
if ((i == 0)); then
|
||
|
|
PREFIX=""
|
||
|
|
fi
|
||
|
|
echo "$PREFIX${CLASSPATH_LINE:$i:71}"
|
||
|
|
done
|
||
|
|
echo "Created-By: Bazel"
|
||
|
|
) >$MANIFEST_FILE
|
||
|
|
|
||
|
|
# Create classpath JAR file
|
||
|
|
MANIFEST_JAR_FILE="$(mktemp -t XXXXXXXX-classpath.jar)"
|
||
|
|
if is_windows; then
|
||
|
|
MANIFEST_JAR_FILE="$(cygpath --windows "$MANIFEST_JAR_FILE")"
|
||
|
|
MANIFEST_FILE="$(cygpath --windows "$MANIFEST_FILE")"
|
||
|
|
fi
|
||
|
|
JARBIN="${JARBIN:-$(rlocation "$1")}"
|
||
|
|
$JARBIN cvfm "$MANIFEST_JAR_FILE" "$MANIFEST_FILE" >/dev/null || \
|
||
|
|
die "ERROR: $self failed because $JARBIN failed"
|
||
|
|
|
||
|
|
# Execute JAVA command
|
||
|
|
$JAVABIN -classpath "$MANIFEST_JAR_FILE" "${ARGS[@]}"
|
||
|
|
exit_code=$?
|
||
|
|
rm -f "$MANIFEST_FILE"
|
||
|
|
rm -f "$MANIFEST_JAR_FILE"
|
||
|
|
exit $exit_code
|
||
|
|
}
|
||
|
|
|
||
|
|
# If the user didn't specify a --classpath_limit, use the default value.
|
||
|
|
if [ -z "$CLASSPATH_LIMIT" ]; then
|
||
|
|
# Windows per-arg limit MAX_ARG_STRLEN == 8k
|
||
|
|
# Linux per-arg limit MAX_ARG_STRLEN == 128k
|
||
|
|
is_windows && CLASSPATH_LIMIT=7000 || CLASSPATH_LIMIT=120000
|
||
|
|
fi
|
||
|
|
|
||
|
|
if is_windows && (("${#CLASSPATH}" > ${CLASSPATH_LIMIT} )); then
|
||
|
|
create_and_run_classpath_jar "local_jdk/bin/jar.exe"
|
||
|
|
elif (("${#CLASSPATH}" > ${CLASSPATH_LIMIT})); then
|
||
|
|
create_and_run_classpath_jar "local_jdk/bin/jar"
|
||
|
|
else
|
||
|
|
exec $JAVABIN -classpath $CLASSPATH "${ARGS[@]}"
|
||
|
|
fi
|