-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
java_stub_template.txt leaves orphan Java process when terminated #19036
Comments
Turns out signal handling in Bash is way more complicated than I thought, and is proving to be quite tricky to get right. A couple things I've learned while trying to get this to work reliably:
I'm thinking the only way to get the expected behavior in all cases is going to be to
MANIFEST_JAR_FILE="/tmp/$(shasum $MANIFEST_FILE | cut --fields=1 --delimiter=' ').jar"
# Probably need to do an atomic move to the path to avoid races between multiple instances of the same binary, and may be addition security race conditions here.
$JARBIN cvfm "$MANIFEST_JAR_FILE" "$MANIFEST_FILE" ...
rm -f "$MANIFEST_FILE"
exec $JAVABIN -classpath "$MANIFEST_JAR_FILE" "${ARGS[@]}"
rm -f "$MANIFEST_FILE"
(
sleep 3
rm -f "$MANIFEST_JAR_FILE" # I don't think this would work on Windows if the process still has the jar file open
) &
exec $JAVABIN -classpath "$MANIFEST_JAR_FILE" "${ARGS[@]}"
rm -f "$MANIFEST_FILE"
(
while kill -0 $$ 2>/dev/null; do
sleep 5
done
rm -f "$MANIFEST_JAR_FILE"
) &
exec $JAVABIN -classpath "$MANIFEST_JAR_FILE" "${ARGS[@]}"
I feel like 5 is my favorite, but is probably quite a bit of work. Are the Java rules still native, or are those in Starlark now? rules_scala and rules_kotlin use versions of this launcher, so it would be nice if they could share the Starlark implementation if we decide to go down this route. I feel like 4 is the next best option, but not sure if Any guidance on which of these options would be best? Happy to implement any of these once a decision is made. |
Having Bazel generation the file instead of generating it when the script is executed makes sense to me. The classpath jar was a hack that was added when JDKs didn't support params files, and JDK > 8 supports passing flag files. So I'd consider looking at having it generate a text file with the classpath entries, instead of a classpath jar. There's a FR for that here (it's about using an Is supporting JDK 8 or earlier important to you? |
No, we're on 11. Is Bazel ready to drop support for Java 8 entirely, or are you proposing only fixing the bug for |
I'm not sure that it is. @comius @hvadehra have you given any thought to the timeline for Java 8 support? Vendors are going to be provided Java 8 support through at least 2030, so we're probably stuck with it for a while.
I was wondering about it. I'm OK with landing improvements that only benefit Java > 8, as long as they aren't regressing existing Java 8 support. |
I and @meteorcloudy had a chat some time ago about this. I agree we probably need to support using bazel with java 8 for >5 more years.
+1 |
Description of the bug:
java_binary
s with long classpaths are not properly terminated when the parent bash process receives a TERM or INT signal.When bash receives a TERM signal, it does not forward that signal to the child process, and instead just exits, leaving the orphaned process behind.
When possible, it's best to
exec
the process, but since we want to clean up the temporary files created increate_and_run_classpath_jar
, we can'texec $JAVABIN
like we do in the short-classpath case. bazelbuild/rules_nodejs and aspect-build/rules_js handle this case in their launcher scripts (bazel-contrib/rules_nodejs#246, https://github.com/aspect-build/rules_js/blob/2dfdcbf08fda897a2280c686ed03e4a8b22e6286/js/private/js_binary.sh.tpl#L404-L423) by explicitly trapping the signals and forwarding them to the child process. I believe the Java launcher should do the same.What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.
bazel run //src/java_tools/buildjar/java/com/google/devtools/build/buildjar:BazelJavaBuilder -- --classpath_limit=0 --persistent_worker
pgrep -fa BazelJavaBuilder
bazel run ...
processbash .../BazelJavaBuilder ...
processjava ... com.google.devtools.build.buildjar.BazelJavaBuilder ...
processkill -TERM <PID of the bash process>
pgrep -fa BazelJavaBuilder
java
process is still running even though its parents have exitedWhich operating system are you running Bazel on?
linux
What is the output of
bazel info release
?release 6.2.1
If
bazel info release
returnsdevelopment version
or(@non-git)
, tell us how you built Bazel.No response
What's the output of
git remote get-url origin; git rev-parse master; git rev-parse HEAD
?Is this a regression? If yes, please try to identify the Bazel commit where the bug was introduced.
I believe this bug has existed since
create_and_run_classpath_jar
was added in 102ce6d.Have you found anything relevant by searching the web?
No response
Any other information, logs, or outputs that you want to share?
No response
The text was updated successfully, but these errors were encountered: