Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how can I kill a Linux process in java with SIGKILL Process.destroy() does SIGTERM

In Linux when I run the destroy function on java.lang.Process object (Which is true typed java.lang.UNIXProcess ) it sends a SIGTERM signal to process, is there a way to kill it with SIGKILL?

like image 692
ekeren Avatar asked Jun 01 '10 13:06

ekeren


People also ask

In what cases can Sigkill and not Sigterm will fail to kill the process?

SIGKILL cannot be blocked or ignored ( SIGSTOP can't either). A process can become unresponsive to the signal if it is blocked "inside" a system call (waiting on I/O is one example - waiting on I/O on a failed NFS filesystem that is hard-mounted without the intr option for example).

Can a process ignore Sigterm?

The SIGTERM signal is a generic signal used to cause program termination. Unlike SIGKILL , this signal can be blocked, handled, and ignored.

How do you kill a Java process gracefully?

In your application implement a shutdown hook. When you want to shut down your JVM gracefully, install a Java Agent that calls System. exit() using the Attach API.


2 Answers

Not using pure Java.

Your simplest alternative is to use Runtime.exec() to run a kill -9 <pid> command as an external process.

Unfortunately, it is not that simple to get hold of the PID. You will either need to use reflection black-magic to access the private int pid field, or mess around with the output from the ps command.

UPDATE - actually, there is another way. Create a little utility (C program, shell script, whatever) that will run the real external application. Code the utility so that it remembers the PID of the child process, and sets up a signal handler for SIGTERM that will SIGKILL the child process.

like image 146
Stephen C Avatar answered Oct 04 '22 05:10

Stephen C


Stephen his answer is correct. I wrote what he said:

public static int getUnixPID(Process process) throws Exception
{
    System.out.println(process.getClass().getName());
    if (process.getClass().getName().equals("java.lang.UNIXProcess"))
    {
        Class cl = process.getClass();
        Field field = cl.getDeclaredField("pid");
        field.setAccessible(true);
        Object pidObject = field.get(process);
        return (Integer) pidObject;
    } else
    {
        throw new IllegalArgumentException("Needs to be a UNIXProcess");
    }
}

public static int killUnixProcess(Process process) throws Exception
{
    int pid = getUnixPID(process);
    return Runtime.getRuntime().exec("kill " + pid).waitFor();
}

You can also get the pid this way:

public static int getPID() {
  String tmp = java.lang.management.ManagementFactory.getRuntimeMXBean().getName();
  tmp = tmp.split("@")[0];
  return Integer.valueOf(tmp);
}
like image 34
Martijn Courteaux Avatar answered Oct 04 '22 05:10

Martijn Courteaux