Managing outside programs within Java

Hey guys.

I am writing a program that is supposed to help manage an online server. Essentially, the program that runs constantly to handle connections is written in C or something like that and goes through the DOS Box (or similar medium) to display output. Unfortunately, it has some sort of bug where nobody can log on if certain “crash” conditions happen. Normally, I could scan the output of the program to see if an error has popped up, but it doesn’t seem to know there has been one. As such, it needs to be manually restarted.

That’s where my program comes in. It essentially has a timer that checks every hour if there are any users connected to the server (using SQL queries). If nobody is, then it forcibly restarts the server process. I know how to launch the process from within my program, but I have no idea how to quit it first, which is necessary for a restart.

One idea I had was that maybe I could have my program start the program in the first place, then save a pointer to the Runtime.


if (System.getProperty("os.name").contains("Windows"))
{
	String[] args = {"rundll32","SHELL32.DLL,ShellExec_RunDLL",locations[1]};
	Runtime.getRuntime().exec(args,null,new File(locations[0]));
}
else if (System.getProperty("os.name").equals("Mac OS X"))
{
	String[] args = {"open",locations[1]};
	Runtime.getRuntime().exec(args,null,new File(locations[0]));
}

Essentially I would just say Process p = Runtime.getRuntime().exec(args,null,new File(locations[0])); Then I can use Java to quit the Process object.

Would this approach work? Also, I would rather do it so the program just has absolute control and doesn’t need to keep track of the Process, so if there is a way to do it like that I would rather.

Thanks.

[quote]Would this approach work?
[/quote]
Yup! :wink:

[quote]Also, I would rather do it so the program just has absolute control and doesn’t need to keep track of the Process, so if there is a way to do it like that I would rather.
[/quote]
You might want to look into native (commandline) programs that show you PID information, and allow you to kill programs by specifying a PID. To know which PID your just exec-ed process has, you can do a before/after comparison of the listings of PIDs (fragile), and search for a certain executable-name (less fragile), if the PID program gives you that kind of information.

It’s a heck of a lot work though, only to get rid of managing the reference to your Process - you need it though if you won’t want to keep your VM running 24/7.

Okay, thanks for the response. I’ll look into writing a UNIX script at some point, but for now I can just leave the program on and be very careful with memory usage.

Thanks!

Hm, well I’ve tried creating my process and calling destroy(), but no dice. It seems to ignore that I’ve done that, even though my variable isn’t null. I also tried using the OutputStream attached to my process to that I could write the quit command to it, but it seems to ignore that as well.

Any ideas?

I just tried;


class ExecTest
{
    public static void main(String[] args)
    {
        try {
            Process p=Runtime.getRuntime().exec("game.exe",null,null);
            long timeIn5Secs=System.currentTimeMillis()+5000;
            while (timeIn5Secs>System.currentTimeMillis()) {}
            p.destroy();
        } catch (Exception e) {System.out.println(e.getMessage());}
    }
}

And it worked as it should… Maybe if you ditch the working dir and put your widget in the same dir as the server.exe?

Well it seems the difference here might be that I am doing this on Mac OS X.

I tried just saying “TextEdit.app” (replacing game.exe) and got a “Not found” error. When I replaced that with “open TextEdit.app” it was able to open it, but not quit it.

When I tried just putting the path in “/Applications/TextEdit.app” it says “cannot execute.” Regardless of where my Java file is running from.

Um… Don’t know much about OS X!
What about trying exec(“close TextEdit.app”,null,null)? Or am I being silly?
What version of Java are you using - 1.6?

Ah, no, I figured it out. One of those epiphanies you have in your sleep.

Applications in Mac OS X are “bundles,” where basically a .app is actually a folder full of resources. The real executable is inside the .app, so UNIX thinks the .app is simply a folder.


public class ExecTest
{
    public static void main(String[] args)
    {
        try
		{
            Process p = Runtime.getRuntime().exec("/Applications/TextEdit.app/Contents/MacOS/TextEdit",null,null);
            Thread.sleep(5000);
            p.destroy();
        } catch (Exception e) {System.out.println(e.getMessage());}
    }
}

Opening it in this way, rather than using the “open” command, allows me to correctly exit the process.

Oh and I tried the “close” command before, but unfortunately it does not exist. :-\ I’m Using JRE 1.5.

there’s a thread about that issue: http://www.java-gaming.org/forums/index.php?topic=17064.msg134376#msg134376