I am using spring WebServiceTemplate as a web service client programmatically i.e. without instantiating a spring container. I am using Jaxb2Marshaller for marshaling/unmarshaling. In my application, I create a single instance of the SaajSoapMessageFactory and one instance of Jaxb2Marshaller. I also create a single instance of the WebServiceTemplate and assign the previously created instances of SaajSoapMessageFactory and Jaxb2Marshaller.
The WebServiceTemplate I created is used in a multi threaded way i.e. multiple threads can call marshalSendAndReceive at the same time. My question is - is my configuration thread safe? I am concerned about the Jaxb2Marshaller. The javadoc says Jaxb2Marshallers are not necessarily thread safe. How can I use the Jaxb2Marshaller in a thread safe way without reinitializing the Jaxb context?
As an aside: looking at the example spring-ws configuration in the spring reference leads me to believe that the Jaxb2Marshaller is thread safe but the Javadoc seems to contradict that.
The javadoc for Jaxb2Marshaller
makes no mention of thread-safety one way or another, so I'm not sure why you think it's not. If it wasn't thread-safe, the javadoc would say that very clearly.
Your configuration of WebServiceTemplate
, SaajSoapMessageFactory
and Jaxb2Marshaller
singletons is perfectly fine, and entirely thread-safe.
The class org.springframework.oxm.jaxb.Jaxb2Marshaller is thread safe, since it creates for every marshalling event new instance of javax.xml.bind.Marshaller, see the original source code from Spring 5.2.6:
@Override
public void marshal(Object graph, Result result, @Nullable MimeContainer mimeContainer) throws XmlMappingException {
try {
Marshaller marshaller = createMarshaller();
if (this.mtomEnabled && mimeContainer != null) {
marshaller.setAttachmentMarshaller(new Jaxb2AttachmentMarshaller(mimeContainer));
}
if (StaxUtils.isStaxResult(result)) {
marshalStaxResult(marshaller, graph, result);
}
else {
marshaller.marshal(graph, result);
}
}
catch (JAXBException ex) {
throw convertJaxbException(ex);
}
}
/**
* Return a newly created JAXB marshaller.
* <p>Note: JAXB marshallers are not necessarily thread-safe.
* This method is public as of 5.2.
* @since 5.2
* @see #createUnmarshaller()
*/
public Marshaller createMarshaller() {
try {
Marshaller marshaller = getJaxbContext().createMarshaller();
initJaxbMarshaller(marshaller);
return marshaller;
}
catch (JAXBException ex) {
throw convertJaxbException(ex);
}
}
Similar situation is by Unmarshaller.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With