如何访问 Quarkus 原生镜像中的资源?
How to access resources in a Quarkus native image?
我开始玩 quarkus 和 graalvm。我将文件(txt 和 jpg)添加到项目中的资源 (src/main/resources/
)。为了确保我可以在控制器中访问此文件,我显示了它的大小:
URL url = Thread.currentThread().getContextClassLoader().getResource("/Resource2.txt");
File file = new File(url.toURI());
return "Hello My Friend! File size in bytes = " + file.length();
当我 运行 它与 Maven (mvn quarkus:dev
) 一起工作时。控制器代码是 here.
当我创建本机 Quarkus 应用程序并尝试在 docker 中 运行 时出现问题。
为了确保该文件包含在原始图像中,我添加了一个大的 jpg 文件 (3.3MB),创建了 resources-config.json
:
{ "resources":
{ "includes": [
{ "pattern": "IMG_3_3M\.jpg$"},
{ "pattern": "Resources2\.txt$"}
]
}}
并在 application.properties
中添加:
quarkus.native.additional-build-args = -H:ResourceConfigurationFiles=resources-config.json
。本机 运行ner 大小增加自:
39M Mar 21 12:48 hello-quarkus-1.0-SNAPSHOT-runner
- 至:
44M Mar 21 12:19 hello-quarkus-1.0-SNAPSHOT-runner
所以我假设包含了 jpg 文件,但是当 运行 本机应用程序在 docker 图像中时,我仍然得到 NPE:
Caused by: java.lang.NullPointerException
at it.tostao.quickstart.GreetingResource.hello(GreetingResource.java:24)
其中第 24 行:是 url.toURI()
.
知道如何读取原生图像中的资源吗?配置中是否缺少某些内容?
这里是重现问题的示例图像,构建所需的所有命令和 运行 您可以在 README.MD:
中找到的原生图像
https://github.com/sleski/hello-quarkus
到目前为止,我检查了这个网址,但仍然无法在原生图像中找到资源:
•
• How to read classpath resources in Quarkus native image?
• https://quarkus.io/guides/writing-native-applications-tips
•
第一次修复json
{
"resources": [
{
"pattern": "Resource2.txt"
}
]
}
或者您可以将 *.txt 作为模式。就像在 doc
https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/Resources.md 说使用
InputStream resource = ModuleLayer.boot().findModule(moduleName).getResourceAsStream(resourcePath);
当我尝试时遇到了问题。您可以在下面看到您的项目的工作代码
@Path("/hello")
public class GreetingResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() throws IOException {
String moduleName = "java.base";
String resourcePath = "/Resource2.txt";
Module resource = ModuleLayer.boot().findModule(moduleName).get();
InputStream ins = resource.getResourceAsStream(resourcePath);
if (ins == null) {
System.out.println("module came empty, now trying to load from GreetingResource");
ins = GreetingResource.class.getResourceAsStream(resourcePath);
}
if (ins != null) {
StringBuilder sb = new StringBuilder();
for (int ch; (ch = ins.read()) != -1; ) {
sb.append((char) ch);
}
return "Hello My Friend! File size in bytes = " + sb;
}
return "empty";
}
}
GreetingResource.class.getResourceAsStream(resourcePath);
其实是把资源带到这里来了。我认为此功能将来可能会发生变化,因此我也将 ModuleLayer 留在了代码中。我用的是 graalvm 17-21.3.0
您可以在下面找到构建日志
[INFO] [io.quarkus.deployment.pkg.steps.NativeImageBuildRunner] C:\Program Files\GraalVM\graalvm-ce-java17-21.3.0\bin\native-image.cmd -J-Dsun.nio.ch.maxUpdateArraySize=100 -J-Djava.util.logging.manager=org.jboss.logmanager.LogManager -J-Dvertx.logger-delegate-factory-class-name=io.quarkus.vertx.core.runtime.VertxLogDelegateFactory -J-Dvertx.disableDnsResolver=true -J-Dio.netty.leakDetection.level=DISABLED -J-Dio.netty.allocator.maxOrder=3 -J-Duser.language=en -J-Duser.country=GB -J-Dfile.encoding=UTF-8 -H:-ParseOnce -J--add-exports=java.security.jgss/sun.security.krb5=ALL-UNNAMED -J--add-opens=java.base/java.text=ALL-UNNAMED -H:ResourceConfigurationFiles=resources-config.json -H:+PrintAnalysisCallTree -H:Log=registerResource:verbose -H:InitialCollectionPolicy=com.oracle.svm.core.genscavenge.CollectionPolicy$BySpaceAndTime -H:+JNI -H:+AllowFoldMethods -J-Djava.awt.headless=true -H:FallbackThreshold=0 -H:+ReportExceptionStackTraces -H:-AddAllCharsets -H:EnableURLProtocols=http -H:-UseServiceLoaderFeature -H:+StackTrace -J--add-exports=java.management/sun.management=ALL-UNNAMED hello-quarkus-1.0-SNAPSHOT-runner -jar hello-quarkus-1.0-SNAPSHOT-runner.jar
[hello-quarkus-1.0-SNAPSHOT-runner:20428] classlist: 2,920.35 ms, 0.94 GB
[hello-quarkus-1.0-SNAPSHOT-runner:20428] (cap): 1,493.84 ms, 0.94 GB
[hello-quarkus-1.0-SNAPSHOT-runner:20428] setup: 2,871.07 ms, 0.94 GB
[Use -Dgraal.LogFile=<path> to redirect Graal log output to a file.]
[thread:1] scope: main
[thread:1] scope: main.registerResource
ResourcesFeature: registerResource: Resource2.txt
14:23:38,709 INFO [org.jbo.threads] JBoss Threads version 3.4.2.Final
[thread:1] scope: main.registerResource
ResourcesFeature: registerResource: java/lang/uniName.dat
[hello-quarkus-1.0-SNAPSHOT-runner:20428] (clinit): 475.20 ms, 5.14 GB
[hello-quarkus-1.0-SNAPSHOT-runner:20428] (typeflow): 2,931.83 ms, 5.14 GB
[hello-quarkus-1.0-SNAPSHOT-runner:20428] (objects): 24,294.27 ms, 5.14 GB
[hello-quarkus-1.0-SNAPSHOT-runner:20428] (features): 2,979.07 ms, 5.14 GB
[hello-quarkus-1.0-SNAPSHOT-runner:20428] analysis: 32,083.24 ms, 5.14 GB
# Printing call tree to: C:\Users\ozkan\tmp\hello-quarkus\target\hello-quarkus-1.0-SNAPSHOT-native-image-source-jar\reports\call_tree_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142406.txt
# Printing list of used methods to: C:\Users\ozkan\tmp\hello-quarkus\target\hello-quarkus-1.0-SNAPSHOT-native-image-source-jar\reports\used_methods_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142407.txt
# Printing list of used classes to: C:\Users\ozkan\tmp\hello-quarkus\target\hello-quarkus-1.0-SNAPSHOT-native-image-source-jar\reports\used_classes_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142407.txt
# Printing list of used packages to: C:\Users\ozkan\tmp\hello-quarkus\target\hello-quarkus-1.0-SNAPSHOT-native-image-source-jar\reports\used_packages_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142407.txt
# Printing call tree for vm entry point to: C:\Users\ozkan\tmp\hello-quarkus\target\hello-quarkus-1.0-SNAPSHOT-native-image-source-jar\reports\csv_call_tree_vm_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142408.csv
# Printing call tree for methods to: C:\Users\ozkan\tmp\hello-quarkus\target\hello-quarkus-1.0-SNAPSHOT-native-image-source-jar\reports\csv_call_tree_methods_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142408.csv
# Printing call tree for virtual methods to: C:\Users\ozkan\tmp\hello-quarkus\target\hello-quarkus-1.0-SNAPSHOT-native-image-source-jar\reports\csv_call_tree_virtual_methods_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142408.csv
# Printing call tree for entry points to: C:\Users\ozkan\tmp\hello-quarkus\target\hello-quarkus-1.0-SNAPSHOT-native-image-source-jar\reports\csv_call_tree_entry_points_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142408.csv
# Printing call tree for direct edges to: C:\Users\ozkan\tmp\hello-quarkus\target\hello-quarkus-1.0-SNAPSHOT-native-image-source-jar\reports\csv_call_tree_direct_edges_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142408.csv
# Printing call tree for overriden by edges to: C:\Users\ozkan\tmp\hello-quarkus\target\hello-quarkus-1.0-SNAPSHOT-native-image-source-jar\reports\csv_call_tree_override_by_edges_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142408.csv
# Printing call tree for virtual edges to: C:\Users\ozkan\tmp\hello-quarkus\target\hello-quarkus-1.0-SNAPSHOT-native-image-source-jar\reports\csv_call_tree_virtual_edges_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142408.csv
[hello-quarkus-1.0-SNAPSHOT-runner:20428] universe: 1,547.28 ms, 5.14 GB
[hello-quarkus-1.0-SNAPSHOT-runner:20428] (parse): 4,919.32 ms, 4.87 GB
[hello-quarkus-1.0-SNAPSHOT-runner:20428] (inline): 7,013.78 ms, 5.83 GB
[hello-quarkus-1.0-SNAPSHOT-runner:20428] (compile): 27,387.04 ms, 5.56 GB
[hello-quarkus-1.0-SNAPSHOT-runner:20428] compile: 41,595.59 ms, 5.56 GB
[hello-quarkus-1.0-SNAPSHOT-runner:20428] image: 2,515.22 ms, 5.56 GB
[hello-quarkus-1.0-SNAPSHOT-runner:20428] write: 858.79 ms, 5.56 GB
[hello-quarkus-1.0-SNAPSHOT-runner:20428] [total]: 90,068.97 ms, 5.56 GB
# Printing build artifacts to: C:\Users\ozkan\tmp\hello-quarkus\target\hello-quarkus-1.0-SNAPSHOT-native-image-source-jar\hello-quarkus-1.0-SNAPSHOT-runner.build_artifacts.txt
[INFO] [io.quarkus.deployment.QuarkusAugmentor] Quarkus augmentation completed in 94323ms
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:37 min
[INFO] Finished at: 2022-03-24T14:24:56Z
[INFO] ------------------------------------------------------------------------
我开始玩 quarkus 和 graalvm。我将文件(txt 和 jpg)添加到项目中的资源 (src/main/resources/
)。为了确保我可以在控制器中访问此文件,我显示了它的大小:
URL url = Thread.currentThread().getContextClassLoader().getResource("/Resource2.txt");
File file = new File(url.toURI());
return "Hello My Friend! File size in bytes = " + file.length();
当我 运行 它与 Maven (mvn quarkus:dev
) 一起工作时。控制器代码是 here.
当我创建本机 Quarkus 应用程序并尝试在 docker 中 运行 时出现问题。
为了确保该文件包含在原始图像中,我添加了一个大的 jpg 文件 (3.3MB),创建了 resources-config.json
:
{ "resources":
{ "includes": [
{ "pattern": "IMG_3_3M\.jpg$"},
{ "pattern": "Resources2\.txt$"}
]
}}
并在 application.properties
中添加:
quarkus.native.additional-build-args = -H:ResourceConfigurationFiles=resources-config.json
。本机 运行ner 大小增加自:
39M Mar 21 12:48 hello-quarkus-1.0-SNAPSHOT-runner
- 至:
44M Mar 21 12:19 hello-quarkus-1.0-SNAPSHOT-runner
所以我假设包含了 jpg 文件,但是当 运行 本机应用程序在 docker 图像中时,我仍然得到 NPE:
Caused by: java.lang.NullPointerException
at it.tostao.quickstart.GreetingResource.hello(GreetingResource.java:24)
其中第 24 行:是 url.toURI()
.
知道如何读取原生图像中的资源吗?配置中是否缺少某些内容?
这里是重现问题的示例图像,构建所需的所有命令和 运行 您可以在 README.MD:
中找到的原生图像https://github.com/sleski/hello-quarkus
到目前为止,我检查了这个网址,但仍然无法在原生图像中找到资源:
•
• How to read classpath resources in Quarkus native image?
• https://quarkus.io/guides/writing-native-applications-tips
•
第一次修复json
{
"resources": [
{
"pattern": "Resource2.txt"
}
]
}
或者您可以将 *.txt 作为模式。就像在 doc
https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/Resources.md 说使用
InputStream resource = ModuleLayer.boot().findModule(moduleName).getResourceAsStream(resourcePath);
当我尝试时遇到了问题。您可以在下面看到您的项目的工作代码
@Path("/hello")
public class GreetingResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() throws IOException {
String moduleName = "java.base";
String resourcePath = "/Resource2.txt";
Module resource = ModuleLayer.boot().findModule(moduleName).get();
InputStream ins = resource.getResourceAsStream(resourcePath);
if (ins == null) {
System.out.println("module came empty, now trying to load from GreetingResource");
ins = GreetingResource.class.getResourceAsStream(resourcePath);
}
if (ins != null) {
StringBuilder sb = new StringBuilder();
for (int ch; (ch = ins.read()) != -1; ) {
sb.append((char) ch);
}
return "Hello My Friend! File size in bytes = " + sb;
}
return "empty";
}
}
GreetingResource.class.getResourceAsStream(resourcePath);
其实是把资源带到这里来了。我认为此功能将来可能会发生变化,因此我也将 ModuleLayer 留在了代码中。我用的是 graalvm 17-21.3.0
您可以在下面找到构建日志
[INFO] [io.quarkus.deployment.pkg.steps.NativeImageBuildRunner] C:\Program Files\GraalVM\graalvm-ce-java17-21.3.0\bin\native-image.cmd -J-Dsun.nio.ch.maxUpdateArraySize=100 -J-Djava.util.logging.manager=org.jboss.logmanager.LogManager -J-Dvertx.logger-delegate-factory-class-name=io.quarkus.vertx.core.runtime.VertxLogDelegateFactory -J-Dvertx.disableDnsResolver=true -J-Dio.netty.leakDetection.level=DISABLED -J-Dio.netty.allocator.maxOrder=3 -J-Duser.language=en -J-Duser.country=GB -J-Dfile.encoding=UTF-8 -H:-ParseOnce -J--add-exports=java.security.jgss/sun.security.krb5=ALL-UNNAMED -J--add-opens=java.base/java.text=ALL-UNNAMED -H:ResourceConfigurationFiles=resources-config.json -H:+PrintAnalysisCallTree -H:Log=registerResource:verbose -H:InitialCollectionPolicy=com.oracle.svm.core.genscavenge.CollectionPolicy$BySpaceAndTime -H:+JNI -H:+AllowFoldMethods -J-Djava.awt.headless=true -H:FallbackThreshold=0 -H:+ReportExceptionStackTraces -H:-AddAllCharsets -H:EnableURLProtocols=http -H:-UseServiceLoaderFeature -H:+StackTrace -J--add-exports=java.management/sun.management=ALL-UNNAMED hello-quarkus-1.0-SNAPSHOT-runner -jar hello-quarkus-1.0-SNAPSHOT-runner.jar
[hello-quarkus-1.0-SNAPSHOT-runner:20428] classlist: 2,920.35 ms, 0.94 GB
[hello-quarkus-1.0-SNAPSHOT-runner:20428] (cap): 1,493.84 ms, 0.94 GB
[hello-quarkus-1.0-SNAPSHOT-runner:20428] setup: 2,871.07 ms, 0.94 GB
[Use -Dgraal.LogFile=<path> to redirect Graal log output to a file.]
[thread:1] scope: main
[thread:1] scope: main.registerResource
ResourcesFeature: registerResource: Resource2.txt
14:23:38,709 INFO [org.jbo.threads] JBoss Threads version 3.4.2.Final
[thread:1] scope: main.registerResource
ResourcesFeature: registerResource: java/lang/uniName.dat
[hello-quarkus-1.0-SNAPSHOT-runner:20428] (clinit): 475.20 ms, 5.14 GB
[hello-quarkus-1.0-SNAPSHOT-runner:20428] (typeflow): 2,931.83 ms, 5.14 GB
[hello-quarkus-1.0-SNAPSHOT-runner:20428] (objects): 24,294.27 ms, 5.14 GB
[hello-quarkus-1.0-SNAPSHOT-runner:20428] (features): 2,979.07 ms, 5.14 GB
[hello-quarkus-1.0-SNAPSHOT-runner:20428] analysis: 32,083.24 ms, 5.14 GB
# Printing call tree to: C:\Users\ozkan\tmp\hello-quarkus\target\hello-quarkus-1.0-SNAPSHOT-native-image-source-jar\reports\call_tree_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142406.txt
# Printing list of used methods to: C:\Users\ozkan\tmp\hello-quarkus\target\hello-quarkus-1.0-SNAPSHOT-native-image-source-jar\reports\used_methods_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142407.txt
# Printing list of used classes to: C:\Users\ozkan\tmp\hello-quarkus\target\hello-quarkus-1.0-SNAPSHOT-native-image-source-jar\reports\used_classes_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142407.txt
# Printing list of used packages to: C:\Users\ozkan\tmp\hello-quarkus\target\hello-quarkus-1.0-SNAPSHOT-native-image-source-jar\reports\used_packages_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142407.txt
# Printing call tree for vm entry point to: C:\Users\ozkan\tmp\hello-quarkus\target\hello-quarkus-1.0-SNAPSHOT-native-image-source-jar\reports\csv_call_tree_vm_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142408.csv
# Printing call tree for methods to: C:\Users\ozkan\tmp\hello-quarkus\target\hello-quarkus-1.0-SNAPSHOT-native-image-source-jar\reports\csv_call_tree_methods_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142408.csv
# Printing call tree for virtual methods to: C:\Users\ozkan\tmp\hello-quarkus\target\hello-quarkus-1.0-SNAPSHOT-native-image-source-jar\reports\csv_call_tree_virtual_methods_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142408.csv
# Printing call tree for entry points to: C:\Users\ozkan\tmp\hello-quarkus\target\hello-quarkus-1.0-SNAPSHOT-native-image-source-jar\reports\csv_call_tree_entry_points_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142408.csv
# Printing call tree for direct edges to: C:\Users\ozkan\tmp\hello-quarkus\target\hello-quarkus-1.0-SNAPSHOT-native-image-source-jar\reports\csv_call_tree_direct_edges_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142408.csv
# Printing call tree for overriden by edges to: C:\Users\ozkan\tmp\hello-quarkus\target\hello-quarkus-1.0-SNAPSHOT-native-image-source-jar\reports\csv_call_tree_override_by_edges_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142408.csv
# Printing call tree for virtual edges to: C:\Users\ozkan\tmp\hello-quarkus\target\hello-quarkus-1.0-SNAPSHOT-native-image-source-jar\reports\csv_call_tree_virtual_edges_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142408.csv
[hello-quarkus-1.0-SNAPSHOT-runner:20428] universe: 1,547.28 ms, 5.14 GB
[hello-quarkus-1.0-SNAPSHOT-runner:20428] (parse): 4,919.32 ms, 4.87 GB
[hello-quarkus-1.0-SNAPSHOT-runner:20428] (inline): 7,013.78 ms, 5.83 GB
[hello-quarkus-1.0-SNAPSHOT-runner:20428] (compile): 27,387.04 ms, 5.56 GB
[hello-quarkus-1.0-SNAPSHOT-runner:20428] compile: 41,595.59 ms, 5.56 GB
[hello-quarkus-1.0-SNAPSHOT-runner:20428] image: 2,515.22 ms, 5.56 GB
[hello-quarkus-1.0-SNAPSHOT-runner:20428] write: 858.79 ms, 5.56 GB
[hello-quarkus-1.0-SNAPSHOT-runner:20428] [total]: 90,068.97 ms, 5.56 GB
# Printing build artifacts to: C:\Users\ozkan\tmp\hello-quarkus\target\hello-quarkus-1.0-SNAPSHOT-native-image-source-jar\hello-quarkus-1.0-SNAPSHOT-runner.build_artifacts.txt
[INFO] [io.quarkus.deployment.QuarkusAugmentor] Quarkus augmentation completed in 94323ms
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:37 min
[INFO] Finished at: 2022-03-24T14:24:56Z
[INFO] ------------------------------------------------------------------------