diff --git a/spring-oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java b/spring-oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java index df1100e471cf..596b587fa292 100644 --- a/spring-oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java +++ b/spring-oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -113,6 +113,7 @@ * @author Peter Meijer * @author Arjen Poutsma * @author Juergen Hoeller + * @author Sam Brannen * @since 3.0 */ public class XStreamMarshaller extends AbstractMarshaller implements BeanClassLoaderAware, InitializingBean { @@ -187,7 +188,7 @@ public class XStreamMarshaller extends AbstractMarshaller implements BeanClassLo private ClassLoader beanClassLoader = new CompositeClassLoader(); @Nullable - private XStream xstream; + private volatile XStream xstream; /** @@ -616,12 +617,21 @@ protected void customizeXStream(XStream xstream) { *
NOTE: This method has been marked as final as of Spring 4.0. * It can be used to access the fully configured XStream for marshalling * but not configuration purposes anymore. + *
As of Spring Framework 5.2.7, creation of the {@link XStream} instance
+ * returned by this method is thread safe.
*/
public final XStream getXStream() {
- if (this.xstream == null) {
- this.xstream = buildXStream();
+ XStream xs = this.xstream;
+ if (xs == null) {
+ synchronized (this) {
+ xs = this.xstream;
+ if (xs == null) {
+ xs = buildXStream();
+ this.xstream = xs;
+ }
+ }
}
- return this.xstream;
+ return xs;
}
diff --git a/spring-oxm/src/test/java/org/springframework/oxm/xstream/XStreamMarshallerTests.java b/spring-oxm/src/test/java/org/springframework/oxm/xstream/XStreamMarshallerTests.java
index 3d427fcd5f8e..5f05936d751a 100644
--- a/spring-oxm/src/test/java/org/springframework/oxm/xstream/XStreamMarshallerTests.java
+++ b/spring-oxm/src/test/java/org/springframework/oxm/xstream/XStreamMarshallerTests.java
@@ -21,10 +21,10 @@
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
-import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import java.util.stream.IntStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
@@ -185,13 +185,23 @@ void marshalStaxResultXMLEventWriter() throws Exception {
@Test
void converters() throws Exception {
marshaller.setConverters(new EncodedByteArrayConverter());
- byte[] buf = new byte[]{0x1, 0x2};
- Writer writer = new StringWriter();
- marshaller.marshal(buf, new StreamResult(writer));
- assertThat(XmlContent.from(writer)).isSimilarTo("