Java Runtime exec问题

1. java.lang.IllegalThreadStateException: process hasn't exited

1 public static void main(String[] args) {
2         try {
3             Process process = Runtime.getRuntime().exec("javac");
4             System.out.println(process.exitValue());
5         } catch (IOException e) {
6             e.printStackTrace();
7         }
8     }

exec方法创建了一个native的进程,并返回该process的对象,如果进程还没有返回,调用exitValue方法就会出现此异常,因为该方法没有阻塞,其实现如下:
1 public synchronized int exitValue() {
2         if (!hasExited) {
3             throw new IllegalThreadStateException("process hasn't exited");
4         }
5         return exitcode;
6     }

2. waitFor方法

 1 public static void main(String[] args) {
 2         try {
 3             Process process = Runtime.getRuntime().exec("javac");
 4             int result = process.waitFor();
 5             System.out.println(result);
 6         } catch (IOException e) {
 7             e.printStackTrace();
 8         } catch (InterruptedException e) {
 9             e.printStackTrace();
10         }
11     }

waitFor方法会一直阻塞直到native进程完成,并返回native进程的执行结果。如果native进程无法执行完成,waitFor方法将一直阻塞下去,其实现如下:
1 public synchronized int waitFor() throws InterruptedException {
2         while (!hasExited) {
3             wait();
4         }
5         return exitcode;
6     }

该程序在jdk1.7 windows下测试工作正常,返回2; 但是jdk1.4 windows下测试出现hang。JDK documention的解释是
The methods that create processes may not work well for special processes on certain native platforms,
such as 
native windowing processes, daemon processes, Win16/DOS processes on Microsoft Windows,or shell scripts.
The created subprocess does not have its own terminal or console. All its standard io (i.e. stdin, stdout, stderr)
operations will be redirected to the parent process through three streams (getOutputStream(), getInputStream(),
getErrorStream()). The parent process uses these streams to feed input to and get output from the subprocess. Because some 
native platforms only provide limited buffer size for standard input and output streams,
failure to promptly write the input stream or read the output stream of the subprocess may cause
the subprocess to block, and even deadlock.

所以,出现hang时,及时的flush标准输入输出或者错误流能够消除hang,如上面的javac,我们知道redirect到stderr中,所以解决hang后的代码
 1 public static void main(String[] args) {
 2         try {
 3             Process process = Runtime.getRuntime().exec("echo 'abc'>b.txt");
 4             BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
 5             String line;
 6             while((line=reader.readLine())!=null){
 7                 System.out.println(line);
 8             }
 9             int result = process.waitFor();
10             System.out.println(result);
11         } catch (IOException e) {
12             e.printStackTrace();
13         } catch (InterruptedException e) {
14             e.printStackTrace();
15         }
16     }


3. exec() is not a command line 并不是所有的command line命令都可以用exec

 1  public static void main(String[] args) {
 2         try {
 3             Process process = Runtime.getRuntime().exec("echo 'abc'>a.txt");
 4             BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
 5             String line;
 6             while((line=reader.readLine())!=null){
 7                 System.out.println(line);
 8             }
 9             int result = process.waitFor();
10             System.out.println(result);
11         } catch (IOException e) {
12             e.printStackTrace();
13         } catch (InterruptedException e) {
14             e.printStackTrace();
15         }
16     }
结果为:
1 'abc'>a.txt
2 0
并没有将创建a.txt,而从命令行执行"echo 'abc'>a.txt"却正确创建了a.txt

posted on 2012-09-05 22:43 *** 阅读(4288) 评论(0)  编辑  收藏


只有注册用户登录后才能发表评论。


网站导航:
 
<2012年9月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

导航

统计

常用链接

留言簿

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜