I have some objects marshalling to XML properly, but when unmarshalling the wrong setter gets called... and I can't figure out why.
I'm using JAXB to marshal/unmarshal with some small POJOs and some interfaces. I've already seen advice on dealing with interfaces, and I've needed to strategically use XmlAnyElement.
I'd share the whole project for you to play with, but I don't know how CodeRanch dudes normally do that.
This is the main POJO, where JAXB is trying to give a FrequencyInterface to setActivity(ActivityInterface activity)
When I marshal a code-built "Worksheet" instance I get this nice result:
When Unmarshalling the above (the output JAXB just created!)...
Notice it creates the "DiggingActivity" and gives it to setActivity()... then creates "EveryDay" and tries to also give it to setActivity() !?!?
This is how my tester does JAXB marshal/unmarshal:
Thanks in advance!
Joined: Jan 11, 2014
It occurred to me after making the big setup and post last night.... what if I can only have one of these "wild card" properties?
There can be only one XmlAnyElement annotated JavaBean property in a class and its super classes.
I would think that JAXB would look at the setters, and find one that it could typecast the argument into. There *could* be some ambiguity, but in my example "try type casting" would fix the problem, and prevent the unmarshalling from calling one setter over and over again. For that matter, why would a single unmarshal ever call the same setter twice (like it is in my example)?
While this is not surprising, it is inconvenient to my design abstraction, and there may be great workarounds.
I'm considering a last resort of something like this which puts an intermediary class in between... just so that intermediary will have only one XmlAnyElement.
This is a bit silly since there is only one Activity and one Frequency for the ScheduledActivity.
Any other clever ideas to explain, address or work around this?
I see there is a fine effort made in the op's posts: well-done and welcome!
The handling of interfaces and implementations in jaxb is somewhat delicate. (Even the documentation may/might contain inexactitude. But I won't push the observation too far. They may improve over time.)
To properly make the case of multiple interface each with its implementation(s) using the approach with "strategic" XmlAnyElement annotation as you posted in the first post, you have to put an additional annotation XmlElementRef side-by-side with the XmlAnyElement annotation. Concretely, like this.
The "strategic" XmlAnyElement (which is arguably actually more "strategic" XmlRootElement) is not the only approach. But for this it should do.