From cccfa8a59873408e60b84f5a53154f263b25adc4 Mon Sep 17 00:00:00 2001 From: Holger Friedrich Date: Sun, 6 Sep 2026 16:28:05 +0200 Subject: [PATCH] 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. --- .../diagnostic/core/internal/Activator.java | 14 ++---- .../diagnostic/core/internal/DumpHandler.java | 47 +++++++++++++++---- 2 files changed, 42 insertions(+), 19 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 4b84bb750a5..b3c195ac87b 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 e) { + // Will happen if sun.misc.Signal is not available } } } 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 a70371c85b7..6bf2cb10268 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 @@ 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,20 +29,41 @@ 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) -> { + handle(); + return null; + } + ); + + handleMethod = signalClass.getMethod("handle", signalClass, signalHandlerClass); + signal = signalClass.getConstructor(String.class).newInstance(SIGNAL); + previous = handleMethod.invoke(null, signal, signalHandler); } - - public void handle(Signal signal) { + + private void handle() { SimpleDateFormat dumpFormat = new SimpleDateFormat("yyyy-MM-dd_HHmmss-SSS"); String fileName = "dump-" + dumpFormat.format(new Date()) + ".zip"; DumpDestination destination = new ZipDumpDestination(new File(fileName)); @@ -49,7 +72,11 @@ public void handle(Signal signal) { @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); + } } }