This is an automated email from the ASF dual-hosted git repository.

jbonofre pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/karaf.git


The following commit(s) were added to refs/heads/main by this push:
     new 327ea0d85a Install the SIGHUP dump handler reflectively (#2852)
327ea0d85a is described below

commit 327ea0d85a36cf4b5b0cd888f0eeee870e632228
Author: Holger Friedrich <[email protected]>
AuthorDate: Wed Sep 9 07:43:55 2026 +0200

    Install the SIGHUP dump handler reflectively (#2852)
    
    * Install the SIGHUP dump handler reflectively
    
    This avoids warnings during compilation which are printed in every CI
    summary.
    sun.misc.Signal and SignalHandler are internal proprietary APIs.
    The approach is taken over from Main.java.
    
    * Address review findings
---
 .../karaf/diagnostic/core/internal/Activator.java  | 14 ++---
 .../diagnostic/core/internal/DumpHandler.java      | 65 +++++++++++++++++-----
 2 files changed, 56 insertions(+), 23 deletions(-)

diff --git 
a/diagnostic/boot/src/main/java/org/apache/karaf/diagnostic/core/internal/Activator.java
 
b/diagnostic/boot/src/main/java/org/apache/karaf/diagnostic/core/internal/Activator.java
index 4b84bb750a..911d475954 100644
--- 
a/diagnostic/boot/src/main/java/org/apache/karaf/diagnostic/core/internal/Activator.java
+++ 
b/diagnostic/boot/src/main/java/org/apache/karaf/diagnostic/core/internal/Activator.java
@@ -16,28 +16,24 @@
  */
 package org.apache.karaf.diagnostic.core.internal;
 
-import java.io.Closeable;
-
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 
 public class Activator implements BundleActivator {
-    Closeable dumpHandler;
+    DumpHandler dumpHandler;
 
     public void start(BundleContext context) throws Exception {
         if (!isWindows()) {
-            ClassLoader cl = this.getClass().getClassLoader();
             try {
-                Class<?> dumpHandlerClazz = 
cl.loadClass("org.apache.karaf.diagnostic.core.internal.DumpHandler");
-                dumpHandler = (Closeable) 
dumpHandlerClazz.getConstructor(BundleContext.class).newInstance(context);
-            } catch (Throwable e) {
-                // Will happen if sun.misc.SignalHandler is not available
+                dumpHandler = new DumpHandler(context);
+            } catch (Exception | LinkageError e) {
+                // Will happen if sun.misc.Signal is not available or cannot 
be initialized
             }
         }
     }
 
     public void stop(BundleContext context) throws Exception {
-        if (dumpHandler != null && !isWindows()) {
+        if (dumpHandler != null) {
             dumpHandler.close();
         }
     }
diff --git 
a/diagnostic/boot/src/main/java/org/apache/karaf/diagnostic/core/internal/DumpHandler.java
 
b/diagnostic/boot/src/main/java/org/apache/karaf/diagnostic/core/internal/DumpHandler.java
index a70371c85b..34d454a192 100644
--- 
a/diagnostic/boot/src/main/java/org/apache/karaf/diagnostic/core/internal/DumpHandler.java
+++ 
b/diagnostic/boot/src/main/java/org/apache/karaf/diagnostic/core/internal/DumpHandler.java
@@ -19,6 +19,8 @@ package org.apache.karaf.diagnostic.core.internal;
 import java.io.Closeable;
 import java.io.File;
 import java.io.IOException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 
@@ -27,29 +29,64 @@ import org.apache.karaf.diagnostic.core.DumpDestination;
 import org.apache.karaf.diagnostic.core.common.ZipDumpDestination;
 import org.osgi.framework.BundleContext;
 
-import sun.misc.Signal;
-import sun.misc.SignalHandler;
+/**
+ * Creates a dump when the process receives SIGHUP. sun.misc.Signal is used 
reflectively, as in
+ * org.apache.karaf.main.Main, to avoid the compiler warning about internal 
proprietary API.
+ */
+public class DumpHandler implements Closeable {
 
-public class DumpHandler implements SignalHandler, Closeable {
     private static final String SIGNAL = "HUP";
-    private BundleContext context;
-    private SignalHandler previous;
 
-    public DumpHandler(BundleContext context) {
+    private final BundleContext context;
+    private final Method handleMethod;
+    private final Object signal;
+    private final Object previous;
+
+    public DumpHandler(BundleContext context) throws Exception {
         this.context = context;
-        previous = sun.misc.Signal.handle(new Signal(SIGNAL), this);
+
+        final Class<?> signalClass = Class.forName("sun.misc.Signal");
+        final Class<?> signalHandlerClass = 
Class.forName("sun.misc.SignalHandler");
+
+        Object signalHandler = 
Proxy.newProxyInstance(getClass().getClassLoader(),
+            new Class<?>[] {
+                signalHandlerClass
+            },
+                (proxy, method, args) -> {
+                    if ("handle".equals(method.getName())) {
+                        handle();
+                        return null;
+                    }
+                    // Object methods such as equals, hashCode and toString
+                    return method.invoke(this, args);
+                }
+        );
+
+        handleMethod = signalClass.getMethod("handle", signalClass, 
signalHandlerClass);
+        signal = signalClass.getConstructor(String.class).newInstance(SIGNAL);
+        previous = handleMethod.invoke(null, signal, signalHandler);
     }
-    
-    public void handle(Signal signal) {
-        SimpleDateFormat dumpFormat = new 
SimpleDateFormat("yyyy-MM-dd_HHmmss-SSS");
-        String fileName = "dump-" + dumpFormat.format(new Date()) + ".zip";
-        DumpDestination destination = new ZipDumpDestination(new 
File(fileName));
-        Dump.dump(context, destination, false, false);
+
+    /**
+     * Creates the dump on a short-lived thread, so that the JVM signal 
dispatch thread is not
+     * blocked while everything is collected and zipped.
+     */
+    private void handle() {
+        new Thread(() -> {
+            SimpleDateFormat dumpFormat = new 
SimpleDateFormat("yyyy-MM-dd_HHmmss-SSS");
+            String fileName = "dump-" + dumpFormat.format(new Date()) + ".zip";
+            DumpDestination destination = new ZipDumpDestination(new 
File(fileName));
+            Dump.dump(context, destination, false, false);
+        }, "karaf-diagnostic-dump").start();
     }
 
     @Override
     public void close() throws IOException {
-        sun.misc.Signal.handle(new Signal(SIGNAL), previous);
+        try {
+            handleMethod.invoke(null, signal, previous);
+        } catch (Exception e) {
+            throw new IOException("Cannot restore the previous " + SIGNAL + " 
handler", e);
+        }
     }
 
 }

Reply via email to