Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.Sign up
JAXB marshalling with 'any' elements [SWS-751] #839
This can also be an improvement, but different from what the user expects as Jaxb2Marshaller is correctly configured.
// B is any
If I create an object A with A.any=B, AbstractJaxb2PayloadMethodProcessor.getJaxbContext creates a JAXBContext which only sees A, and not B, so marshalling fails.
Arjen Poutsma commented
I am not sure if there are better ways to configure the Jaxb2Marshaller for this scenario.
At any rate, I can't reproduce this issue with the following code:
<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller"> <property name="classesToBeBound"> <list> <value>jaxb.schema.A</value> <value>jaxb.schema.B</value> </list> </property> </bean>
the above prints out:
which I think is correct.
Dan Luputan commented
As I said (maybe not that clear), the issue is with AbstractJaxb2PayloadMethodProcessor.getJaxbContext, not using Jaxb2Marshaller directly which obviously works.
The issue here is how to populate the JAXBContext. With 'any' elements, the possible candidates are lost since this is how JAXB works. But Jaxb2Marshaller already has all the candidates configured. getJaxbContext does JAXBContext.newInstance(clazz), where I would need the 'any' candidates included. So I asked for a solution to that.
Arjen Poutsma commented
I see now; sorry for the misunderstanding earlier.
I don't think there is a better way of using the AbstractJaxb2PayloadMethodProcessor in this particular scenario. The underlying reason is that this processor detects the JAXBContext for a given class automatically, and since A does not have a reference to B (except with the
You can, however, use the MarshallingPayloadMethodProcessor instead of the JAXB2 one. The way to make this work is to configure a Jaxb2Marshaller from the Spring OXM module with the classesToBeBound property (as shown in the snippet above), and plug that into the MarshallingPayloadMethodProcessor. This way, JAXB2 is explicitly configured for a particular set of classes (A & B) and will only work for those classes.
To answer your final question: we cache the JAXB2Contexts in a map because they are quite expensive to create. Check the getJaxbContext() method to see more.
Hope this helps.