micronaut-core: @JsonSubTypes discriminator property not correctly serialized in native image

Expected Behavior

Given a polymorphic class hierarchy that uses @JsonSubTypes to declare a property discriminator

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
        @JsonSubTypes.Type(name = "car", value = Car.class),
        @JsonSubTypes.Type(name = "van", value = Van.class),
})
@Introspected
@Data
public class Vehicle {
  private int wheels = 4;
}

the Car subclass should serialize as {"type":"car", ...} and the Van subclass as {"type":"van", ...} in all cases.

Actual Behaviour

Behaviour is correct when running in a normal JVM (including GraalVM’s java), but in a native image the discriminator "type" property is only present when the Vehicle object is the top level object returned from a controller action.

{"type":"car","passengers":4,"wheels":4}

When the Vehicle is nested as a property of another object the true properties of the Vehicle are serialized as normal but the "type" property is missing.

{"vehicle":{"passengers":4,"wheels":4}}

Steps To Reproduce

  1. clone the example app https://github.com/ianroberts/micronaut-jsonsubtypes-test
  2. ./gradlew test (on a Java 11 JVM - including GraalVM-as-a-JDK)
  • all tests pass
  1. ./gradlew testNativeImage (which of course requires GraalVM)
  • “unwrapped” tests pass, “wrapped” tests fail

Environment Information

  • Java 11, both adoptopenjdk and GraalVM CE 21.3.0
  • Mac OS 11 (Big Sur), but the same issue occurs when building native image as a Docker container (which runs Linux)

Example Application

https://github.com/ianroberts/micronaut-jsonsubtypes-test

Version

3.2.3

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 21 (9 by maintainers)

Most upvoted comments

With configuration properties there’s a lot more to it than just loading a single YAML/JSON file - various property sources get merged into one (the application.yml inside the JAR, values from environment variables, files named in MICRONAUT_CONFIG_FILES env var or micronaut.config.files system property, etc. etc.) and then the configuration properties bean is data-bound from the final merged config data.