Home |  MySQL Buzz |  FAQ |  Feeds |  Submit your blog feed |  Feedback |  Archive |  Aggregate feed RSS 2.0 English Deutsch Español Français Italiano 日本語 Русский
Running Shell Commands in Java
+0 Vote Up -0 Vote Down

The Skoll Client retrieves a set of commands from the Skoll Server to compile and test MySQL; these commands are UNIX shell commands. My Google Summer of Code project is to work on the Java Skoll Client, I spent a great deal of time and effort getting these shell commands to run well in Java. Running shell commands in Java is not always straightforward, here are some techniques I learned to get the job done.

Use Java's ProcessBuilder class instead of Runtime class for Java 5.0+ projects. There are two reasons. First, ProcessBuilder has redirectErrorStream() method that automatically merges the standard output and standard error together so the output of a command would make more sense and more importantly the process won't freeze if the developer doesn't clear the error output stream. Second, the environment() method returns a nice Map the developer can use to manipulate the environment in which the command should run. Unfortunately, I must support Java 1.4 and 5.0 so I had to do everything the hard way.

Modifying the PATH environment variable does not add a location for Java to locate executables, at least not the way I expected it to. I was trying to run the "bzr" command which is not in my default path, I thought setting the PATH environment variable to include the non-default path would allow Java to find "bzr". That did not work. The environment settings do not take affect until the process has started, but Java cannot start the process because it cannot find the "bzr" command. For now, I set the PATH in the shell script that starts the Skoll Client. But one possible solution is to set the environment variables, then run the command "sh -c 'bzr'" (not yet tested).

Passing a shell command to Java does not always work. The way Java parses the commands does unexpected things, at least to me at first. I found that parsing the commands myself then passing them to Java guarantees correct execution. This command parsing algorithm divides one command string into an array of command parts; the command parts are divided by whitespace, unless the whitespace appears in quotation. Here is a simple method that prepares the command for Java.

private String[] prepareCommand(String command)
{
   ArrayList commandParts = new ArrayList();
   StringBuffer currPart = new StringBuffer();
   boolean inQuote = false;

for (int x = 0; x < command.length(); x++) { char ch = command.charAt(x);

if (ch == ''' || ch == '"') { inQuote = !inQuote; } else if (Character.isWhitespace(ch) && !inQuote) { commandParts.add(currPart.toString()); currPart = new StringBuffer(); } else { currPart.append(ch); }

// get the last part of the command if (x == command.length() - 1) { commandParts.add(currPart.toString()); } }

String[] coms = new String[commandParts.size()]; commandParts.toArray(coms);

return coms; }

For more information and source code related to running shell commands in Java, see ShellCommandsWithJava.

Votes:

You must be logged in with a MySQL account to vote on Planet MySQL entries. More information on PlanetMySQL voting.

Planet MySQL © 1995-2008 MySQL AB, 2008-2010 Sun Microsystems, Inc.,
2010, Oracle Corporation and/or its affiliates.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.