You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by jo...@apache.org on 2022/07/26 08:25:04 UTC
[jackrabbit-oak] 03/03: OAK-9849 write a stacktrace when oak-run is interrupted
This is an automated email from the ASF dual-hosted git repository.
joerghoh pushed a commit to branch OAK-9849
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git
commit 39423f2292a568d4d6675890428032694e875e3a
Author: Joerg Hoh <jh...@adobe.com>
AuthorDate: Tue Jul 26 10:23:48 2022 +0200
OAK-9849 write a stacktrace when oak-run is interrupted
---
.../org/apache/jackrabbit/oak/run/HelpCommand.java | 2 +-
.../java/org/apache/jackrabbit/oak/run/Main.java | 29 ++++++++++++++++++++--
.../java/org/apache/jackrabbit/oak/run/Utils.java | 12 +++++++++
3 files changed, 40 insertions(+), 3 deletions(-)
diff --git a/oak-run/src/main/java/org/apache/jackrabbit/oak/run/HelpCommand.java b/oak-run/src/main/java/org/apache/jackrabbit/oak/run/HelpCommand.java
index d899eb13ab..06fb1bcd76 100644
--- a/oak-run/src/main/java/org/apache/jackrabbit/oak/run/HelpCommand.java
+++ b/oak-run/src/main/java/org/apache/jackrabbit/oak/run/HelpCommand.java
@@ -28,7 +28,7 @@ class HelpCommand implements Command {
public int execute(String... args) throws Exception {
System.err.print("Available run modes: ");
System.err.println(Joiner.on(", ").join(MODES.getModes()));
- return 1;
+ return 0;
}
}
\ No newline at end of file
diff --git a/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java b/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java
index ebcf448405..e29b1fdf7a 100644
--- a/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java
+++ b/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java
@@ -19,6 +19,10 @@ package org.apache.jackrabbit.oak.run;
import org.apache.jackrabbit.oak.run.commons.Command;
import org.apache.jackrabbit.oak.run.commons.Utils;
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
+import java.util.Arrays;
import java.util.Locale;
import static java.util.Arrays.copyOfRange;
@@ -29,7 +33,25 @@ public final class Main {
// Prevent instantiation.
}
+ public static boolean wasInterrupted = true;
+
+ public static final String PROP_PRINT_STACK = "printStackTraceOnSignal";
+
+ public static Thread interruptionHandler = new Thread( () -> {
+ if (wasInterrupted) {
+ System.err.println("oak-run was interrupted by a signal and stops");
+ if (System.getProperty(PROP_PRINT_STACK) != null) {
+ System.err.println("Dumping threads as requested");
+ ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
+ for(ThreadInfo threadInfo : threadMXBean.dumpAllThreads(true, true)) {
+ System.err.println(org.apache.jackrabbit.oak.run.Utils.formatThreadInfo(threadInfo));
+ }
+ }
+ }
+ });
+
public static void main(String[] args) throws Exception {
+ Runtime.getRuntime().addShutdownHook(interruptionHandler);
Utils.printProductInfo(
args,
Main.class.getResourceAsStream("/META-INF/maven/org.apache.jackrabbit/oak-run/pom.properties"));
@@ -46,8 +68,11 @@ public final class Main {
args = copyOfRange(args, 1, args.length);
}
- int statuscode = command.execute(args);
+ int exitcode = command.execute(args);
+ wasInterrupted = false;
+ // when this point is reached, the interruptionHandler is no longer required; there is a slight
+ // chance that the signal is arriving now, but we just ignore this case.
- System.exit(statuscode);
+ System.exit(exitcode);
}
}
diff --git a/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Utils.java b/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Utils.java
index ab69802384..c20d8a3c69 100644
--- a/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Utils.java
+++ b/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Utils.java
@@ -28,6 +28,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
+import java.lang.management.ThreadInfo;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Enumeration;
@@ -371,6 +372,17 @@ class Utils {
return closer;
}
+ public static String formatThreadInfo(ThreadInfo threadInfo) {
+ StringBuilder threadDumpDescription = new StringBuilder();
+ threadDumpDescription.append(String.format("\"%s\" java.lang.Thread.State: %s",
+ threadInfo.getThreadName(), threadInfo.getThreadState()));
+ for (StackTraceElement stackTraceElement : threadInfo.getStackTrace()) {
+ threadDumpDescription.append(System.lineSeparator()).append("\tat ").append(stackTraceElement);
+ }
+ threadDumpDescription.append(System.lineSeparator()).append(System.lineSeparator());
+ return threadDumpDescription.toString();
+ }
+
private static Properties loadAndTransformProps(String cfgPath) throws IOException {
Dictionary dict = ConfigurationHandler.read(new FileInputStream(cfgPath));
Properties props = new Properties();