Runtime.exec() 死锁?

kingofhawks 2005-12-07 10:54:11
代码如下,请高人指点,在output.readLine()无限等待,不知何故.
public int runCommand(String command)throws IOException {
try {
logger.debug("enter OPMNUtil runCommand....");
this.command=command;
logger.debug("command----\n"+this.command);
Process process = Runtime.getRuntime().exec(this.command);
BufferedReader output = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader error = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String line=null;
while((line=output.readLine())!=null)
{
logger.debug("output is----"+line);
}
while((line=error.readLine())!=null)
{
logger.debug("error is----"+line);
}
int exitValue=process.exitValue();
//int exitValue = process.waitFor();
logger.debug("waitcode---------"+exitValue);
return exitValue;

}
catch(IOException e){
throw new IOException();
}
catch (Exception e) {
e.printStackTrace();
return -1000;
}

}
...全文
277 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
kingofhawks 2005-12-09
  • 打赏
  • 举报
回复
自己重新写了一个,现在可以了,应该还是Stream的问题,参考了More java Pitfall里的实现,不过如果在运行时用鼠标点击Console窗口还是会block掉,那个问题应该是跟输入流没有处理有关了,反正我的程序是做成Windows Service的,所以也不会有那种情况了,谢谢楼上诸位,以下是最新的代码.
/*
* Created on 2005-11-29
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/

import java.io.*;
import java.io.IOException;
import cn.zyxel.util.LogHelper;

/**
* @author Simon
*
* TODO class OPMNUtil aims to deal with OPMNCTL command
*/
public final class OPMNUtil {
//command to run with OPMNCTL
private String command;
//singleton instance
private static OPMNUtil opmnUtil;
private OPMNUtil(){

}
public static OPMNUtil getInstance(){
if(opmnUtil==null){
opmnUtil=new OPMNUtil();
}
return opmnUtil;
}

/**run arbitary OPMNCTL command
* @param command
* @return
* @throws IOException
*/
public int runCommand(String command)throws IOException {

try {

LogHelper.logger.debug("enter OPMNUtil runCommand....");
this.command=command;
LogHelper.logger.debug("command----\n"+this.command);
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(this.command);
StreamGobbler errorGobbler = new
StreamGobbler(proc.getErrorStream(), "ERROR");
StreamGobbler outputGobbler = new
StreamGobbler(proc.getInputStream(), "OUTPUT");
errorGobbler.start();
outputGobbler.start();
int exitVal = proc.waitFor();
LogHelper.logger.debug("ExitValue:" + exitVal);
return exitVal;
}
catch(IOException e){
throw new IOException();
}
catch (Throwable t) {
t.printStackTrace();
return -1000;
}

}

/**get OPMN managed component's status
* @param componentType
* @param processType
* @return
* @throws IOException
*/
public String getComponentStatus(String componentType,String processType)throws IOException{
String status=Constants.EXCEPTION_STATUS;
try {
LogHelper.logger.debug("enter OPMNUtil getComponentStatus....");
this.command="opmnctl status ias-component="+componentType+" process-type="+processType;
LogHelper.logger.debug("command----\n"+this.command);
Process process = Runtime.getRuntime().exec(this.command);
BufferedReader output = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader error = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String line=null;
while((line=output.readLine())!=null) {
if(line.indexOf(processType)!=-1){
status=line.substring(line.lastIndexOf("|")+1,line.length()).trim();
}

}
while((line=error.readLine())!=null) {

}
int exitValue = process.waitFor();
LogHelper.logger.debug("exitValue---------"+exitValue);
return status;

}
catch(IOException e){
throw new IOException();
}
catch (Exception e) {
e.printStackTrace();
return Constants.EXCEPTION_STATUS;
}

}
}

/**
* @author Simon
*
* TODO class StreamGobbler aims to kick off stdout,stderr output.
* So that OPMNUtil will work normally.
*/
class StreamGobbler extends Thread
{
private InputStream is;
private 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) {
LogHelper.logger.debug(type + ">" + line);
System.out.flush();
}
} catch (IOException e){
e.printStackTrace();
}
}
}
kingofhawks 2005-12-08
  • 打赏
  • 举报
回复
我运行的命令是opmnctl startproc ias-component=OC4J process-type=test 如果OC4J test是正常配置的,只是状态是DOWN,我这边也能执行并把test启动起来,但如果故意把OC4J test配置错误,让它无法启动就出现上述情形了.正常情况下启动test需要1分钟左右.
bobokong 2005-12-08
  • 打赏
  • 举报
回复
这是我的代码

import java.io.*;

public class Run
{

public static void main(String[] args)
{
Run r = new Run();
r.runCommand("opmnctl");
}

public int runCommand(String command) {
try {
System.out.println("enter runCommand....");

System.out.println("command----" + command);
final Process process = Runtime.getRuntime().exec(command);

BufferedReader output = new BufferedReader
(new InputStreamReader(process.getInputStream()));


String line=null;


Runnable rr = new Runnable()
{
public void run()
{
try {
BufferedReader error = new BufferedReader
(new InputStreamReader(process.getErrorStream()));

String line2 = null;

System.out.println("handle err stream");
while((line2=error.readLine())!=null)
{
System.out.println("error is----"+line2);
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
(new Thread(rr)).start();

System.out.println("handle std stream");
while((line=output.readLine())!=null)
{
System.out.println("output is----"+line);
}



int exitValue=process.exitValue();
//int exitValue = process.waitFor();
System.out.println("waitcode---------"+exitValue);
return exitValue;

}
catch (Exception e) {
e.printStackTrace();
return -1000;
}
}
}

另,问一下,你执行“opmnctl”需要多久时间
bobokong 2005-12-08
  • 打赏
  • 举报
回复
我写的那个也不行吗?锁在哪一行呢?

我这里没有环境,没法试验
kingofhawks 2005-12-08
  • 打赏
  • 举报
回复
顶上去啊,搞不定啊...
bobokong 2005-12-07
  • 打赏
  • 举报
回复
我猜想是你要启动一个thread专门来接收errorStream,在一个command运行的时候,可能同时有err和输出和std的输出,如果你这样接受,感觉是有问题的。
kingofhawks 2005-12-07
  • 打赏
  • 举报
回复
在线等高人啊~~
bobokong 2005-12-07
  • 打赏
  • 举报
回复
我在2000 server上试的一下,好像可以啊,jdk 1.4.1
不过我觉得最好还是专门用一个Thread来接收err的流
kingofhawks 2005-12-07
  • 打赏
  • 举报
回复
直接执行可以的啊.
treeroot 2005-12-07
  • 打赏
  • 举报
回复
直接执行命令没问题吗
kingofhawks 2005-12-07
  • 打赏
  • 举报
回复
我调用了Oralce Application Server的一个opmnctl命令,在我自己的XP系统上stdout和stderr都能输出啊,但是在2000 Server上就deadlock 了,郁闷啊.
King_Style 2005-12-07
  • 打赏
  • 举报
回复
你执行什么命令会出现这样的错?
我试了一下没有问题呀
不过好象stdout与stderr不会同时输出
kingofhawks 2005-12-07
  • 打赏
  • 举报
回复
是的,在运行command的时候同时会有stdout,stderr输出,而且郁闷的是在xp系统上正常运行,在win2000上就出问题了.

62,625

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧