exec : Java Glossary

go to home page E words local find full screen, hide local find menu Google search web for more information on this topic jump to foot of page translate this page with Babelfish 2008-01-22 by Roedy Green ©1996-2009 Canadian Mind Products
index page for letter ⇒ punctuation 0-9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z (all)
exec
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/W2K3, you must use an explicit *.exe or *.com extension on the parameter. In Vista 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 JDK 1.5, exec 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 and to 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 same Process class. So read about exec first, then enjoy the improved ProcessBuilder.

Overloaded exec ProcessBuilder
Command Interpreter Threads to Tend the Child
Simplifications Spawning java.exe
Spawning A Browser Spawning javac.exe
Unix Java Web Start Spawning
Process Communication Desktop Spawning
Applets Learning More
Gotchas Links

Overloaded exec

There are also many overloaded forms of exec() including this most general one:
// command strings, environment strings, directory to start in
Runtime.getRuntime().exec( new String[] { "cmd.exe", "/E:1900", "/C", "MyBat.bat"},
                           new String[] { "flavour=strawberry", "font=Stone"},
                           "C:\\SomeDirectory" );
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.

Command Interpreter

To run a *.BAT, *.CMD, *.html *.BTM or URL 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:
exec only understands xxx.exe and parameters. It knows nothing about program names without the *.exe explicitly mentioned, | pipes, < redirection >, % environment parameter subsitution, or *.bat, *.cmd or *.html files. Further commands such as attrib, cls, copy del, dir, format, move and rename 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 .exe extension (at least in W98/Me/NT/W2K/XP/W2K3/Vista, in other OSes, 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 parameters.
There is an exception. In XP/W2K3/Vista you can invoke a bat file so long as you use the explicit .bat extension, without resorting to a command interpreter.

Simplifications

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)

Launching A Browser

Windows and NT will let you feed a URL string to the command processor and it will find a browser, launch the browser, and render the page, e.g.
Runtime.getRuntime().exec( "cmd.exe http://mindprod.com/index.html" );
Another lower level approach that does not require extension associations to be quite as well set up is:
Note that a URL is not the same thing as a file name. You can point your browser at a local file with something like this:
file://localhost/E:/mindprod/index.html
or
file:///E|/mindprod/index.html.

// spawning Firefox on the Mac
Runtime.getRuntime().exec( new String[] {
                              "open",
                              "-a",
                              "Firefox.app",
                              url.toString()
                           });
Composing just the right platform-specific command to launch browser and feed it a URL to display can be frustrating. You can use the BrowserLauncher2 package to do that for you.

Note that

rundll32.exe url.dll,FileProtocolHandler file:///E|/mindprod/jgloss.html
won’t work on the command line because | is reserved as the piping operator, though it will work as an exec parameter passed directly to the rundll32.exe executable.

Unix

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:
  1. Start the script with #!bash or whatever the interpreter’s name is.
  2. Mark the script file itself with the executable attribute.
Alternatively start the script interpreter, e.g.
Runtime.getRuntime().exec( new String[]{ "/bin/sh", "-c", "echo $SHELL"} );
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.

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:
  1. Spawn the child (and continue processing).
  2. Write the child’s input from System.in with Process. getOutputStream(). Note the stream is named relative to the parent, not the child.
  3. 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.
  4. Read the child’s output from System. err with Process. getErrorStream().
  5. One each to read the child’s output from files, sockets etc.
  6. Wait for the child with Process.waitFor() once you have all the hooks set up.
  7. Timer to kill the child, and interrupt the waitFor() thread with Thread.interrupt() if the child takes too long.
You need to start all these possible Threads after you create the Process object, but before you call waitfor.

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 stdout.

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.

If you wait for the Process, you might want to do it on some thread other than the main AWT 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.

Applets

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 privilege.

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"));

Gotchas

ProcessBuilder

Starting with Java 1.5 there is a better way of handling exec called ProcessBuilder. It has a number of advantages over exec. Here is how you use it:

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, unable to continue until someone reads its output.
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. 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. You can also use flush() to ensure the other party has access to all the data recently written.

Spawning java.exe

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.

Spawning javac.exe

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 exec.

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 4nt.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.

Desktop Spawning

In JDK 1.6+ there is a simplified exec technique. You cannot communicate with the child task.

Learning More

Sun’s Javadoc on the exec method : available:
Sun’s Javadoc on the Process class : available:
Sun’s Javadoc on the ProcessBuilder class : available:
Sun’s Javadoc on the Desktop class : available:


CMP homejump to top
CMP logo
feedback Please email your feedback for publication, errors, omissions, broken/redirected link reports
and suggestions to improve this page to Roedy Green : feedback email
made with CSS
HTML Checked!
ICRA ratings logo
mindprod.com IP:[65.110.21.43]
Your face IP:[38.103.63.58]
You are visitor number 121,354.
You can get a fresh copy of this page from: or possibly from your local J: drive (Java virtual drive/mindprod.com website mirror)
http://mindprod.com/jgloss/exec.html J:\mindprod\jgloss\exec.html