Java, Cygwin, and Windows.... oh my.
843798Apr 3 2009 — edited Apr 13 2009So the problem can be summarized as follows. I have a call out to the operating system from Java to obtain the value of vmstat which returns a value from every x seconds based on the refresh rate. To do This I use a command similar to this
Runtime rt = Runtime.getRuntime();
String[] comm = new String[] {"vmstat","1"};
Process proc = rt.exec(comm);
I can then loop around capturing the output and parsing it. Simple.... This approach works on Linux, Mac OS, HP-UX, AIX and Solaris however it fails under Windows. It sits there and simply waits. Now this appears to be a common problem based on the number of postings on it. This article(http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html) suggests a number of approaches to solve the problem. Ive tried them all and the good news is that they appear to work for a single atomic call that returns all of its output then exits. However commands such as vmstat/iostat/sar etc. return output periodically based on their refresh rates and dont seem to work at all.
There are plenty of hits in google but no one really seems to suggest a solution. Now Im sure this worked in the past and Im almost certain that I havent changed the code.
Ive tried calling
java myexec cmd /c "c:\\cygwin\\bin\\ls.exe"
Which returns the first line of the directory and then exits.
java myexec cmd /c "c:\\cygwin\\bin\\ls.exe"
simply hangs.... whilst
java myexec cmd /c dir
Works fine.... So my believe its the combination of java and cygwin and the way io is redirected. If anyone has a chance to look at it.... Ill be very grateful. Code for simple testcase below.
import java.util.*;
import java.io.*;
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 (true) {
if (is.available() == 0) {
try {
Thread.sleep(10);
} catch (InterruptedException ie) {
}
continue;
}
line = br.readLine();
if (line == null) {
System.out.println("Error");
} else {
System.out.println(line);
}
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
public class myexec {
public static void main(String[] args) {
try {
String osName = System.getProperty("os.name");
System.out.println(osName);
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(args);
// any error message?
StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "ERROR");
// any output?
StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "OUTPUT");
// kick them off
errorGobbler.start();
outputGobbler.start();
// any error???
int exitVal = proc.waitFor();
System.out.println("ExitValue: " + exitVal);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
Edited by: dgiles on Apr 3, 2009 6:27 AM