quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.57k stars 2.63k forks source link

GeneratedResourceBuildItem doesn't work to generate a static resource file #25303

Closed hbelmiro closed 2 years ago

hbelmiro commented 2 years ago

Describe the bug

I'm writing an extension that needs to generate files that will be downloaded by the end-user as static resource. Like stated here, those files need to be placed in the META-INF/resources directory. For instance, the META-INF/resources/my_resource.txt file should be accessible from http://localhost:8080/my_resource.txt. To do that, I used the following code:

    @BuildStep
    void produceSourceFiles(BuildProducer<GeneratedResourceBuildItem> resourceProducer) {
        String path = "classes/META-INF/resources/my_resource.txt";
          /*
        Also tried to use the following:
        - String path = "META-INF/resources/my_resource.txt";
        - String path = "/META-INF/resources/my_resource.txt";
         */

        resourceProducer.produce(new GeneratedResourceBuildItem(path, "This is the content".getBytes()));
    }

But it doesn't work. The file isn't accessible from http://localhost:8080/my_resource.txt. I could make it work by replacing GeneratedResourceBuildItem with GeneratedFileSystemResourceBuildItem. But in this Zulip topic, @gsmet told me that it should work with GeneratedResourceBuildItem and aksed me to open this issue.

I created this repository to reproduce the issue. There are 2 projects in there:

  1. quarkus-generate-static-resource-extension-demo - The extension
  2. quarkus-generate-static-resource-extension-demo-test - The application that uses the extension

Expected behavior

The application should serve the file as a static resource.

Actual behavior

The application doesn't serve the file as a static resource.

How to Reproduce?

Steps to reproduce:

  1. Install the extension:

    cd quarkus-generate-static-resource-extension-demo
    mvn install
  2. Run the application

    cd ../quarkus-generate-static-resource-extension-demo-test
    mvn quarkus:dev
  3. Try to access the file in http://localhost:8080/my_resource.txt

Output of uname -a or ver

uname -a Linux fedora 5.16.18-200.fc35.x86_64 #1 SMP PREEMPT Mon Mar 28 14:10:07 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

Output of java -version

java -version openjdk version "17.0.2" 2022-01-18 OpenJDK Runtime Environment Homebrew (build 17.0.2+0) OpenJDK 64-Bit Server VM Homebrew (build 17.0.2+0, mixed mode, sharing)

GraalVM version (if different from Java)

No response

Quarkus version or git rev

2.8.2.Final

Build tool (ie. output of mvnw --version or gradlew --version)

Apache Maven 3.8.4 (9b656c72d54e5bacbed989b64718c159fe39b537)

Additional information

No response

quarkus-bot[bot] commented 2 years ago

You added a link to a Zulip discussion, please make sure the description of the issue is comprehensive and doesn't require accessing Zulip.

This message is automatically generated by a bot.

quarkus-bot[bot] commented 2 years ago

/cc @Sanne, @aloubyansky, @geoand, @gsmet, @radcortez, @stuartwdouglas

stuartwdouglas commented 2 years ago

Use io.quarkus.vertx.http.deployment.spi.AdditionalStaticResourceBuildItem.

hbelmiro commented 2 years ago

@stuartwdouglas @geoand

Actually, the file is programmatically created and, as AdditionalStaticResourceBuildItem's constructor expects a path (and not the file contents as GeneratedResourceBuildItem does), I had to create the file using Files.write(... and then create the AdditionalStaticResourceBuildItem. For my surprise, it works without even using AdditionalStaticResourceBuildItem. I just created the file in the resources/META-INF/resources directory and it even worked in the native image. This solves the problem I described here in this issue.

Now I have another problem, which is the original one and the reason why I created this issue. I work in the Kogito team and I'm creating an extension that needs to create static resources. But the same solution that worked for the reproducer (pure Quarkus app) we used in this issue doesn't work in Kogito. The static resources are not available in the native image. I tried several approaches, but none of them makes it work. My team mates don't know of any config or restriction from Kogito that prevents those files from being copied to the native image. So, it should work the same way as a pure Quarkus application.

Can I use this same issue or do I need to create a new one?

Here is the code.

ia3andy commented 2 years ago

It seems you need to use BuildProducer<NativeImageResourceBuildItem> nativeImageResourceBuildItemBuildProducer, I am facing similar problems in the Quinoa extension. I am currently trying it alongsideGeneratedResourceBuildItem, I will let you know :)

You can find an example in ConfigGenerationBuildStep

ia3andy commented 2 years ago

Also I agree we should have a AdditionalGeneratedStaticResourceBuildItem to avoid creating the file.

ia3andy commented 2 years ago

Ok I tested native and it now works: https://github.com/quarkiverse/quarkus-quinoa/pull/32/files

hbelmiro commented 2 years ago

@ia3andy my case is a bit different than yours. I need to generate static HTTP resources. AFAIK NativeImageResourceBuildItem is for resources as in src/main/resources, but not for the HTTP ones. For the HTTP ones, we should use AdditionalStaticResourceBuildItem, as its javadoc says:

Meant to be used by extensions that generate resource into {@code META-INF/resources}. These resources cannot be picked up automatically by the standard Static resources handling because when the check is made, these resources don't exist yet on the file system.

The value of {@code path} should be prefixed with {@code '/'} and is assumed to be a path under {@code 'META-INF/resources'}.

But, I tested with NativeImageResourceBuildItem anyway and it doesn't work.

hbelmiro commented 2 years ago

I made it work finally. I had to use GeneratedResourceBuildItem, NativeImageResourceBuildItem and AdditionalStaticResourceBuildItem. I was pretty sure I had tried this combination in one of the several previous attempts, but I might missed some detail.