简体   繁体   English

在Perl中捕获内联Java错误

[英]catching inline java error in perl

In this little perl script using inline saxon XSLT parser: 在这个使用内联saxon XSLT解析器的perl脚本中:

use Inline::Java;
use warnings;
use XML::Saxon::XSLT2;
open(my $xslt, '<:encoding(UTF-8)', $xslfile) or die $!;
open(my $xml, '<:encoding(UTF-8)', $xmlfile) or die $!;
my $trans  = XML::Saxon::XSLT2->new($xslt);
my $output = $trans->transform($xml);
print $output;

I would like to catch the transformation errors from saxon. 我想抓住撒克逊人的转型错误。 Starting the script from the commandline, errors are written to STDERR. 从命令行启动脚本,错误将写入STDERR。 But how can I redirect the error message to a file inside the perl script? 但是,如何将错误消息重定向到perl脚本中的文件? I tried Tie::STDERR which doesn't work. 我尝试了不起作用的Tie :: STDERR。

I tried to redirect STDERR with 我试图用重定向

 open my $log_fh, '>>', '/tmp/the-log-file';
 *STDERR = $log_fh;

Then the perl errors are logged in /tmp/the-log-file, but not the saxon errors. 然后,将perl错误记录在/ tmp / the-log-file中,但不会记录在saxon错误中。

You should be able to do that with Capture::Tiny , which can grab the STDOUT and STDERR from external programs and XS. 您应该能够使用Capture :: Tiny做到这一点,它可以从外部程序和XS中获取STDOUT和STDERR。

use strict;
use warnings;
use XML::Saxon::XSLT2;
use Capture::Tiny 'capture';

my ($xslfile, $xmlfile) = ( ... ); 

open(my $xslt, '<:encoding(UTF-8)', $xslfile) or die $!;
open(my $xml, '<:encoding(UTF-8)', $xmlfile) or die $!;

my $trans  = XML::Saxon::XSLT2->new($xslt);
my $output;
my ( $stdout, $stderr ) = capture {
  $output = $trans->transform($xml);
};

print $output;

Please note I did not test this. 请注意,我没有对此进行测试。 Also I don't see where you need the Inline::Java. 我也看不到您需要Inline :: Java的地方。

The JVM has its own notion of standard error that is not easily manipulated from Perl. JVM有自己的标准错误概念,很难从Perl中进行操纵。 To do what you want to do I think you have to reset STDERR before the JVM starts up. 要执行您想做的事情,我认为您必须在JVM启动之前重置STDERR That will require a BEGIN block that appears before your use Inline Java statement. 这将需要在use Inline Java语句之前显示一个BEGIN块。

Proof of concept: 概念证明:

# javaerr.pl
BEGIN {
    open OLDERR, '>&STDERR'; # save orig STDERR
    open STDERR, '>', 'foo'; # redirect before JVM starts
}

use Inline Java => <<'END_OF_JAVA_CODE';
public class Foo {
  static { 
    System.err.println("loaded Foo static block");
  }

  public Foo() {
  }

  public void warn(String msg) {
    System.err.println("Foo warning: " + msg);
  }
}
END_OF_JAVA_CODE

*STDERR = *OLDERR;        # restore orig STDERR
open STDERR, '>', 'bar';  # or direct it somewhere else

$Foo = Foo->new();
$Foo->warn("hello world");

print STDERR "goodbye\n";

-- -

$ perl javaerr.pl
$ cat foo
loaded Foo static block
Foo warning: hello world
$ cat bar
goodbye

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

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