Java
Why wont it work...
27/03/09 16:16
Ok... So if your not interested in Java ignore what follows.
So 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 suggests a number of approaches to solve the problem. I’ve 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 don’t 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 haven’t changed the code.
I’ve 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.... I’ll 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(); } }}
So 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 suggests a number of approaches to solve the problem. I’ve 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 don’t 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 haven’t changed the code.
I’ve 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.... I’ll 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(); } }}
Comments