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();