Details
-
Type:
New Feature
-
Status:
Closed
-
Priority:
Major
-
Resolution: Fixed
-
Affects Version/s: None
-
Fix Version/s: 1.5
-
Component/s: None
-
Labels:None
-
Number of attachments :1
Description
Although I feel that it is not a good idea to heavily use polymorphism (by inheritance) when exchanging data (Json != Object graph), there are cases where this is useful. And perhaps full object serialization is something Jackson could eventually do well enough.
Currently it is hard to handle sub-classing correctly and generally without having a way to embed class information in Json transmitted. But if class information (qualified name should be enough) was added, it would be much easier to support proper deserialization to exact types (from serialization).
This of course also renders resulting Json somewhat less portable, since impls on other languages would achieve the same result some other way. That is probably acceptable risk, given that no one has to use such feature.
So.... It would make sense to have simple serialization/deserialization feature that:
- On writer (serialization) side would include "class" (or, "@class"?) member in beans that are serialized as Json Objects
- On reader (deserialization) side would look for the same member, and use that class as the value type, instead of declared type, or annotation-derived type.
In addition to global setting, perhaps similar annotation should be added that could be attached to class (to add such class declaration for class itself) and setters/getters (to add declaration for property method represents, iff it's serialized as a Json Object).
One thing to note is that this would not allow specifying container type of Collections, but it would still work for contents. This is probably acceptable deficiency as well.
-
Hide
- jackson_test.zip
- 15/Feb/10 4:46 PM
- 9 kB
- Mike Rheinheimer
-
- jackson_test/bin/org/.../jaxb/Mike.class 0.8 kB
- jackson_test/bin/.../jaxb/MyJAXBObject.class 1 kB
- jackson_test/bin/.../ObjectFactory.class 2 kB
- jackson_test/bin/org/.../jaxb/IMike.class 0.1 kB
- jackson_test/bin/org/mike/Tester.class 4 kB
- jackson_test/.project 0.4 kB
- jackson_test/src/org/mike/jaxb/Mike.java 0.5 kB
- jackson_test/src/.../jaxb/ObjectFactory.java 1 kB
- jackson_test/src/.../jaxb/MyJAXBObject.java 0.7 kB
- jackson_test/src/org/.../jaxb/IMike.java 0.1 kB
- jackson_test/src/org/mike/Tester.java 2 kB
Activity
I'm definitely interested in this feature as well. Can any Jackson developers point me to some places I can start digging around in the JsonWriter and JsonReader, is there some type of way to plugin this behavior without disrupting the default JSON read/write capabilities?
Why is polymorphism frowned upon so much when discussion Java objects to JSON data exchange? I do agree that it really is only useful if your deserialization system could support that meta-data to it's own strongly typed system.
Also in terms of a JSON schema using the knowledge of the root Java object type a lot of the elements could be devoid of the meta-data "@class" but there are cases like subclasses where you absolutely require that meta-data to properly deserialize (and maybe that's the point if you need to know the exact type then it should be a different concretely defined field). If only a minimal set of "@class" elements are used it wouldn't pollute the JSON output and could easily be ignored by systems that don't care about that information like Javascript.
For example if I had the following set of classes, I'd like to see a JSON output as follows:
class Message {
public long id = 2;
}
class NamedMessage extends Message {
public String name = "testName";
public long[] idTags =
;
}
class MessageContainer {
public List<Message> messages;
}
MessageContainer msgContainer = new MessageContainer();
List<Message> messages = new ArrayList<Message>();
messages.add(new Message());
messages.add(new NamedMessage());
messages.add(new Message());
messages.add(new NamedMessage());
msgContainer.messages = messages;
JSON output that included sufficient type information to deserialize:
{"messages":
[
,
,
,
{"@class":"com.ddaniels.NamedMessage", "id": 2, "name": "testName", "idTags": [1, 2, 3 ] } ]
}
It could be taken further and annotations could be attached to the Java classes (which I consider as the schema) to provide generic Collection default type information (if you use primitive arrays you could use that information as the default type, e.g. Message[] would allow you to not include "@class" for instances of the base object Message).
class MessageContainer {
@JsonDefaultCollectionType(Message.class)
public List<Message> messages; //or simply use a Message[] to implicitly have the Message.class as the default collection type
}
{"messages":
[
,
,
,
{"@class":"com.ddaniels.NamedMessage", "id": 2, "name": "testName", "idTags": [1, 2, 3 ] } ]
}
I'd then plan on using this strongly type Java class to generate serializiation/deserialization code for other languages like ActionScript or C# that would let me create an object hierarchy that could be read/written in JSON.
Quick comment on polymorphism being frowned upon: I think this may be related to multiple things, like:
- Part of that may be serialization vs data binding impedance: as in, "object first" or "data first". If you view JSON data as the primary thing, there is no strict type structure, no identity, no behavior, just data. But starting with (Java) objects reverse is true. So from "purist" data binding/mapping perspective, metadata that is needed for serialization (type/class) seems like noise.
- It is also quite tricky to get polymorphism work right – this is not necessarily a good reason to be against that, as long as it can be made to work.

My view on this has evolved a lot, and although I think there is fundamental difference between views here I think Jackson can and should evolve to handle important aspects of both approaches. Jackson's background is data binding, so there is much more to do with serialization side; and it can not be done solely focusing on how to transfer java objects (if that was the goal, it'd be easy – could just use very strict serialization of class metadata etc, no need to allow custom JSON structures etc).
I'll try to add more thoughts on exact details tho: above is just some philosophic/background stuff, and not directly related to implemntation.
Additional notes: I think it's worth pursuing proper polymorphic deserialization, and include class-name inclusion as one of methods for achieving this. I think general system can be defined where combinations of various aspects could be used.
For example:
- First define where metadata is to be stored:
- As a single named property, configurable, per-method defaults (for class-name one that'd be "@class")
- As wrapper property (JAXB style); name of property is metadata, contents are actual data. With class that'd mean class name as key, actual object data as JSON object value
- Then define method
- Java class (with partial or full path, depending)
- Type name (requires mapping between name and class name)
- Custom (define custom converter class that gets passed metadata)
Why make it more complex like this? To support both java-only use case (with less config, but without interoperability with other systems), more generic one (type names between platforms, languages) and anything else (custom). And java class based method should be no more complicated to implemented – much of functionality would be shared between methods; specifically unpacking of metadata (which is usually a String, but that's not a requirement: could even be a full JSON-bound object!).
Now that 1.3.0 is released, we could start implementing this to maybe be included in 1.4.0 release.
I need to implement this on a current project. Is there a workaround I can use while waiting for this feature to be developed? I have the following:
@XmlElements({
@XmlElement(name = "textbox", type = TextBox.class),
@XmlElement(name = "radio", type = Radio.class)
})
private List<Element> elements;
And I expect it to come across as "textbox" and "radio", but it comes across as "elements" instead.
JAXB annotation support currently only maps to existing features of serializer/deserializer, so this will not have any effect.
My hope has been to first tackle the "full" system, into which this annotation would easily map to.
Challenge with partial solutions is two-fold: first, while serialization would be easy to implement, deserialization is less so (although probably easier than full solution). And second is that any interims solution should work nicely with eventual full solution.
For what it's worth, initial plan for full PM is outlined at http://wiki.fasterxml.com/JacksonPolymorphicDeserialization. This would be part of 1.5 release – 1.4 should be finalized during december 2009, and just include some more features (json view, static typing for root level serialization) beyond what is already in trunk.
As to work arounds: you can do a lot with custom serializers/deserializers, but that's about it, at least for specific style that JAXB uses. We are of course always open for patches and recommendations.
On short term, my highest priority is to wrap 1.4, since that would allow starting PM implementation; first thing could be annotations, and then it'd be much easier for others to be involved?
Thinking through this issue a bit more, I think best course of action is to implement short term feature that does allow serializing bean objects with class information (global on/off feature); in such a way that it will be the baseline that later PM annotations can override.
And obviously implement counterpart for deserialization.
I will outline the plan on mailing list, and target it for 1.4 release.
Whether that will work nicely with JAXB annotation in question is still an open question: I don't think it would quite work; so the question is, what is the most important aspect – to allow preserving type information as a feature, or making JAXB annotations work in a way to do this.
what is the most important aspect - to allow preserving type information as a feature, or making JAXB annotations work in a way to do this.
I'm not sure they're mutually exclusive. I'm fine with using a different mechanism (Jackson annotations vs. JAXB annotations) to produce/consume JSON with subclass information.
Eventually they are not conflicting, it's just that if I am to add interim feature (subset of eventual feature set, ideally), that has to focus on specific deliverable.
So: what I am thinking of doing is equivalent to forcing writing of actual class name in configurable per-JSON-object property (like "@class"), and making deserializer use that for instantiation. This would only be globally on/off feature, and not allow type names or other configurability (except for choosing name of property to use).
Would this be useful? I am just asking to avoid implementing something that would not address the problem; if that was the case I would be better off working on the "full" thing from beginning.
FWIW I am finally progressing with Json View too; checked in initial version, just need to modify slightly to allow better overriding (no support for alternative view definition schemes per se, just possibility to subclass and override to do so).
Sorry for posting this here, but I've tried sending this to the mailing list several times (from different accounts) and it keeps bouncing.
I've implemented JsonSerializable in my class in order to handle a List<Element> where I want the child classes to show up in the JSON. This is a workaround for the following not working (yet) with Jackson.
@XmlElements({
@XmlElement(name = "textbox", type = TextBox.class),
@XmlElement(name = "radio", type = Radio.class)
})
private List<Element> elements;
The code is below, but I'm still seeing "key": null in my JSON output. Is the 3rd line below correct?
Thanks,
Matt
public void serialize(JsonGenerator jgen, SerializerProvider provider) throws IOException { provider.getConfig().setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL); Class clazz = this.getClass(); jgen.writeStartObject(); writeFields(jgen, clazz.getSuperclass().getDeclaredFields()); writeFields(jgen, clazz.getDeclaredFields()); jgen.writeEndObject(); } private void writeFields(JsonGenerator jgen, Field[] fields) throws IOException { for (Field field : fields) { field.setAccessible(true); if (field.getType().equals(List.class)) { try { List values = (List) field.get(this); // build up types of objects in list Map<String, List<Element>> map = new LinkedHashMap<String, List<Element>>(); for (Object value : values) { String key = value.getClass().getSimpleName().toLowerCase(); if (map.containsKey(key)) { map.get(key).add((Element) value); } else { List<Element> elements = new ArrayList<Element>(); elements.add((Element) value); map.put(key, elements); } } System.out.println(map); for (String key : map.keySet()) { if (map.get(key).size() > 1) { jgen.writeArrayFieldStart(key); List<Element> elements = map.get(key); for (Element e : elements) { jgen.writeObject(e); } jgen.writeEndArray(); } else { Element e = map.get(key).get(0); jgen.writeFieldName(key); jgen.writeObject(e); } } } catch (IllegalAccessException iae) { iae.printStackTrace(); } } else { try { jgen.writeObjectField(field.getName(), field.get(this)); } catch (IllegalAccessException iae) { iae.printStackTrace(); } } } }
Hmmh. One thing to note is that the config change has no effect, if it's called during operation itself (needs to be set prior to serialization, since it affects how bean serializers are constructed, and serializers are cached – later changes are not guaranteed to have any effect). So that could explain some part.
But can you add sample JSON output; I may be missing part of the issue here.
Hi, I'll put in a vote for this too. I have JAXB objects that I cannot change. Because of this, I'll require some type information to be transmitted with the JSON. For example, my JAXB object:
@XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "ReturnWrapper", namespace = "http://org.mike/") public class ReturnWrapper implements Serializable{ @XmlElement private Object returnObject;
That "returnObject" could be anything. Currently, Jackson correctly deserializes it to a LinkedHashMap. I need it to be the expected object. The only way I can see to do this is for the type data to be transmitted with the corrosponding JSON in-message.
This will be the major issue to work on after 1.4.0 release (which will be RSN). I will start with simplest way to do this (which will essentially do what original issues requested), get that working, then move on to full/better handling.
Started work on full polymorphic type handling implementation: checking in annotations, interfaces, and hopefully will have a working implementation within a week. Will be part of 1.5.0.
Tatu, you are a rock star! Thanks for working on this. I'll keep an eye on the jira and be glad to give it a thorough test when you have an alpha.
Work is maybe 60% complete: for a sneak peek, have a look in trunk, and look for usage of @JsonTypeInfo. Serialization support more complete (method based on class name), deserialization almost works as well. Unit tests (src/test/.../jsontype/*.java) show some usage.
Should have complete implementation early next week.
Implemented fully automatic Polymorphic Type Handling; using 2 mechanism:
- @JsonTypeInfo annotation on base type, to indicate if and how type metadata is to be included in JSON
- ObjectMapper.enableDefaultTyping() to alternatively force specific type info setting on class of types (Object.class, abstract types)
Looks like this new feature is not handling collections correctly. I've only tested it so far, have not yet looked at Jackson source. When reading the following JSON:
{"mikes":["java.util.ArrayList",[["org.mike.jaxb.Mike",
{"id":"mike1"}],["org.mike.jaxb.Mike",
{"id":"mike2"}]]]}
I get the error:
Caused by: java.lang.IllegalArgumentException: Class org.mike.jaxb.Mike is not assignable to java.util.List
at org.codehaus.jackson.type.JavaType._assertSubclass(JavaType.java:284)
at org.codehaus.jackson.type.JavaType.narrowBy(JavaType.java:76)
at org.codehaus.jackson.map.deser.BasicDeserializerFactory.modifyTypeByAnnotation(BasicDeserializerFactory.java:510)
I've attached a testcase. The output JSON looks ok to me, but the reader obviously didn't like it.
Collections should be supported, but sounds like there are issues. Will investigate.
Test seems to be missing actual test code (that does serialization), so I can not be 100% sure, but I think the problem is due to use of @XmlElement (only), not @XmlElements. Or rather, because JAXB annotation handler assumes it's always latter, not former.
So this might be a really easy fix (for a somewhat silly omission – I have not used JAXB polymorphic part before so it's a newbie mistake).
Hi Tatu. Not sure what you mean by "test seems to be missing actual test code." What I zipped and uploaded in jackson_test.zip is everything I was using. Do I need to have some kind of custom serializer? Do I need to modify my JAXB annotations? Thanks.
Hmmh. Actually, it's bit more complicated than this: @XmlElement was already supported before PTH. So this has more to do with bit of overlap, and oddity of JAXB annotations that has to do with Lists vs scalars handling. Blah. Reminds me of why I do not like JAXB annotations.
At any rate, there is a problem to resolve, which I am working on now.
Fixed the issue related to @XmlElement used for container types (Lists, Maps, arrays). Passes unit tests I added, and hopefully works for your test case (should, from what I can see).
Please let me know if you encounter other problems.
I will go ahead and push a new 1.5.0 snapshot to codehaus maven snapshot repo as well.
With the same testcase code, I now get:
org.codehaus.jackson.map.JsonMappingException: Unexpected token (VALUE_STRING), expected START_ARRAY: need JSON Array to contain As.WRAPPER_ARRAY type information for class java.util.List
at [Source: java.io.ByteArrayInputStream@53505350; line: 1, column: 11]
at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:159)
at org.codehaus.jackson.map.deser.StdDeserializationContext.wrongTokenException(StdDeserializationContext.java:240)
at org.codehaus.jackson.map.jsontype.impl.AsArrayTypeDeserializer._locateTypeId(AsArrayTypeDeserializer.java:94)
at org.codehaus.jackson.map.jsontype.impl.AsArrayTypeDeserializer._deserialize(AsArrayTypeDeserializer.java:80)
at org.codehaus.jackson.map.jsontype.impl.AsArrayTypeDeserializer.deserializeTypedFromObject(AsArrayTypeDeserializer.java:49)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeWithType(BeanDeserializer.java:342)
at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:109)
at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:84)
at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:24)
at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:135)
at org.codehaus.jackson.map.deser.SettableBeanProperty$FieldProperty.deserializeAndSet(SettableBeanProperty.java:326)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:390)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:286)
at org.codehaus.jackson.map.ObjectMapper._readValue(ObjectMapper.java:1456)
at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:728)
at org.codehaus.jackson.jaxrs.JacksonJsonProvider.readFrom(JacksonJsonProvider.java:339)
at org.mike.Tester.runTest(Tester.java:52)
at org.mike.Tester.main(Tester.java:24)
I was able to reproduce additional problems: difference between my test case and yours is that I only had public field with annotations.
Your code had annotation for the field, but not accessor/setter, and Jackson JAXB annotation introspector apparently does not link the two.
I assume JAXB does this (given that test case relies on linkage), so this seems like a discrepancy between Jackson and JAXB handling.
I will try to resolve this issue.
What concerns me a bit tho is that error message I get is somewhat different – looks like test case manages to make ObjectMapper think that polymoprhic type info is included, which should NOT be the case.
This is because plain @XmlElement does not indicate polymorphic type (but rather just specialization of single type), whereas @XmlElements does.
Hence test case should not actually use PTH, just "regular" type definition.
Anyway, one thing at a time, I will address the problem I do see and see if there are other problems lurking behind it. ![]()
Hmmh. This may be tricky to resolve... need to consider if it's even worth supporting, since solving this completely might mean serious rewrite of annotation introspector interface.
JAXB annotations continue to be a royal PITA. :-/
Problem here is specifically how to efficiently link property descriptors (which ONLY cover methods, getters and setters) and fields.
Created JACKSON-242 for future work on revamping annotation introspection framework.
But for now I think will be able to find a way to solve this particular problem, with more limited scope of work.
Fixed the immediate problem, once again. Will try to see if I can find other problems; let me know if you find some.
Tatu, not sure what's going on. I'm still getting the same problem. I'm up to SVN rev 791 out of trunk. I tried two different JVMs (IBM J9 VM build 2.4, J2RE 1.6.0 IBM J9 2.4 Linux x86-32 jvmxi3260-20090215_29883 and Sun: 1.6.0_13-b03)
I can hook up a debugger or collect some trace if you'd like..
Hello !
I was able to do a bit of polymorphic (de)serializing with Jackson 1.4 (not wanting to wait for 1.5
), but I'd like to come up with something more "generic".
The idea is to add a "clazz" field to the parent for serializing, and to use a custom deserializer for this parent type, that first deserialize the bean to a map, look for the "clazz" key, and uses om.convertValue to convert the map to the real bean.
Here is the code :
************************
public class JacksonTestPolymorphic {
private static abstract class MyBean
{ public String name; public String clazz = getClass().getName(); } private static class SubMyBean1 extends MyBean {
public String myString;
@Override
public String toString()
}
private static class SubMyBean2 extends MyBean {
public double myDouble;
@Override
public String toString()
}
public static void main(String[] args) throws Exception {
final ObjectMapper om = new ObjectMapper();
CustomDeserializerFactory cdf = new CustomDeserializerFactory();
DeserializerProvider dp = new StdDeserializerProvider(cdf);
cdf.addSpecificMapping(MyBean.class, new JsonDeserializer<MyBean>() {
@Override
public MyBean deserialize(JsonParser arg0, DeserializationContext arg1) throws IOException,
JsonProcessingException {
Map<String, String> map = om.readValue(arg0, new TypeReference<Map<String, String>>() {});
Class clazz;
try
catch (ClassNotFoundException e)
{ throw new IOException(e); } return (MyBean) om.convertValue(map, clazz);
}
});
om.setDeserializerProvider(dp);
SubMyBean1 bean1 = new SubMyBean1();
bean1.name = "b1";
bean1.myString = "yeah !";
SubMyBean2 bean2 = new SubMyBean2();
bean2.name = "b2";
bean2.myDouble = 42;
String bean1AsJson = om.writeValueAsString(bean1);
String bean2AsJson = om.writeValueAsString(bean2);
System.out.println(bean1AsJson);
MyBean bean1Back = om.readValue(bean1AsJson, MyBean.class);
MyBean bean2Back = om.readValue(bean2AsJson, MyBean.class);
System.out.println(bean1Back);
System.out.println(bean2Back);
}
}
***********************
I used om.convertValue because I needed to read the Json to determine the real implementation class, and then delegate to the good deserializer.
There might be other ways to do so, without having to convert twice.
Also, adding a "clazz" field in the bean is not clean, I'd rather set a special Serialiser using @JsonSerializer. This Serialiser could then write the "clazz" property, but then I don't know how to delegate to the "real" expected Serializer. So here, the question is : how can we add fields (metadata) for some specific classes serialization in 1.4 ? Any kind of "InterceptorSerializer", that would let you serialize data before/after the std serializers for some specific classes ?
I may be going to far, or completely missing the point.. Please let me know ![]()
If you can make existing 1.4 API work for certain set of classes, I'm sure other users would find it useful.
Additional code could (should) be added to sample code, or sand box area (to be created).
As a general rule, no new functionality or behavioral changes other than bug fixes are added to finalized versions.
So I would be hesitant to add anything new there. Part of the reason is that this would make patch versions have much more significance, such that users would be less likely to be able to just define version "1.4.x" in Maven.
But if you figure very small changes that would allow things to work, I am open to suggestions.
In general your approach makes sense. There may not be way to really avoid binding things twice. convertType will actually be quite efficient in 1.5 (due to introduction of TokenBuffer), so this might not be a problem.
In fact, 1.5 approach works in a way similarly, first finding base-class handlers for deserialization, and only delegates once it locates subclass handler.
Handler is located by using deserialization context; for serialization, this can be done using SerializerProvider.
I'm just starting to use this feature by compiling the trunk and as far as I know the 1.5 is nearly the delivery (cool!).
So just a little note for the release if not yet identified: ObjectMapper.setDefaltTyping ==> ObjectMapper.setDefa*u*ltTyping
![]()
Whoa. Nasty typo... where is that at? Definitely need to fix. Dang IDEs, too easy to add typos (via refactoring). :-/
Is there any sample on how to customize default typing?
Actually,my use case is probably taken into account but I miss documentation (and time
.
I want to force a specific implementation class B to be the default deserialization for an interface A.
And I'd like do it without introducing a dependency from A to B (@JsonSubTypes).
Do I have to use JsonTypeResolver? Any sample to make it easy?
Wrt default typing; no, but it should be easy by looking at ObjectMapper's default implementation.
However, that alone would not be enough.
But... hmmh. It would allow you to provide other JsonTypeResolver, which you do need.
That would allow not having annotation dependency.
On same note, I am hoping to find better ways to register subtypes, without requiring direct
coupling. Feel free to suggest approaches; simplest one would be to add a method to just
register arbitrary types, which would automatically checked for supertypes to establish linking.
Btw: just for default impl to use, @JsonDeserialize.as should allow doing it, although with direct coupling
(mix-ins can avoid that), if that's enough.
Hi, after dealing with other stuff, I come back to my deserialization use case ![]()
Let's take the following sample: my objective is to avoid declaring JsonSubTypes on the mother class, to avoid coupling, by using mixins.
(Dog and Cat are part of two different packages, and Animal is used in a framework not knowing all animals in advance)
@JsonTypeInfo(use=Id.NAME, include=As.PROPERTY, property="objectType")
abstract class Animal { }
@JsonTypeName("doggie")
class Dog implements Animal { }
@JsonTypeName("kitty")
class Cat implements Animal { }
@JsonSubTypes (
{ @Type(value = Cat.class, name = "kitty") } )
static class MixinCat {
}
@JsonSubTypes(
{ @Type(value = Dog.class, name = "doggie") } )
static class MixinDog {
}
m.getDeserializationConfig().addMixInAnnotations(Animal.class, MixinDog.class);
m.getDeserializationConfig().addMixInAnnotations(Animal.class, MixinCat.class);
The problem here is that a mixin can only be associated to one and only one target class.
What I need would be kind of aggregation of annotations on all of my mixins and apply it to a target class.
Any idea on how to do that?
Probably by using tricky reflection/generation on annotations to generate the composite mixin.
Or change the underlying mixin map behavior to aggregate list of mixin per class (but I don't have the background to know if it would be right way).
But maybe I'm in the wrong direction and there's a totally different way (more at the annotation capability level).
Yes, current assumption is that there is just one mix-in per target class.
This could be changed with more work. But I am not sure if this is the optimal path to take all things considered.
I was about to suggest sub-classing, but since annotations just mask each other, and not add,
it would not help.
I think better approach will be to add a specific non-annotation based method for declaring sub-classes; and possibly even helper classes for
automatic discover (like jersey and other packages have: give a package name, and they go
and find all classes in that package; this is heuristic based on class loader, files etc,
but seems to work).
I think there is already an issue for this... yes, JACKSON-257.
Just a reminder of the type identified by Fabrice Delhoste is still in 1.5.6
ObjectMapper.setDefaltTyping ==> ObjectMapper.setDefa*u*ltTyping
Holy guacamoley. I totally missed that one... thanks.
Also, with respect to ability to register subtypes; JACKSON-257 was implemented for Jackson 1.6, so it is now possible to register subtypes without annotations.
One quick comment: one specific set of classes for which this is sorely needed are exceptions (Throwable and subtypes). For example,
JACKSON-95can only be partially resolved without resolving this issue. Put another way, adding class info will help a lot with exception deserialization.