使用可执行jar时,将phantomjs作为本地资源启动

时间:2014-08-14 12:06:09

标签: java jar resources

需要一点帮助。 我的目标是拥有一个可执行的jar文件,它可以获取网页的屏幕截图并在Windows和Linux机器上运行。我尝试过使用html2image,但是phantomjs的结果呈指数级增长。 我的代码看起来像这样:

RESOURCE_PATH = MyClass.class.getClassLoader().getResource("resources").getPath();

public static void main (String[] args) {    
    String url = args[1];
    String outFilePath = args[0];
    final String phantomjsHome = RESOURCE_PATH + "/phantomjs/";
    ProcessBuilder pb = new ProcessBuilder(phantomjsHome + "phantomjs.exe", phantomjsRasterizeScript, url, outFilePath);
    Process process = pb.start();
    process.waitFor();

}

现在我有测试可以向我保证,当我将它作为一个Java应用程序运行时它运行正常但是当我构建一个可执行jar时我得到一个错误。我已经检查并仔细检查了RESOURCE_FOLDER是否指向了正确的位置。但是当我运用jar时 java -jar MyProject.jar "google.png" "https://google.com" 我得到了 java.io.Exception: Cannot run program "file:/C:/Users/Joe/MyProject.jar/resources/phantomjs.exe": CreateProcess error=2, The system cannot find file specified

顺便说一下,这是我第一次询问关于SO的问题,所以如果您需要其他信息或对短语评论有任何建议或意见,请提供一些反馈。谢谢!

更新
经过一些搜索后,我发现无法从jar中执行可执行文件。我已经创建了一个方法来将可执行文件复制到jar之外,这似乎有效。

private static String loadPhantomJS() {
    String phantomJs = "phantomjs.exe";
    try {
        InputStream in = WebShot.class.getResourceAsStream("/resources/phantomjs/" + phantomJs);
        File fileOut = new File(storePath + phantomJs);
        OutputStream out = FileUtils.openOutputStream(fileOut);
        IOUtils.copy(in, out);
        in.close();
        out.close();
        return fileOut.getAbsolutePath();
    } catch (Exception e) {
        return "";
    }
} 

请注意,此方法仅适用于Windows机器,更改linux的文件路径。

1 个答案:

答案 0 :(得分:0)

上述方法适用于Windows机器,但请注意,您要运行的任何文件也必须在jar文件外部解压缩。与loadPhantomJS类似的方法可用于从jar文件中解压缩其他资源文件。我用这个方法:

private static void makeLocalFile(String outPath, InputStream is) {
    try {
        InputStream is;
        File fileOut = new File(outPath);
        OutputStream out;
        out = FileUtils.openOutputStream(fileOut);
        IOUtils.copy(in, out);
        in.close();
        out.close();
    } catch (Exception e) {
        System.out.println(e);
    }
}

我使用InputStream从我的资源中获得MyClass.class.getResourceAsStream("jsFile.js")。到目前为止,我能够在linux上使用它的唯一方法是首先实际安装phantomjs linux灌注。如果/当我找到更好的解决方案时,将更新此答案。