Sep
3
Shelling out in Java re-visited
Filed Under 42 (Life the Universe & Everything) on September 3, 2005 at 7:37 pm
Following on from my previous post on shelling out in Java.
When shelling out in Java there are only two models you get by default, you can either set the process off and carry on your thread of execution in parallel, or you can halt your thread of execution until the thread you spawned finishes. The questions is, what if you want something in between, what if you want to wait for a given length of time and then simply assume that something has gone horribly wrong and kill the child process and then move on?
Well, I have what I consider to be a good solution!
The following is a Java function that allows you to specify just
about everything you could ever need when shelling out. It has made my
life a lot easier so hopefully it will be of some use to other people
too!
/** The exit code that indicuated success. */ public final static int SUCCESS = 0; /** * A static method to execute a given command on the shell and return the exit * code. * * @param cmd The command to execute. * @param waitForSecs How many seconds to wait for the spawned thread to * terminate. A value of zero indicated not to wait at all but to let the * new process carry on in the background. A negative value indicates * that this function should wait indefinitely for the spawned process to * finish and any positive value will be interpreted as the number of * seconds to wait for the process to terminate before killing it. * @param workingDir The working directory for Java to use. If a blank * string or null is passed no working directory is set. * @param env The environment variables to shell out with. If an * empty array or null is passed no environment variables will be sent * are sent. * @return Whether or not the spawned process exited without * errors. If we are not waiting for the proccess to end it is impossible * to know this so false will always be returned. * @exception Exception If any exception is thrown in the process of * executing the command it is caught and encapsulated in a Exception * and then re-thrown. */ public static boolean executeCommand(String cmd, String[] env, String workingDir, int waitForSecs) throws Exception { try { String[] theEnv = env; if(theEnv == null) { theEnv = new String[0]; } Process proc = null; if(workingDir != null && !workingDir.equals("")) { proc = Runtime.getRuntime().exec(cmd, theEnv, new File(workingDir)); } else { proc = Runtime.getRuntime().exec(cmd, theEnv); } //if we are not waiting, return if(waitForSecs == 0) { return false; } //if we are waiting indefinitely, do so if(waitForSecs < 0) { return SUCCESS == proc.waitFor(); } //if we are waiting for a set amound of seconds do so int waited = 0; do { Thread.sleep(1000); try { boolean ans = SUCCESS == proc.exitValue(); return ans; } catch(IllegalThreadStateException e) { //the thread has not finished yet waited++; if(waited >= waitForSecs) { //we have been here too long, kill the process and return false proc.destroy(); return false; } } }while (true); } catch(Exception e) { throw new Exception("An exception occouted while shelling out for the command " + cmd, e); } }
Hey. I realize this is an old post, but the subject is something I am currently interested in. Just letting you know that the code formatting is broken in FF on Mac OS X.
Hi John,
Thanks for the heads-up – this is one of the posts that got eaten when I moved from Serendipity to WordPress. I’ve fixed the formatting now.
Bart.