Skip to content

Commit ad10301

Browse files
committed
AbstractMarshaller defensively uses DocumentBuilderFactory within synchronized block
Issue: SPR-13935 (cherry picked from commit 5047e90)
1 parent 512d126 commit ad10301

File tree

1 file changed

+28
-29
lines changed

1 file changed

+28
-29
lines changed

spring-oxm/src/main/java/org/springframework/oxm/support/AbstractMarshaller.java

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2015 the original author or authors.
2+
* Copyright 2002-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -41,6 +41,7 @@
4141

4242
import org.apache.commons.logging.Log;
4343
import org.apache.commons.logging.LogFactory;
44+
import org.w3c.dom.Document;
4445
import org.w3c.dom.Node;
4546
import org.xml.sax.ContentHandler;
4647
import org.xml.sax.EntityResolver;
@@ -121,6 +122,28 @@ public boolean isProcessExternalEntities() {
121122
}
122123

123124

125+
/**
126+
* Build a new {@link Document} from this marshaller's {@link DocumentBuilderFactory},
127+
* as a placeholder for a DOM node.
128+
* @see #createDocumentBuilderFactory()
129+
* @see #createDocumentBuilder(DocumentBuilderFactory)
130+
*/
131+
protected Document buildDocument() {
132+
try {
133+
DocumentBuilder documentBuilder;
134+
synchronized (this.documentBuilderFactoryMonitor) {
135+
if (this.documentBuilderFactory == null) {
136+
this.documentBuilderFactory = createDocumentBuilderFactory();
137+
}
138+
documentBuilder = createDocumentBuilder(this.documentBuilderFactory);
139+
}
140+
return documentBuilder.newDocument();
141+
}
142+
catch (ParserConfigurationException ex) {
143+
throw new UnmarshallingFailureException("Could not create document placeholder: " + ex.getMessage(), ex);
144+
}
145+
}
146+
124147
/**
125148
* Create a {@code DocumentBuilder} that this marshaller will use for creating
126149
* DOM documents when passed an empty {@code DOMSource}.
@@ -226,19 +249,7 @@ else if (result instanceof StreamResult) {
226249
*/
227250
protected void marshalDomResult(Object graph, DOMResult domResult) throws XmlMappingException {
228251
if (domResult.getNode() == null) {
229-
try {
230-
synchronized (this.documentBuilderFactoryMonitor) {
231-
if (this.documentBuilderFactory == null) {
232-
this.documentBuilderFactory = createDocumentBuilderFactory();
233-
}
234-
}
235-
DocumentBuilder documentBuilder = createDocumentBuilder(this.documentBuilderFactory);
236-
domResult.setNode(documentBuilder.newDocument());
237-
}
238-
catch (ParserConfigurationException ex) {
239-
throw new UnmarshallingFailureException(
240-
"Could not create document placeholder for DOMResult: " + ex.getMessage(), ex);
241-
}
252+
domResult.setNode(buildDocument());
242253
}
243254
marshalDomNode(graph, domResult.getNode());
244255
}
@@ -249,7 +260,7 @@ protected void marshalDomResult(Object graph, DOMResult domResult) throws XmlMap
249260
* {@code marshalXMLEventConsumer}, depending on what is contained in the
250261
* {@code StaxResult}.
251262
* @param graph the root of the object graph to marshal
252-
* @param staxResult a Spring {@link org.springframework.util.xml.StaxSource} or JAXP 1.4 {@link StAXSource}
263+
* @param staxResult a JAXP 1.4 {@link StAXSource}
253264
* @throws XmlMappingException if the given object cannot be marshalled to the result
254265
* @throws IllegalArgumentException if the {@code domResult} is empty
255266
* @see #marshalDomNode(Object, org.w3c.dom.Node)
@@ -358,19 +369,7 @@ else if (source instanceof StreamSource) {
358369
*/
359370
protected Object unmarshalDomSource(DOMSource domSource) throws XmlMappingException {
360371
if (domSource.getNode() == null) {
361-
try {
362-
synchronized (this.documentBuilderFactoryMonitor) {
363-
if (this.documentBuilderFactory == null) {
364-
this.documentBuilderFactory = createDocumentBuilderFactory();
365-
}
366-
}
367-
DocumentBuilder documentBuilder = createDocumentBuilder(this.documentBuilderFactory);
368-
domSource.setNode(documentBuilder.newDocument());
369-
}
370-
catch (ParserConfigurationException ex) {
371-
throw new UnmarshallingFailureException(
372-
"Could not create document placeholder for DOMSource: " + ex.getMessage(), ex);
373-
}
372+
domSource.setNode(buildDocument());
374373
}
375374
try {
376375
return unmarshalDomNode(domSource.getNode());
@@ -437,7 +436,7 @@ protected Object unmarshalSaxSource(SAXSource saxSource) throws XmlMappingExcept
437436
if (!isSupportDtd()) {
438437
throw new UnmarshallingFailureException("NPE while unmarshalling. " +
439438
"This can happen on JDK 1.6 due to the presence of DTD " +
440-
"declarations, which are disabled.", ex);
439+
"declarations, which are disabled.");
441440
}
442441
throw ex;
443442
}

0 commit comments

Comments
 (0)