簡體   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