无法从使用Java JLink工具创建的应用程序映像中读取外部文件。

huangapple go评论57阅读模式
英文:

I cannot read external files from the application image created using the Java JLink tool

问题

我无法在使用JLink工具(mvn javaf:jlink)创建的应用程序镜像中读取外部文件,当应用程序正在运行时。这些外部文件位于resources文件夹中。这是我收到的错误信息:

ERROR ExecutorOfFiles 脚本无法读取或加载:SampleScript.jsh
java.nio.file.NoSuchFileException: /com.luisosv/com/luisosv/SampleScript.jsh
        at java.base/jdk.internal.jrtfs.JrtFileSystem.checkNode(JrtFileSystem.java:494)
        at java.base/jdk.internal.jrtfs.JrtFileSystem.getFileContent(JrtFileSystem.java:253)
        at java.base/jdk.internal.jrtfs.JrtFileSystem.newByteChannel(JrtFileSystem.java:351)
        at java.base/jdk.internal.jrtfs.JrtPath.newByteChannel(JrtPath.java:696)
        at java.base/jdk.internal.jrtfs.JrtFileSystemProvider.newByteChannel(JrtFileSystemProvider.java:302)
        at java.base/java.nio.file.Files.newByteChannel(Files.java:370)
        at java.base/java.nio.file.Files.newByteChannel(Files.java:421)
        at java.base/java.nio.file.Files.readAllBytes(Files.java:3205)
        at com.luisosv@1.0-SNAPSHOT/com.luisosv.ExecutorOfFiles.loadSnippetsFromFile(ExecutorOfFiles.java:55)

我使用以下代码来读取外部文件:

String sourceCode = new String(Files.readAllBytes(
                Paths.get(
                        this.getClass().getResource(scriptFileName).toURI())));

然而,通过命令行使用应用程序时,它正常工作 mvn javafx:run

我已经阅读到一旦创建应用程序镜像,就无法更新或修补该镜像。对于任何更改,需要从https://www.studytrails.com/java/java-9/java-9-jlink/部署新的应用程序,我不知道是否是原因或其他原因。

提前感谢。

英文:

I cannot read external files from the application image that I created using JLink tool(mvn javaf:jlink) when the application is running. The external files are placed in the resources folder. This is the error that I got:

ERROR ExecutorOfFiles Script failed to read or load: SampleScript.jsh
java.nio.file.NoSuchFileException: /com.luisosv/com/luisosv/SampleScript.jsh
        at java.base/jdk.internal.jrtfs.JrtFileSystem.checkNode(JrtFileSystem.java:494)
        at java.base/jdk.internal.jrtfs.JrtFileSystem.getFileContent(JrtFileSystem.java:253)
        at java.base/jdk.internal.jrtfs.JrtFileSystem.newByteChannel(JrtFileSystem.java:351)
        at java.base/jdk.internal.jrtfs.JrtPath.newByteChannel(JrtPath.java:696)
        at java.base/jdk.internal.jrtfs.JrtFileSystemProvider.newByteChannel(JrtFileSystemProvider.java:302)
        at java.base/java.nio.file.Files.newByteChannel(Files.java:370)
        at java.base/java.nio.file.Files.newByteChannel(Files.java:421)
        at java.base/java.nio.file.Files.readAllBytes(Files.java:3205)
        at com.luisosv@1.0-SNAPSHOT/com.luisosv.ExecutorOfFiles.loadSnippetsFromFile(ExecutorOfFiles.java:55)

I'm using the following to read the external file:

String sourceCode = new String(Files.readAllBytes(
                Paths.get(
                        this.getClass().getResource(scriptFileName).toURI())));

However, using the application from command-line it works fine mvn javafx:run.

I've read that the application image once created, cannot be updated or patched. For any changes, a new application needs to be deployed from https://www.studytrails.com/java/java-9/java-9-jlink/, and I don't know if that is the reason or something else.

Thanks in advance.

答案1

得分: 6

以下是翻译好的内容:

在影响 Java 13 之前版本的 jrt 文件系统的资源查找中存在一个错误。

当我运行以下代码片段时:

Path p = Paths.get(Object.class.getResource("Object.class").toURI());
System.out.println(p);
System.out.println(Files.exists(p));

从 9 到 12 的所有 JDK 都会产生以下输出:

/java.base/java/lang/Object.class
false

从 JDK 13 开始,输出为:

/modules/java.base/java/lang/Object.class
true

同样,Files.readAllBytes(Paths.get(Object.class.getResource("Object.class").toURI())) 会产生异常 java.nio.file.NoSuchFileException: /java.base/java/lang/Object.class,类似于你的问题中的异常,显示一个带有模块名称但没有前缀 /modules 的路径,适用于 JDK 9 到 12。

因此,只需切换到 JDK 13 或更新版本即可解决问题。


然而,使用以下方式会更好:

byte[] b = Object.class.getResourceAsStream("Object.class").readAllBytes();

或者更简洁的方式:

try(InputStream is = Object.class.getResourceAsStream("Object.class")) {
    byte[] b = is.readAllBytes();
}

从 9 到 14 的所有版本都适用。因此,我建议一开始就使用 getResourceAsStream,而不是通过 URLURIPath 的方式。


话虽如此,你不应该使用 String(byte[]) 构造函数。这个构造函数的结果将取决于当前环境,使用系统的默认字符编码,而嵌入式资源的实际编码永远不会改变。

例如,使用 new String(b, StandardCharsets.UTF_8),或者指定你的资源使用的编码方式。

英文:

There is a bug in the resource lookup for the jrt filesystem affecting Java versions prior to 13.

When I run the following code snippet:

Path p = Paths.get(Object.class.getResource("Object.class").toURI());
System.out.println(p);
System.out.println(Files.exists(p));

All JDKs from 9 to 12 produce the following output:

/java.base/java/lang/Object.class
false

Starting with JDK 13, the output is

/modules/java.base/java/lang/Object.class
true

Likewise, Files.readAllBytes(Paths.get(Object.class.getResource("Object.class").toURI())) produces the exception java.nio.file.NoSuchFileException: /java.base/java/lang/Object.class similar to the exception in your question, showing a path with a module name but no preceding /modules, for JDK 9 to 12.

So, just switching to JDK 13 or newer would solve your problem.


Note, however, that using

byte[] b = Object.class.getResourceAsStream("Object.class").readAllBytes();

or cleaner

try(InputStream is = Object.class.getResourceAsStream("Object.class")) {
    byte[] b = is.readAllBytes();
}

works on all versions from 9 to 14. So I recommend using getResourceAsStream in the first place instead of the URLURIPath detour.


That said, you should not use the String(byte[]) constructor. The outcome of this constructor will depend on the current environment, using the system’s default character encoding whereas the actual encoding of your embedded resource will never change.

Use, e.g. new String(b, StandardCharsets.UTF_8), or specify whatever your resource is encoded with.

答案2

得分: 1

将资源作为文件加载在JAR文件中打包时无法正常工作。请改用getResourceAsStream(...)

new String(this.getClass().getResourceAsStream(scriptFileName).readAllBytes());
英文:

Loading a resource as file does not work if the file is packed in a JAR file. Use getResourceAsStream(...) instead:

new String(this.getClass().getResourceAsStream(scriptFileName).readAllBytes());

huangapple
  • 本文由 发表于 2020年8月24日 12:16:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/63554653.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定