The new Java ProcessBuilder in 1.5 is very nice. But there are a few unexpected issues that I ran into while attempted to create an executable-wrapping framework with it.
The first and most important issue is this: Changes to the Path environment variable are not reflected until a new process is created and running. Here is an example of how this can bite you in the ass:
new ProcessBuilder(”myExe.exe”, “arg1″, “arg2″);
Map env = pb.environment();
// watch out here! this could be “PATH” or “path”
// Windows doesn’t care, but Java will
String path = env.get(”Path”);
env.set(”Path”, path + File.pathSeparator
+ “path\to\the\executable”);
pb.start();
- You have an executable file that you want to run with ProcessBuilder that is not on your path.
- You assume that you can write the previous code in order to temporarily add the exe’s path to the process’s environment before executing it.
- You always get an error=2 back from the ProcessBuilder because it cannot find the file.
This is because the changes you made to the new process environment are not reflected until the process is actually running. In other words, Java does not change the path until it attempts to execute the command you have told it to execute. It will never find an executable file that is not on the previous system path even if you change the “Path” environment variable in the ProcessBuilder before you call the “start()” method.
I think the best way to go about accomplishing this is to send the executable’s absolute path into the ProcessBuilder as the command. It may be inconvenient for you, but you can never depend on a certain path within the user environment once the application is installed (unless, of course, this is on a web server that you have complete control over… in that case just add the executable to your path and carry on happily).

One Comment
This exactly matches my conclusion after some experimentation. Note that at least in Unix the environment, including PATH, is an immutable characteristic of the current process (e.g. the JVM) and can only be adjusted for subprocesses, such as the one you’re starting. Assuming a File object workingDir, and a String containing the command in workingDir I want to run, this code worked for me:
pArgs.add(new File(workingDir, command).getAbsolutePath());
pb = new ProcessBuilder(pArgs);
env = pb.environment(); // OPTIONAL: Adjust env for subprocess only
env.put(”Path”, env.get(”Path”)
+ System.getProperty(”path.separator”) + workingDir.getAbsolutePath());
pb.directory(workingDir);
prc = pb.start();