📜 ⬆️ ⬇️

Signal Processing in Java

Before me often got up the task to write some Java-service. As an operating system, we mostly use Linux, so the most convenient way to manage these services is to work with them as with demons. That is, we run:
start-stop-daemon - start - make-pidfile - pidfile /var/run/myservice.pid --exec / usr / bin / java - -jar myservice.jar

and stop:
start-stop-daemon --stop --quiet --oknodo --pidfile /var/run/myservice.pid

The --stop command sends the SIGTERM signal to the JVM and the service stops. Everything seems to be quite good, the JVM is completed in the normal manner, unless you need to perform any action after the completion of the service. For example, explicitly free the resource, or write something nice in stdout.

But all is not so bad, the benefit of the JVM since 1.3.1 allows you to process signals. For the answer as - under habrakat.

For signal processing, I once wrote a simple auxiliary class:
import sun.misc.Signal;
import sun.misc.SignalHandler;

public class DiagnosticSignalHandler implements SignalHandler {

// Static method to install the signal handler
public static void install(String signalName, SignalHandler handler) {
Signal signal = new Signal(signalName);
DiagnosticSignalHandler diagnosticSignalHandler = new DiagnosticSignalHandler();
SignalHandler oldHandler = Signal.handle(signal, diagnosticSignalHandler);
diagnosticSignalHandler.setHandler(handler);
diagnosticSignalHandler.setOldHandler(oldHandler);
}
private SignalHandler oldHandler;
private SignalHandler handler;

private DiagnosticSignalHandler() {
}

private void setOldHandler(SignalHandler oldHandler) {
this .oldHandler = oldHandler;
}

private void setHandler(SignalHandler handler) {
this .handler = handler;
}

// Signal handler method
@Override
public void handle(Signal sig) {
System. out .println( "Diagnostic Signal handler called for signal " + sig);
try {
handler.handle(sig);

// Chain back to previous handler, if one exists
if (oldHandler != SIG_DFL && oldHandler != SIG_IGN) {
oldHandler.handle(sig);
}

} catch (Exception e) {
System. out .println( "Signal handler failed, reason " + e);
}
}
}


* This source code was highlighted with Source Code Highlighter .

Example of use:
import sun.misc.Signal;
import sun.misc.SignalHandler;

public class App {
private SomeVeryImportantResource resource;

public static void main(String[] args) {
SignalHandler signalHandler = new SignalHandler() {
@Override
public void handle(Signal sig) {
...
resource.release();
...
}
};
DiagnosticSignalHandler.install( "TERM" , signalHandler);
DiagnosticSignalHandler.install( "INT" , signalHandler);
DiagnosticSignalHandler.install( "ABRT" , signalHandler);
...
resource. lock ();
...
}
}


* This source code was highlighted with Source Code Highlighter .

That's all, nothing complicated. In the handler, we perform the necessary actions and the application is terminated.

In the topic I gave the simplest use case - we catch SIGINT, SIGTERM and SIGABRT. In fact, there are many more types of signals, as well as their uses. A more detailed description is available here:
http://www.ibm.com/developerworks/ibm/library/i-signalhandling/

')

Source: https://habr.com/ru/post/78035/


All Articles