从 Jar 内部执行 PhantomJS

Executing PhantomJS From Inside Jar

我正在使用 PhantomJS 对网站进行无头测试。由于 exe 将被捆绑在 jar 文件中,我决定读取它并将其写入一个临时文件,以便我可以通过绝对路径正常访问它。

这里是将 InputStream 转换成 String 引用新临时文件的代码:

public String getFilePath(InputStream inputStream, String fileName)
        throws IOException
{
    String fileContents = readFileToString(inputStream);
    File file = createTemporaryFile(fileName);
    String filePath = file.getAbsolutePath();
    writeStringToFile(fileContents, filePath);

    return file.getAbsolutePath();
}

private void writeStringToFile(String text, String filePath)
        throws FileNotFoundException
{
    PrintWriter fileWriter = new PrintWriter(filePath);

    fileWriter.print(text);
    fileWriter.close();
}

private File createTemporaryFile(String fileName)
{
    String tempoaryFileDirectory = System.getProperty("java.io.tmpdir");
    File temporaryFile = new File(tempoaryFileDirectory + File.separator
            + fileName);

    return temporaryFile;
}

private String readFileToString(InputStream inputStream)
        throws UnsupportedEncodingException, IOException
{
    StringBuilder inputStringBuilder = new StringBuilder();
    BufferedReader bufferedReader = new BufferedReader(
            new InputStreamReader(inputStream, "UTF-8"));

    String line;
    while ((line = bufferedReader.readLine()) != null)
    {
        inputStringBuilder.append(line);
        inputStringBuilder.append(System.lineSeparator());
    }

    String fileContents = inputStringBuilder.toString();

    return fileContents;
}

这有效,但是当我尝试启动 PhantomJS 时,它会给我一个 ExecuteException:

SERVERE: org.apache.commons.exec.ExecuteException: Execution failed (Exit value: -559038737. Caused by java.io.IOException: Cannot run program "C:\Users\%USERPROFILE%\AppData\Local\Temp\phantomjs.exe" (in directory "."): CreateProcess error=216, the version of %1 is not compatible with this Windows version. Check the system information of your computer and talk to the distributor of this software)

如果我不尝试从 jar 中读取 PhantomJS,那么使用相对路径就可以正常工作。问题是我如何从 jar 文件中读取和执行 PhantomJS,或者至少获得读取和写入新(临时)文件的解决方法。

您不能执行 JAR 条目,因为 JAR 是一个 zip 文件,操作系统不支持 运行ning 压缩文件中的可执行文件。他们原则上可以,但它会归结为 "copy the exe out of the zip and then run it".

exe 已损坏,因为您将其存储在字符串中。字符串不是二进制数据,它们是 UTF-16,这就是为什么您不能直接从 InputStream 读取到字符串的原因——需要进行编码转换。您的代码正在以 UTF-8 格式读取 exe,将其转换为 UTF-16,然后使用默认字符集将其写回。即使您机器上的默认字符集恰好是 UTF-8,这也会导致数据损坏,因为 exe 不是有效的 UTF-8。

试试这件尺码。 Java 7 介绍了 NIO.2,它(除其他外)有很多用于常见文件操作的便捷方法。包括将 InputStream 放入文件中!我还使用了临时文件 API,如果您的应用程序的多个实例同时 运行,这将防止冲突。

public String getFilePath(InputStream inputStream, String prefix, String suffix)
        throws IOException
{
    java.nio.file.Path p = java.nio.file.Files.createTempFile(prefix, suffix);
    p.toFile().deleteOnExit();
    java.nio.file.Files.copy(inputStream, p, java.nio.file.StandardCopyOption.REPLACE_EXISTING);
    return p.toAbsolutePath().toString();
}