skip to Main Content

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
  • to: 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

2

Answers


  1. Chosen as BEST ANSWER

    This is how I solved the problem - example with changes are in this branch: https://github.com/sleski/hello-quarkus/tree/solution_for_native

    Explanations:

    Image is in: src/main/resources/images and name is:IMG_3_3M.jpg. In application.properties I added images.location variable:

    images.location=src/main/resources/images/
    %prod.images.location=/work/images/
    

    and in the java controller I added:

    @ConfigProperty(name = "images.location")
    String imageLocation;
    

    in docker.native added: COPY target/classes/images/*.jpg /work/images/

    When I start application with querkus:dev it is getting image from src/main/resources/images and when I run narive image: /work/images.

    In both cases work: File size is = 3412177.


  2. 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 FilesGraalVMgraalvm-ce-java17-21.3.0binnative-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:Usersozkantmphello-quarkustargethello-quarkus-1.0-SNAPSHOT-native-image-source-jarreportscall_tree_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142406.txt
    # Printing list of used methods to: C:Usersozkantmphello-quarkustargethello-quarkus-1.0-SNAPSHOT-native-image-source-jarreportsused_methods_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142407.txt
    # Printing list of used classes to: C:Usersozkantmphello-quarkustargethello-quarkus-1.0-SNAPSHOT-native-image-source-jarreportsused_classes_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142407.txt
    # Printing list of used packages to: C:Usersozkantmphello-quarkustargethello-quarkus-1.0-SNAPSHOT-native-image-source-jarreportsused_packages_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142407.txt
    # Printing call tree for vm entry point to: C:Usersozkantmphello-quarkustargethello-quarkus-1.0-SNAPSHOT-native-image-source-jarreportscsv_call_tree_vm_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142408.csv
    # Printing call tree for methods to: C:Usersozkantmphello-quarkustargethello-quarkus-1.0-SNAPSHOT-native-image-source-jarreportscsv_call_tree_methods_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142408.csv
    # Printing call tree for virtual methods to: C:Usersozkantmphello-quarkustargethello-quarkus-1.0-SNAPSHOT-native-image-source-jarreportscsv_call_tree_virtual_methods_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142408.csv
    # Printing call tree for entry points to: C:Usersozkantmphello-quarkustargethello-quarkus-1.0-SNAPSHOT-native-image-source-jarreportscsv_call_tree_entry_points_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142408.csv
    # Printing call tree for direct edges to: C:Usersozkantmphello-quarkustargethello-quarkus-1.0-SNAPSHOT-native-image-source-jarreportscsv_call_tree_direct_edges_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142408.csv
    # Printing call tree for overriden by edges to: C:Usersozkantmphello-quarkustargethello-quarkus-1.0-SNAPSHOT-native-image-source-jarreportscsv_call_tree_override_by_edges_hello-quarkus-1.0-SNAPSHOT-runner_20220324_142408.csv
    # Printing call tree for virtual edges to: C:Usersozkantmphello-quarkustargethello-quarkus-1.0-SNAPSHOT-native-image-source-jarreportscsv_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:Usersozkantmphello-quarkustargethello-quarkus-1.0-SNAPSHOT-native-image-source-jarhello-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] ------------------------------------------------------------------------
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search