I started playing with quarkus and graalvm. I added files (txt and jpg) to resources in the project (src/main/resources/
). To be sure that I have access to this file in controller I display size of it:
URL url = Thread.currentThread().getContextClassLoader().getResource("/Resource2.txt");
File file = new File(url.toURI());
return "Hello My Friend! File size in bytes = " + file.length();
and when I run it with maven (mvn quarkus:dev
) it works. Controller code is here.
Problem occurred when I created native Quarkus application and try to run inside docker.
To be sure that file is included in native image, I added a big jpg file (3.3MB), created resources-config.json
:
{ "resources":
{ "includes": [
{ "pattern": "IMG_3_3M\\.jpg$"},
{ "pattern": "Resources2\\.txt$"}
]
}}
and in application.properties
added:
quarkus.native.additional-build-args = -H:ResourceConfigurationFiles=resources-config.json
. The native runner size was increased from:
39M Mar 21 12:48 hello-quarkus-1.0-SNAPSHOT-runner
44M Mar 21 12:19 hello-quarkus-1.0-SNAPSHOT-runner
So I assume that jpg file was included, but still when run native application inside docker image, I got NPE:
Caused by: java.lang.NullPointerException
at it.tostao.quickstart.GreetingResource.hello(GreetingResource.java:24)
where line 24: is url.toURI()
.
Any idea how I can read resources in native image? Is something missing in the configuration?
here is sample image to reproduce the problem, all commands needed to build and run native image you can find in README.MD:
https://github.com/sleski/hello-quarkus
So far I checked this urls and still was not able to find resources in native image:
• How to include classpath resources in a Quarkus native image?
• How to read classpath resources in Quarkus native image?
• https://quarkus.io/guides/writing-native-applications-tips
• Read txt file from resources folder on maven Quarkus project From Docker Container
First fix json
{
"resources": [
{
"pattern": "Resource2.txt"
}
]
}
or you can have *.txt as pattern. like in the doc
https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/Resources.md says use
InputStream resource = ModuleLayer.boot().findModule(moduleName).getResourceAsStream(resourcePath);
when I tried I had issues. you can see the working code below for your project
@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);
is actually bringing the resource here. I think this feature may change in the future so I left ModuleLayer in the code too. I used graalvm 17-21.3.0
you can find the build log below
[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] ------------------------------------------------------------------------