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
- clone the example app https://github.com/ianroberts/micronaut-jsonsubtypes-test
./gradlew test
(on a Java 11 JVM - including GraalVM-as-a-JDK)
- all tests pass
./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)
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 inMICRONAUT_CONFIG_FILES
env var ormicronaut.config.files
system property, etc. etc.) and then the configuration properties bean is data-bound from the final merged config data.