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); + } } }