如何将 perl 脚本嵌入到 jar 文件中执行?

发布于 2024-11-26 15:26:48 字数 539 浏览 0 评论 0原文

我对 Perl 还很陌生,但已经用 Java 编程几个月了(来自 C++ 背景)。我编写了一个 Perl 脚本来解析一些数据日志,现在我所服务的客户想要一个 GUI。 GUI 已创建为 java 小程序(使用 Netbeans),我想将 perl 脚本“嵌入”其 jar 文件中作为默认安全功能。预计将来会对 perl 脚本进行多次更新,因此我想对其进行设置,以便用户在更新时所要做的就是通过 GUI 定义最新 perl 脚本的新文件路径。我已经使用文件浏览器实现了此功能,一切正常。

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

I'm pretty new to Perl but have been programming in java for several months now (coming from a C++ background). I wrote a Perl script that parses some data logs and now the customer I'm working for wants a GUI. The GUI has been created as a java applet (using Netbeans) and I would like to "embed" the perl script inside its jar file as a default safety feature. Multiple updates are expected for the perl script later in the future, so I want to set it up so that all the user has to do when an update comes along is define a new file path to the latest perl script through the GUI. I've already implemented this functionality with a file browser and everything works fine.

The problem I'm running into is something very simple that's probably not very hard for someone with more java experience. Just in case one of the updated perl scripts they receive in the future doesn't work properly, I want them to be able to use the default "embedded" script if they have to resort to that. When I'm running the applet through Netbeans, everything works perfectly however when I try and run the jar file from the command line, the program returns an error saying it cannot find the file. I might not be using the correct terminology to search for a solution to this problem, but I would like to be able to have my jar file execute the embedded perl script at runtime. Any suggestions are appreciated. I've tried placing the perl file in the same package as the java files and calling for the script by its filename alone, but that was a no go.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

挽手叙旧 2024-12-03 15:26:48

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

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

You can access any file in the jar as a classpath resource, but the problem you're going to have is users may not have a perl interpreter installed.

EDIT: Since you've mentioned that users will have a Perl runtime, then this is doable. You can try piping the contents of the file using Process.getOutputStream() or just copy the contents to a temp file with File.createTempFile() and pass that file name as an argument to the perl interpreter.

嘿看小鸭子会跑 2024-12-03 15:26:48

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

这与用于从 jar 加载资源的策略类似例如属性文件。

我使用这种方法是因为当每个子模块构建一个 jar 时我有一个多模块 Maven 项目。我们有一个模块负责一般信息提取,然后另一个模块专门为特定客户提供该模块。 Perl 代码位于通用模块内,但专用模块中需要它。 在 Maven 中的模块之间复制文件相当尴尬,所以更容易把它放在资源中,然后让Java代码解决问题。

请参阅此相关问题,以获得替代方法的良好答案将本机代码(例如 C)嵌入到 jar 中。

代码如下所示(我使用的是 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);
    }
}

I have the same problem, here's how I solved it based on Josh and Jiggy's discussion above. First look for the file in src/main/resources/perl (so it works in Eclipse). If it does not exist then copy the Perl file from the perl directory inside the jar to src/main/resources/perl. I building with Maven so using the src/main/resources/perl directory means when I build the jar, Maven automatically includes the perl directory in the jar.

This is a similar strategy to the one used to load resources from jars such as properties files.

I am using this approach because I have a multi-module Maven project when each submodule builds a jar. We have one that does general information extraction, then another one that specializes that module for a particular client. The Perl code lives inside the general module, but it is needed in the specialized one. Copying files between modules in Maven is rather awkward, so it is easier just to put it in resources, then let the Java code solve the problem.

See this related question for a good answer of an alternative approach to embedding native code such as C in jars.

The code looks like this (I'm using 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);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文