如何在jar文件中嵌入perl脚本以便执行?

时间:2011-07-26 23:43:38

标签: java perl jar

我对Perl很陌生,但现在已经用java编程了几个月(来自C ++背景)。我编写了一个解析一些数据日志的Perl脚本,现在我正在为之工作的客户想要一个GUI。 GUI已经创建为java applet(使用Netbeans),我想将perl脚本“嵌入”其jar文件中作为默认安全功能。预计将来稍后会对perl脚本进行多次更新,因此我希望将其设置为当更新出现时所有用户必须执行的操作是通过GUI定义到最新perl脚本的新文件路径。我已经用文件浏览器实现了这个功能,一切正常。

我遇到的问题非常简单,对于拥有更多java经验的人来说可能并不是很难。为了防止他们将来收到的更新的perl脚本之一无法正常工作,我希望他们能够使用默认的“嵌入式”脚本,如果他们不得不诉诸于此。当我通过Netbeans运行applet时,一切都运行正常但是当我尝试从命令行运行jar文件时,程序返回一个错误,说它无法找到该文件。我可能没有使用正确的术语来搜索此问题的解决方案,但我希望能够让我的jar文件在运行时执行嵌入式perl脚本。任何建议表示赞赏。我已经尝试将perl文件放在与java文件相同的包中,并仅通过文件名调用脚本,但这是不行的。

2 个答案:

答案 0 :(得分:3)

您可以将jar中的任何文件作为类路径资源访问,但是您将遇到的问题是用户可能没有安装perl解释器。

编辑:既然你已经提到用户将拥有Perl运行时,那么这是可行的。您可以尝试使用Process.getOutputStream()来管道文件的内容,或者只是将内容复制到File.createTempFile()的临时文件,并将该文件名作为参数传递给perl解释器。

答案 1 :(得分:1)

我有同样的问题,这是我如何基于Josh和Jiggy上面的讨论解决它。首先在src / main / resources / perl中查找文件(因此它在Eclipse中工作)。如果它不存在,则将Perl文件从jar内的perl目录复制到src / main / resources / perl。我用Maven构建,所以使用src / main / resources / perl目录意味着当我构建jar时,Maven会自动在jar中包含perl目录。

这与用于load resources from jars的属性文件类似。

我正在使用这种方法,因为当每个子模块构建一个jar时,我有一个多模块Maven项目。我们有一个提供一般信息提取,然后另一个专门为特定客户提供该模块。 Perl代码存在于通用模块中,但在专用模块中需要它。 Copying files between modules in Maven is rather awkward,因此将它放入资源更容易,然后让Java代码解决问题。

请参阅此related question,以获得在jar中嵌入本机代码(如C)的替代方法的良好答案。

代码看起来像这样(我正在使用Apache Commons IO):

public class PerlTableParser {

  private static final String RESOURCES_DIR = "src/main/resources";
  private static final String LIB_PATH = RESOURCES_DIR + "perl/";
  private static final String PERL_PARSER = "perl/parser.pl";
  private static final String PERL_CMD = String.format("perl -I %s %s",
        LIB_PATH, RESOURCES_DIR + PERL_PARSER);

  public PerlTableParser() {
    File perlCodeDir = new File(LIB_PATH);
    if (!perlCodeDir.exists()) {
        perlCodeDir.mkdirs();
    }
    File perlParserFile = new File(RESOURCES_DIR, PERL_PARSER);
    try {
        if (!perlParserFile.exists()) {
            FileUtils.copyInputStreamToFile(getClass().getClassLoader()
                    .getResourceAsStream(PERL_PARSER), perlParserFile);
        }
    } catch (IOException e) {
        MyLogger.logger.error(
                "Failed to copy Perl code to local directory " + e, e);
    }
}