Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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));
Expand All @@ -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);
}
}

}
Loading