I write a simple Java program, which just output some "hello"s to std every 5s.
public class DDD {
public static void main(String[] args) throws InterruptedException {
for (int i = 0; ; i++) {
System.out.println("hello " + i);
Thread.sleep(5000);
}
}
}
Then I compile it and getting a .class.
I write another java program to run it and get the output:
public static void main(String[] args) throws Exception {
String command = "c:\\java\\jdk1.7.0_07\\bin\\java mytest.DDD";
Process exec = Runtime.getRuntime().exec(command);
BufferedReader reader = new BufferedReader(new InputStreamReader(exec.getInputStream()));
while (true) {
String line = reader.readLine();
System.out.println(line);
if (line == null) {
Thread.sleep(1000);
}
}
}
But it always prints:
null
null
null
null
null
null
null
Where is wrong? My os is "windows XP".
First, your program is totally correct. By that I mean the way you launch the process and read the input stream should work. So let's see why it doesn't.
I ran your program and I encountered the same behavior. To understand why it didn't work, I made a simple change: instead of reading
getInputStream()
, I listened togetErrorStream()
. This way, I could see if thejava
command returned an error instead of launching the program. And sure enough, it printed the following message:That's it, and I guess it's probably the case for you too. The program could simply not find the DDD class because it's not in the classpath.
I work in Eclipse and the classes are compiled into the directory
bin
in the project, so I simply changed the command toand it worked. I obtained (after switching back to getInputStream()):
This means that by default the working directory for processes spawned by the command
exec
is the root of the project, not the directory where the classes are compiled.In conclusion, just specify the classpath and it should work fine. If not, look at what the error stream contains.
Note: You could have guessed the reason: the Javadoc specifies that
readline()
returnsnull
if the end of the stream has been reached. It was a clear indicator that the process was terminated early.BufferedReader#readLine
will returnnull
when it reaches the end of the stream.Because you're basically ignoring this exit indicator and looping in an infinite loop, all you get is
null
.The likely cause is because the process has output some error information to the error stream, which you are not reading...
You should try using
ProcessBuilder
instead, which allows you to, amongst other things, redirect the error stream into the input streamps- This will work if
java.exe
is your path, otherwise you will need to provide the full path to the executable as you already have done in your example ;)