Wednesday, August 05, 2009

How to execute a command line tool from a servlet

In a java program when you want to execute an external program you will normally write something like this:

Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(cmd);
proc.waitFor();


Where cmd is the command line needed to be executed.



However, if you run the same piece of code from a tomcat servlet it may just hung up until you kill it. The problem is documented in the documentation of the exec method, you need to consume the inputStream and the outputStream, so a quick way of doing it is to start other two threads that will consume those stream.



First create the thread class that will process the stream:



class StreamGobbler extends Thread
{
InputStream is;
String type;

StreamGobbler(InputStream is, String type)
{
this.is = is;
this.type = type;
}

public void run()
{
try {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line=null;
while ( (line = br.readLine()) != null) {
System.out.println(type + ">" + line);
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}



Now we can modify the previous code to handle InputStream and ErrorStream:



Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(cmd);
StreamGobbler errorGlobber = new StreamGobbler(proc.getErrorStream(), "CMDTOOL-E");
StreamGobbler outputGlobber = new StreamGobbler(proc.getInputStream(), "CMDTOOL-O");
errorGlobber.start();
outputGlobber.start();
proc.waitFor();


et voilĂ  the code will execute just fine in a servlet.



The idea and code has been taken from: http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=1

2 comments:

carte sdhc 32gb said...

I found that the external program can be launched within JSP only if it is stateless. If the external program tries to open a window, the process will be hanging on and never get finished. I know, in reality, we won't use servlet to start an external program on server to open a window. But, I guess Tomcat doesn't have this capability, either. Please correct me if I am wrong.

mnd said...

obviously opening a window in a server program where you may not have, in fact, an x server or any kind of windowing system....would not be possible.
However tomcat can execute java.awt packages (this is quite different), look at http://wiki.apache.org/tomcat/FAQ/Linux_Unix for some notionson it.