我无法从使用 Java JLink 工具创建的应用程序映像中读取外部文件
I cannot read external files from the application image created using the Java JLink tool
当应用程序为运行时,我无法从使用JLink 工具(mvn javaf:jlink
) 创建的应用程序映像中读取外部文件。外部文件放在 resources 文件夹中。这是我得到的错误:
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)
我正在使用以下内容读取外部文件:
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/ 部署新的应用程序,我不知道是这个原因还是其他原因。
提前致谢。
如果文件打包在 JAR 文件中,则无法将资源作为文件加载。使用 getResourceAsStream(...)
代替:
new String(this.getClass().getResourceAsStream(scriptFileName).readAllBytes());
jrt 文件系统的资源查找中存在错误,影响 Java 13 之前的版本。
当我运行下面的代码片段:
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
从 JDK13 开始,输出为
/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。
因此,只需切换到 JDK13 或更新版本即可解决您的问题。
但是请注意,使用
byte[] b = Object.class.getResourceAsStream("Object.class").readAllBytes();
或清洁工
try(InputStream is = Object.class.getResourceAsStream("Object.class")) {
byte[] b = is.readAllBytes();
}
适用于从 9 到 14 的所有版本。因此我建议首先使用 getResourceAsStream
而不是 URL
→ URI
→ Path
绕行。
就是说,您不应该使用 String(byte[])
构造函数。此构造函数的结果将取决于当前环境,使用系统的默认字符编码,而嵌入资源的实际编码永远不会改变。
使用,例如new String(b, StandardCharsets.UTF_8)
,或指定您的资源编码的内容。
当应用程序为运行时,我无法从使用JLink 工具(mvn javaf:jlink
) 创建的应用程序映像中读取外部文件。外部文件放在 resources 文件夹中。这是我得到的错误:
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)
我正在使用以下内容读取外部文件:
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/ 部署新的应用程序,我不知道是这个原因还是其他原因。
提前致谢。
如果文件打包在 JAR 文件中,则无法将资源作为文件加载。使用 getResourceAsStream(...)
代替:
new String(this.getClass().getResourceAsStream(scriptFileName).readAllBytes());
jrt 文件系统的资源查找中存在错误,影响 Java 13 之前的版本。
当我运行下面的代码片段:
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
从 JDK13 开始,输出为
/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。
因此,只需切换到 JDK13 或更新版本即可解决您的问题。
但是请注意,使用
byte[] b = Object.class.getResourceAsStream("Object.class").readAllBytes();
或清洁工
try(InputStream is = Object.class.getResourceAsStream("Object.class")) {
byte[] b = is.readAllBytes();
}
适用于从 9 到 14 的所有版本。因此我建议首先使用 getResourceAsStream
而不是 URL
→ URI
→ Path
绕行。
就是说,您不应该使用 String(byte[])
构造函数。此构造函数的结果将取决于当前环境,使用系统的默认字符编码,而嵌入资源的实际编码永远不会改变。
使用,例如new String(b, StandardCharsets.UTF_8)
,或指定您的资源编码的内容。