简体   繁体   English

为什么我的Java程序不能读取Perl的STDERR?

[英]Why can't my Java program read Perl's STDERR?

We have a Perl program to validate XML which is invoked from a Java program. 我们有一个Perl程序来验证从Java程序调用的XML。 It is not able to write to standard error and hanging in the print location. 它无法写入标准错误并挂在打印位置。

Perl is writing to STDERR and a java program is reading the STDERR using getErrorStream() function. Perl正在写入STDERR,java程序正在使用getErrorStream()函数读取STDERR。 But the Perl program is hanging to write to STDERR. 但是Perl程序暂时写入STDERR。 I suspect Java function is blocking the STDERR stream completely and Perl is waiting for this stream to be released. 我怀疑Java函数完全阻塞了STDERR流,Perl正在等待这个流被释放。

Is there a way in Perl to overcome this blockage and write to standard error forcefully? 在Perl中是否有办法克服这种阻塞并强行写入标准错误? Since Java is doing only a read the API should not be locking the STDERR stream as per java doc. 由于Java只进行读取,因此API不应该按照java doc锁定STDERR流。

Perl Code snippet is: Perl Code代码段是:

sub print_error
{
    print STDERR shift;
}

Java code snippet is: Java代码段是:

while ( getErrorStream() != null )
{
    SOP errorMessage;
}

Appreciate the help in advance. 提前感谢您的帮助。

Thanks, Mathew Liju 谢谢,Mathew Liju

getErrorStream does not read the error stream, it just obtains a handle to it. getErrorStream不读取错误流,它只是获取它的句柄。 As it's a pipe, if you never actually read it, it will fill up and force the Perl program to block. 因为它是一个管道,如果你从未真正读过它,它将填满并强制Perl程序阻止。

You need something like: 你需要这样的东西:

Inputstream errors = getErrorStream();
while (errors.read(buffer) > 0) {
    SOP buffer;
}

An additional factor to consider is the buffering that occurs with piped processes. 要考虑的另一个因素是管道进程发生的缓冲。

There is by default, about a 30-line-ish buffer that is maintained by the shell creating the inter-process pipe, so if the Perl app has not created enough data, it won't have been sent to the Java application yet to process. 默认情况下,创建进程间管道的shell维护了大约30行的缓冲区,因此如果Perl应用程序没有创建足够的数据,它将不会被发送到Java应用程序处理。

May be this thread has a possible cause for your problem: 可能是这个帖子可能导致您的问题:

Add 3 lines to the top of the Perl script: 在Perl脚本的顶部添加3行:

use IO::Handle;
STDOUT->autoflush(1);
STDERR->autoflush(1);

The problem in the mentioned thread was related to "the way Perl is buffering its output". 提到的线程中的问题与“Perl缓冲其输出的方式”有关。

However here, Adrian Pronk mentions in the comments that "Perl is hanging because Java is never reading its output". 然而,在这里, Adrian Pronk在评论中提到“Perl因为Java永远不会读取它的输出而挂起”。

Ideally, I think that to avoid deadlock, in Java you need to spawn separate threads to read the STDERR and the STDOUT. 理想情况下,我认为为避免死锁,在Java中,您需要生成单独的线程来读取STDERR和STDOUT。 It sounds like Perl is blocking when writing to STDERR because for one reason or another you are never reading from it in Java. 听起来Perl在写入STDERR时会阻塞,因为出于这样或那样的原因,你永远不会在Java中读取它。

STDOUT->autoflush(1);
STDERR->autoflush(1);

This is the information I needed! 这是我需要的信息! I have a Java app running some Perl scripts and I'd only get the output after it was finished. 我有一个运行一些Perl脚本的Java应用程序,我只在完成后获得输出。 By adding the autoflush(1) I get it right away. 通过添加autoflush(1)我马上得到它。

BTW, I do have separate threads for reading STDERR and STDOUT , and that's the way to go. 顺便说一句,我确实有单独的线程来读取STDERRSTDOUT ,这就是要走的路。

Thanks. 谢谢。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM