【问题标题】:catching inline java error in perl在 perl 中捕获内联 java 错误
【发布时间】:2015-08-13 13:08:03
【问题描述】:

在这个使用内联 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 不起作用。

我试图用

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

然后 perl 错误记录在 /tmp/the-log-file 中,而不是 saxon 错误。

【问题讨论】:

    标签: java perl xslt error-handling


    【解决方案1】:

    您应该可以使用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。

    【讨论】:

      【解决方案2】:

      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
      

      【讨论】:

      • 在启动 JVM 之前重置 STDERR 工作,谢谢!
      猜你喜欢
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 2017-11-10
      • 2014-11-02
      • 1970-01-01
      • 1970-01-01
      • 2012-06-16
      • 2016-01-05
      相关资源
      最近更新 更多