【问题标题】:Using Runtime.exec() to launch Websphere's wsadmin.bat - Hangs while reading from InputStream of the process使用 Runtime.exec() 启动 Websphere 的 wsadmin.bat - 从进程的 InputStream 读取时挂起
【发布时间】:2013-08-01 07:46:00
【问题描述】:

直接粘贴代码示例:

        Runtime rt = Runtime.getRuntime();
        path = "c:\IBM\WebSphere\AppServer\profiles\STSCDmgrProfile\bin\";
        cmd = path + "wsadmin";
        String cmdString = cmd
                + " -host "
                + host
                + " -port "
                + port
                + " -username "
                + username
                + " -password "
                + password
                + " "
                + "-f" + "c:/IBM/WebSphere/AppServer/profiles/STSCDMgrProfile/temp/mergedScripts.jy"
                + " -lang "
                + lang
                + " -tracefile logs/ssc_wsadmin_trace.txt -appendtrace true";
        _logger.finer(cmdString.replaceAll(" " + password, " <password>"));
        Process proc = rt.exec(cmdString);
        _logger.finer("Launched process");

        stdInput = new BufferedReader(new InputStreamReader(proc
                .getInputStream()));
        stdError = new BufferedReader(new InputStreamReader(proc
                .getErrorStream()));

        // read the output from the command
        String sIn = "";
        **while ((sIn = stdInput.readLine()) != null) {**
            _logger.log(Level.FINE, "runJCommand stin ==>", sIn);
        }

但是,它在从 stdInput 执行 readLine() 时挂起。上面突出显示。以下是我在跟踪日志中看到的内容:

[7/30/13 23:48:04:937 GMT-12:00] 000000a6 ThreadMonitor W   WSVR0605W: Thread "WebContainer : 1" (00000175) has been active for 664085 milliseconds and may be hung.  There is/are 1 thread(s) in total in the server that may be hung.
at java.io.FileInputStream.readBytes(Native Method)
at java.io.FileInputStream.read(FileInputStream.java:223)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:267)
at java.io.BufferedInputStream.read(BufferedInputStream.java:328)
at sun.nio.cs.StreamDecoder$CharsetSD.readBytes(StreamDecoder.java:464)
at sun.nio.cs.StreamDecoder$CharsetSD.implRead(StreamDecoder.java:506)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:234)
at java.io.InputStreamReader.read(InputStreamReader.java:188)
at java.io.BufferedReader.fill(BufferedReader.java:147)
at java.io.BufferedReader.readLine(BufferedReader.java:310)
**at java.io.BufferedReader.readLine(BufferedReader.java:373)**
at com.ibm.sametime.console.admin.plugins.wsadmin.SSCWsAdmin.runJCommand(SSCWsAdmin.java:924)

如果我通过命令行手动运行相同的 mergedScripts.jy(我在上面的 java 代码中调用),那么它会成功执行并在几分钟内完成。 但是,通过 Java 代码,它会永远运行。

可能的原因是什么?在上述情况下,STDIN 究竟是什么?

【问题讨论】:

    标签: java websphere wsadmin


    【解决方案1】:

    在您从 InputStream 读取的示例代码中,但根本不是从 ErrorStream 读取的,您的问题可能是 ErrorStream 的缓冲区已满,这导致进程阻塞或死锁。请参阅“为什么 Runtime.exec() 挂起”部分 in this article。本文继续描述如何避免这种情况,但您可以通过使用 ProcessBuilder 而不是 Runtime.exec() 来简化该过程,然后重定向 ErrorStream。

    ProcessBuilder pb = new ProcessBuilder("wsadmin", "-host", host, "-port", port, "-username", username, ... );
    Process proc = pb.redirectErrorStream(true).start();
    //Read from the InputStread as you were...
    

    在上述情况下,STDIN 究竟是什么?

    proc.getInputStream() 将包含从命令行运行wsadmin 命令时会产生的任何输出。

    【讨论】:

      【解决方案2】:

      我不确定你到底在编码什么,但我曾经写过一些类似于你在 perl 中所做的事情。也许你可以把它改成 python。

      my $line = "cd /usr/websphere/profiles/myProfile/bin;";
      $line .= ($user !~ /root/i) ? ' sesudo' : '';
      $line .= " ./wsadmin.sh -lang jython ";
      $line .= "-f $wasscriptpth ".join(' ', @args);
      $line .= " 2>&1";
      

      然后我只是在 shell 上调用命令并将输出通过管道传输到文件句柄...

      open(SSHANDLE, "$line |")
      

      注意“2>&1” 这是在一个地方读取错误和标准输出的非常简单的方法。也许你可以在 python 中做这样的事情?

      【讨论】:

        猜你喜欢
        • 2015-01-15
        • 1970-01-01
        • 1970-01-01
        • 2010-10-03
        • 2011-08-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-15
        相关资源
        最近更新 更多