Runtime.getRuntime().exec( "myprog.exe" );
will spawn an external process (usually a program written in some language other than Java) that runs in parallel
with the Java execution. In W95/W98/Me/NT/W2K/XP/W2003, you must use an explicit *.exe or *.com extension on the parameter. In
it will still work even if you leave it off. Be careful to include it, or your code will mysteriously fail on the
older operating systems.
It is also best to fully qualify executable names so that the system executable search path is irrelevant, and
so you don’t pick up some stray program off the path with the same name.
Starting with Java version 1.5
has been replaced by ProcessBuilder. start
. You should
likely not be using exec
for new programs. However, studying exec
is useful to understand old programs that use exec
understand why ProcessBuilder
is designed the way it is. They have many things in
common, especially the way command interpreters and internal commands must be handled, and they both use the
class. So read about exec
first, then enjoy
the improved ProcessBuilder
EXEC vs Threads
There are two ways to get parallel execution, spawn a separate job with exec, or use threads. Which is best
for your problem?
Threads join the queue of processes to execute. The OS (Operating System) schedules them
on the next available CPU (Central Processing Unit) core. So if you have 7 threads and 4 cores,
you can have 4 of those threads running fully simultaneously, not just interleaved.
Your threads compute just like independent jobs, though the OS can do
proprietary clever things to treat them differently.
When you exec/fork, you spin off a separate job than runs
independently in a separate address space. The spawner can fail and
the child keeps going. The child can be written in a different
language. The child have very limited ability to communicate with the
spawner. In contrast a thread has access to the shared address space directly which
makes interthread communication much easier.
You can also use Thread pools where you logically want to have hundreds of threads, but don’t want the overhead.
There are also many overloaded forms of exec() including this most general one:
The second argument can be a String , and can be used to set environment variables.
In the second case, C:\\SomeDirectory specifies a directory for the
process to start in. If, for instance, your process saves files to disk, then this form allows you to specify
which directory they will be saved in.
To run a *.BAT, *.CMD, *.html *.BTM or URL (Uniform Resource Locator) you must invoke the command processor
with these as a parameter. These extensions are not first class executables in Windows. They are input data for
the command processor. You must also invoke the command processor when you want to use the <
> | piping options, Here’s how, presuming you are not interested in looking at the output:
There is an exception. In XP/W2003/Vista/W2008/W7-32/W7-64/W8-32/W8-64
you can invoke a bat file so long as you use the explicit .bat extension, without
resorting to a command interpreter.
only understands xxx.exe
and parameters. It knows
nothing about program names without the *.exe
explicitly mentioned, | pipes, <
redirection >, % environment parameter subsitution, or *.bat
files. Further, commands such as attrib
, copy del
are not *.exe
files. They are internal commands to the command
interpreter. For all those things you must spawn a command interpreter/shell script with an explicit
extension (at least in W98/Me/NT/W2K/XP/W2003/Vista/W2008/W7-32/W7-64/W8-32/W8-64
in other OS
es, you need a fully qualified executable name) and pass it the name of your executable or
internal command as a parameter. Similarly in Linux
, if you want to use any of the commands internal to the command
processor that don’t have corresponding independent excutables such as alias, enable,
export, pwd, unset, while…
, you must spawn bash or other shell, and feed it commands as
There is also Marty Hall’s
Exec class, which simplifies the process of using exec
and tends to make the command more stable. Currently, only the exec(String cmd) is supported, with a workaround for exec( String cmd, null, String dir)
For Unix/Linux you must spawn the program that can process the script, e.g. bash. However, you can run scripts
directly with exec if you do two things:
I suspect you will have more success if you pass the entire command line as a single parameter to the shell
interpreter, at least if you have any redirection or piping.
- Start the script with #!bash or whatever the interpreter’s name is.
- Mark the script file itself with the executable attribute.
Communicating With The Spawned Process
exec returns a Process object that you can use to control,
monitor or wait for the background process. This example shows you how you can wait for the child, rather than
letting it run asynchronously. This example does not show the many possible other separate Threads you might use to:
You need to start all these possible Threads after you create the Process object, but before you call waitfor.
- Spawn the child (and continue processing).
- Write the child’s input from System.in
with Process. getOutputStream(). Note the stream
is named relative to the parent, not the child.
- Read the child’s output from System.out
with Process. getInputStream(). Note the stream
is named relative to the parent, not the child. You must do this if there are more that a few line of
output, or the child will stall, constipated with unread output.
- Read the child’s output from System. err with
- One each to read the child’s output from files, sockets etc.
- Wait for the child with Process.waitFor() once you have all the hooks set up.
- Timer to kill the child, and interrupt the waitFor()
thread with Thread.interrupt() if the child takes too long.
Process.getOutputStream lets you write out data that will be used as input to
the process. Don’t forget to include any \n and \r characters the process is expecting. Process.getInputStream lets you read in the data that your process squirted out to
The other cruder way to get the output from the execed program is to spawn a command processor and use the
> or 2> redirection operator to direct stdout or stderr
to a file. When the spawned program completes, read the file. Or simply read and write files both in your mother
and child. If batching up this way is acceptable, it is much simpler and much less likely to go south with thread
If you wait for the Process, you might want to do it on some thread other than the
main AWT (Advanced Windowing Toolkit) event processing one, i.e. create a new Thread, otherwise your app will not be able to process AWT
events while you wait.
ON the Java side you may need to read and write to the child with separate threads to avoid deadlocks. The
deadlock occurs if you try to read and/or write more than a certain amount (empirically it is around 4K). The
deadlock (a Mexican standoff freeze) happens when the child wants you to listen when
you are still trying to feed it more, or when the child is hungry for input and you won’t send it any more
until it has spoken.
You can’t use exec from an unsigned Applet otherwise
you would be able to wreck havoc on the client machine by spawning FORMAT C:. If you
need to do that, you will need to have a signed Applet with high
If you are in an Applet and all you are trying to is get a browser to render a
page, you don’t need exec. Simply use getAppletContext().showDocument( new URL (http://domain/file.html));
- If your child program produces more than a few lines of output, your parent program must
capture and process it, otherwise the child will stall with constipation.
- The sender must use flush() to make that data available to
- If you are used to C exec, watch out. Java does not use the dummy parameter 0 which
duplicates the name of the program.
- In a similar way, Java main methods don’t see that dummy parameter
- Your execed program will stall if it produces more than a few lines out output. You have to make provision
via the Process object for the parent program to read the child’s System. out and System.err output if the child produces more than a few lines.
- You must use the .exe suffix. exec is not smart enough
to figure out the extension. A command interpreter can however figure out if you meant .bat, .com or .exe, however. Spawn a command
interpreter instead, with the program name as a parameter. See the example code above.
- For internal command interpreter commands like dir and del, you must spawn a command interpreter with the command as a parameter. You can’t spawn
the command directly.
Starting with Java version 1.5 there is a better way of handling exec called
ProcessBuilder. It has a number of advantages over exec.
Here is how
- It lets you control the environment.
- There are separate methods for setting up the various aspects of the spawn, rather than confusing
- It will merge the child stderr and stdout streams for
Threads to Tend the Child
Here is an example of using Threads to communicate with the child process to feed it input and read its output.
This example does not show a separate System. err reader or a
timeout timer, but this example should be enough to get you started.
You need code like this, or the child will freeze, the sender unable to empty it buffers and the
receiver starved of data because the sender is still holding onto it. Don’t be seduced by the fact code using
a single thread will often work for small amounts of data.
Here is the source code for the dummy boomerang.exe utility I used to test the above
code. I used Jet to compile in down to an exe file.
On the C/C++ side, in your child program,
you could use getc to read the output from Java’s BufferedWriter and putc to write the input to Java’s
BufferedReader. One you have the communication working, replace the C/ C++ I/O with something fancier.
Keep in mind that using large buffers will delay releasing the output to the other party until a
buffer full of data has been accumulated. This can delude you into thinking things are not working when they are
just fine. You must also use flush() to ensure the other party has access to all the
data recently written. If your child in written in Python, use the -u option to turn off buffering. This will
ensure the mother Java program sees the output of the child as soon as possible.
I mentioned earlier that exec is used to start non-Java apps, though in principle you could spawn a copy of
java.exe. However, there are cleaner and faster ways to get that same effect.
There are a three basic techniques to spawn a copy of the Java compiler: JavaCompiler, sun.tools.javac.Main, or
spawning javac.exe with ProcessBuilder or
Java Web Start Spawning
If you have set up the association between .jnlp to javaws.exe,
you can spawn a shell such an cmd.exe or tcc.exe with the name
of the .jnlp file as the parameter. If you have not, you must spawn javaws.exe with the name of the .jnlp file as the parameter. The current
javaws.exe is automatically on the path, via the registry HKEY_LOCAL_MACHINE/SYSTEM/Microsoft/Windows/CurrentVersion/App Paths.
In Java version 1.6 or later there is a simplified exec technique. You cannot communicate with the child task.
will launch the appropriate application to handle the given file.
will launch a browser and display a URL.
will launch as appropriate editor of some sort on the given file.
will launch the user’s favourite mail program.
will launch the appropriate application to print the given file.
Oracle’s Javadoc on exec
package : available:
Oracle’s Javadoc on Process
class : available:
Oracle’s Javadoc on ProcessBuilder
class : available:
Oracle’s Javadoc on Desktop
class : available: