繁体   English   中英

在Perl中捕获内联Java错误

[英]catching inline java error in perl

在这个使用内联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;

我想抓住撒克逊人的转型错误。 从命令行启动脚本,错误将写入STDERR。 但是,如何将错误消息重定向到perl脚本中的文件? 我尝试了不起作用的Tie :: STDERR。

我试图用重定向

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

然后,将perl错误记录在/ tmp / the-log-file中,但不会记录在saxon错误中。

您应该能够使用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;

请注意,我没有对此进行测试。 我也看不到您需要Inline :: Java的地方。

JVM有自己的标准错误概念,很难从Perl中进行操纵。 要执行您想做的事情,我认为您必须在JVM启动之前重置STDERR 这将需要在use Inline Java语句之前显示一个BEGIN块。

概念证明:

# 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