Feature request: registering subtypes without annotating the parent class
See original GitHub issueWhen using @JsonTypeInfo
with use = Id.NAME
, it is currently required to provide the name to class map with the @JsonSubTypes
annotation on the parent class. This is problematic if a third-party wants to extend my code: they will have to modify my code to register their new subclass.
It would be fantastic if the mapping could be provided via annotations on the subclasses themselves. Something like this:
@JsonTypeInfo(use = Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type")
public interface Parent {
// ...
}
@JsonTypeName(name = "first-child")
public class FirstChild extends Parent {
// ...
}
@JsonTypeName(name = "second-child")
public class SecondChild extends Parent {
// ...
}
This would require retrieving at runtime the subclasses and building the map based on their annotations. This can already be achieved by implementing a custom TypeIdResolver
but the use case seems to be fairly common so I think it would make sense to add this to Jackson directly.
Related SO question: https://stackoverflow.com/questions/34079050/add-subtype-information-at-runtime-using-jackson-for-polymorphism
Issue Analytics
- State:
- Created 5 years ago
- Comments:8 (1 by maintainers)
Top GitHub Comments
A few workable ideas:
registerSubtypes()
(esp. viaModule
) is the way to go. I am not sure I would want to have functionality for this directly in databind, but if someone wants to work on general-purpose extension module, that could be added underFasterXML
if it proves useful.My experiences with SPI for Java 8 and earlier make me pretty skeptic of using it for anything (and possible even more so for registering services actually… performance is horrendous, no way to deal with duplicates, mere existence of something in classpath changing things in weird and non-reproducible ways). But then again, it is a somewhat documented mechanism and Jackson does expose metadata already and even allows auto-registering of Modules (which I personally never use and do not recommend but that’s matter of taste 😃 ). And Java 9+ module path probably makes access less inefficient as well, so as mechanism maybe it is becoming more usable.
So: if anyone wants to create prototype module, great; that would be reasonable way to add such functionality for users I think.
There’s a pattern used by the Dropwizard framework that works pretty well. Put the subclasses in the
META-INF/services
directory under the interface and just load the file, iterating through the lines of the file in a Jackson module callingregisterSubtypes
. Then you can just annotate each class with@JsonTypeName
and it just works.Example: META-INF/services/package.Parent
In your jackson module: