helidon-io / helidon

Java libraries for writing microservices
https://helidon.io
Apache License 2.0
3.52k stars 564 forks source link

JSON SerDes problem with jakarta.ws.rs.core.Response and lombok with GraalVM Native Image #8188

Open dcoracle opened 10 months ago

dcoracle commented 10 months ago

Getting {} as a JSON response to a REST endpoint when compiling to native-image

Environment Details


Problem Description

Problem occured as I was exploring the migration to native-image. All of our helidon microservices use lombok for our beans and jakarta.ws.rs.core.Response to construct responses to our REST-based endpoints. When building and running as a java application, everything works fine and the JSON response is correct. When compiling to native image, I get {} as the response. No errors in the stacktrace

Steps to reproduce

  1. Start with helidon-quickstart-mp for Helidon 4.0.1
  2. Create below Message2.java bean:
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class Message2 {
    private String message;
    private String greeting;
}
  1. Add to GreetResouce.java:
    @Path("/msg2/{name}")
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response getMessage2(@PathParam("name") String name) {
        return Response.ok(Message2.builder().message("hello "+name+"!").build()).build();
    }
  2. Compile normally in java and run
    $ mvn package
    ...
    $ java -jar target/helidon-quickstart-mp.jar
    ...
    ...
    $ curl localhost:8080/greet/msg2/joe
    {"message":"hello joe!"}
  3. Compile to native image and run
    $mvn -Pnative-image install -DskipTests
    ...
    $./target/helidon-quickstart-mp
    ...
    ...
    $ curl localhost:8080/greet/msg2/joe
    {}
dcoracle commented 10 months ago

This could be a red herring but the issue sounds very similar to this: https://github.com/micronaut-projects/micronaut-core/issues/7179

tomas-langer commented 10 months ago

There are two reasons why this may not work:

  1. insufficient configuration of reflection for native image - all types that are processed using reflection must be added in reflect-config.json (native image specific configuration file), as otherwise they will not work at runtime (e.g. you get an empty object with no field and methods)
  2. some problem related to Lombok - I am sorry, we cannot help if this is the case. We do not use Lombok and we do not support it. Please try to reproduce the issue without lombok usage (if point 1 does not help you)
tomas-langer commented 10 months ago

If you create the following file (assuming Maven project): src/main/resources/META-INF/native-image/groupId/artifactId/reflect-config.json with the following content:

[
    {
        "name": "your.package.Message2",
        "allPublicMethods": true
    }
]

your problem should be fixed

dcoracle commented 10 months ago

Thank you for the quick response tomas. Your suggestion worked. I must admit I am new to native images so I was just following and trying to adapt our microservices based on this: https://helidon.io/docs/v4/mp/guides/graalnative

Maybe as feedback, some quick blurb in the documentation can be said about reflection (or maybe a sample file can be added to the quickstart archetype)

Thanks again