Skip to content

Commit cdd3898

Browse files
committed
Use jar from java runtime and not local_jdk
Work around and somewhat prepare for resolution of bazelbuild/bazel#6955
1 parent ebc32f0 commit cdd3898

File tree

7 files changed

+406
-5
lines changed

7 files changed

+406
-5
lines changed

WORKSPACE

+7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
workspace(name = "io_bazel_rules_scala")
22

3+
#used to test what happens when classpath is too large
4+
#until https://github.com/bazelbuild/bazel/issues/6955 is resolved
5+
local_repository(
6+
name = "java_stub_template",
7+
path = "java_stub_template"
8+
)
9+
310
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
411
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
512
load("//scala:scala.bzl", "scala_repositories")

java_stub_template/WORKSPACE

Whitespace-only changes.

java_stub_template/file/BUILD.bazel

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
filegroup(
2+
name = "file",
3+
srcs = ["file.txt"],
4+
visibility = ["//visibility:public"],
5+
)

java_stub_template/file/file.txt

+369
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,369 @@
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

Comments
 (0)