Varun
Varun

Reputation: 5061

Check if process is running on windows/linux

i have a process

Runtime rt = Runtime.getRuntime() ;
Process p = rt.exec(filebase+port+"/hlds.exe +ip "+ip+" +maxplayers "+players+ " -game cstrike -console +port "+port+" -nojoy -noipx -heapsize 250000 +map de_dust2 +servercfgfile server.cfg +lservercfgfile +mapcyclefile mapcycle.txt +motdfile motd.txt +logsdir logs -zone 2048",null,  new File(filebase+port)) ;

i want to keep a check on this process whether its running or has crashed in case of crash want to restart it, this Process can have multiple instance available depending upon the port

Can i trace this thing on Linux as well as on windows? Read some articles on it but this 1 is bit different, since it involves multiple occurrences and have to check on some particular process only

Upvotes: 9

Views: 27177

Answers (7)

pan
pan

Reputation: 1967

In java 9, you can use the isAlive() method to check if a process is stil running like this:

Runtime rt = Runtime.getRuntime() ;
Process p = rt.exec(filebase+port+"/hlds.exe +ip "+ip+" +maxplayers "+players+ " -game cstrike -console +port "+port+" -nojoy -noipx -heapsize 250000 +map de_dust2 +servercfgfile server.cfg +lservercfgfile +mapcyclefile mapcycle.txt +motdfile motd.txt +logsdir logs -zone 2048",null,  new File(filebase+port)) ;
boolean isRunning = p.toHandle.isAlive();

Upvotes: 0

Nadar
Nadar

Reputation: 151

For pre Java 8 code, I'm using reflection with a fallback to catching IllegalThreadStateException. The reflection will only work on instances of ProcessImpl, but as that's what's returned by ProcessBuilder it's usually the case for me.

    public static boolean isProcessIsAlive(@Nullable Process process) {
    if (process == null) {
        return false;
    }
    // XXX replace with Process.isAlive() in Java 8
    try {
        Field field;
        field = process.getClass().getDeclaredField("handle");
        field.setAccessible(true);
        long handle = (long) field.get(process);
        field = process.getClass().getDeclaredField("STILL_ACTIVE");
        field.setAccessible(true);
        int stillActive = (int) field.get(process);
        Method method;
        method = process.getClass().getDeclaredMethod("getExitCodeProcess", long.class);
        method.setAccessible(true);
        int exitCode = (int) method.invoke(process, handle);
        return exitCode == stillActive;
    } catch (Exception e) {
        // Reflection failed, use the backup solution
    }
    try {
        process.exitValue();
        return false;
    } catch (IllegalThreadStateException e) {
        return true;
    }
}

Upvotes: 1

Pace
Pace

Reputation: 43937

As of Java 8 you can do:

process.isAlive()

Upvotes: 2

jobukkit
jobukkit

Reputation: 2670

public class ProcessEndNotifier extends Thread
{
    Process process;
    MyClass classThatNeedsToBeNotified;

    public ProcessEndNotifier(MyClass classThatNeedsToBeNotified, Process process)
    {
        this.process = process;
        this.classThatNeedsToBeNotified = classThatNeedsToBeNotified;
    }

    @Override
    public void run()
    {
        try {
            process.waitFor();
        }
        catch (InterruptedException e) {
            classThatNeedsToBeNotified.processEnded();
        }
        classThatNeedsToBeNotified.processEnded();
    }
}

Now you can know if a process in running like this:

public class MyClass
{
    boolean isProcessRunning;       

    public static void main(String[]args)
    {
        Process process = Runtime.getRuntime().exec("foo -bar");
        isProcessRunning = true;
        new ProcessEndNotifier(this, process).run();
    }

    public void processEnded()
    {
        isProcessRunning = false;
        // Or just do stuff here!
    }
}

Upvotes: 0

AlikElzin-kilaka
AlikElzin-kilaka

Reputation: 36051

boolean isRunning(Process process) {
    try {
        process.exitValue();
        return false;
    } catch (Exception e) {
        return true;
    }
}

See http://docs.oracle.com/javase/6/docs/api/java/lang/Process.html#exitValue()

Upvotes: 25

dj_segfault
dj_segfault

Reputation: 12459

Java 5 and on have a way to handle this using java.util.concurrent.Future.

A Future represents the result of an asynchronous computation. Methods are provided to check if the computation is complete, to wait for its completion, and to retrieve the result of the computation. The result can only be retrieved using method get when the computation has completed, blocking if necessary until it is ready. Cancellation is performed by the cancel method. Additional methods are provided to determine if the task completed normally or was cancelled. Once a computation has completed, the computation cannot be cancelled. If you would like to use a Future for the sake of cancellability but not provide a usable result, you can declare types of the form Future and return null as a result of the underlying task.

Upvotes: 0

lobster1234
lobster1234

Reputation: 7779

You can do a p.waitFor() so the thread that executed the statement waits till the process is complete. You can then do the cleanup/restart logic right after, as that code will get executed when the process dies. However I am not sure how this would work if the process hangs instead of dying, but this could be worth a try. By the way I would recommend using Java Service Wrapper and supervisord in your case if this is something you're going to do on production.

Upvotes: 3

Related Questions