diff --git a/spring-oxm/src/main/java/org/springframework/oxm/jaxb/ClassPathJaxb2TypeScanner.java b/spring-oxm/src/main/java/org/springframework/oxm/jaxb/ClassPathJaxb2TypeScanner.java
index 368655356b..f3047013a6 100644
--- a/spring-oxm/src/main/java/org/springframework/oxm/jaxb/ClassPathJaxb2TypeScanner.java
+++ b/spring-oxm/src/main/java/org/springframework/oxm/jaxb/ClassPathJaxb2TypeScanner.java
@@ -19,7 +19,9 @@ package org.springframework.oxm.jaxb;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+
import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlType;
@@ -42,6 +44,7 @@ import org.springframework.util.ClassUtils;
* @author Arjen Poutsma
* @author Juergen Hoeller
* @author David Harrigan
+ * @author Biju Kunjummen
* @since 3.1.1
* @see #scanPackages()
*/
@@ -50,8 +53,11 @@ class ClassPathJaxb2TypeScanner {
private static final String RESOURCE_PATTERN = "/**/*.class";
private static final TypeFilter[] JAXB2_TYPE_FILTERS = new TypeFilter[] {
- new AnnotationTypeFilter(XmlRootElement.class, false), new AnnotationTypeFilter(XmlType.class, false),
- new AnnotationTypeFilter(XmlSeeAlso.class, false), new AnnotationTypeFilter(XmlEnum.class, false)};
+ new AnnotationTypeFilter(XmlRootElement.class, false),
+ new AnnotationTypeFilter(XmlType.class, false),
+ new AnnotationTypeFilter(XmlSeeAlso.class, false),
+ new AnnotationTypeFilter(XmlEnum.class, false),
+ new AnnotationTypeFilter(XmlRegistry.class, false)};
private final ResourcePatternResolver resourcePatternResolver;
diff --git a/spring-oxm/src/test/java/org/springframework/oxm/jaxb/Airplane.java b/spring-oxm/src/test/java/org/springframework/oxm/jaxb/Airplane.java
new file mode 100644
index 0000000000..bc0060b0f4
--- /dev/null
+++ b/spring-oxm/src/test/java/org/springframework/oxm/jaxb/Airplane.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2002-2013 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.oxm.jaxb;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+public class Airplane {
+
+ private String name;
+
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+}
diff --git a/spring-oxm/src/test/java/org/springframework/oxm/jaxb/Jaxb2MarshallerTests.java b/spring-oxm/src/test/java/org/springframework/oxm/jaxb/Jaxb2MarshallerTests.java
index aa3eca0777..bd75b70adb 100644
--- a/spring-oxm/src/test/java/org/springframework/oxm/jaxb/Jaxb2MarshallerTests.java
+++ b/spring-oxm/src/test/java/org/springframework/oxm/jaxb/Jaxb2MarshallerTests.java
@@ -51,10 +51,15 @@ import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
-import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
+
import static org.junit.Assert.*;
+import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
import static org.mockito.BDDMockito.*;
+/**
+ * @author Arjen Poutsma
+ * @author Biju Kunjummen
+ */
public class Jaxb2MarshallerTests extends AbstractMarshallerTests {
private static final String CONTEXT_PATH = "org.springframework.oxm.jaxb.test";
@@ -281,6 +286,21 @@ public class Jaxb2MarshallerTests extends AbstractMarshallerTests {
verify(mimeContainer, times(3)).addAttachment(isA(String.class), isA(DataHandler.class));
}
+ @Test
+ public void marshalAWrappedObjectHoldingAnXmlElementDeclElement() throws Exception {
+ // SPR-10714
+ marshaller = new Jaxb2Marshaller();
+ marshaller.setPackagesToScan(new String[] { "org.springframework.oxm.jaxb" });
+ marshaller.afterPropertiesSet();
+ Airplane airplane = new Airplane();
+ airplane.setName("test");
+ StringWriter writer = new StringWriter();
+ Result result = new StreamResult(writer);
+ marshaller.marshal(airplane, result);
+ assertXMLEqual("Marshalling should use root Element",
+ writer.toString(), "test");
+ }
+
@XmlRootElement
@SuppressWarnings("unused")
public static class DummyRootElement {
diff --git a/spring-oxm/src/test/java/org/springframework/oxm/jaxb/Jaxb2UnmarshallerTests.java b/spring-oxm/src/test/java/org/springframework/oxm/jaxb/Jaxb2UnmarshallerTests.java
index 55a3f8d226..04842a7366 100644
--- a/spring-oxm/src/test/java/org/springframework/oxm/jaxb/Jaxb2UnmarshallerTests.java
+++ b/spring-oxm/src/test/java/org/springframework/oxm/jaxb/Jaxb2UnmarshallerTests.java
@@ -39,6 +39,10 @@ import org.springframework.util.xml.StaxUtils;
import static org.junit.Assert.*;
import static org.mockito.BDDMockito.*;
+/**
+ * @author Arjen Poutsma
+ * @author Biju Kunjummen
+ */
public class Jaxb2UnmarshallerTests extends AbstractUnmarshallerTests {
private static final String INPUT_STRING = "" +
@@ -104,6 +108,7 @@ public class Jaxb2UnmarshallerTests extends AbstractUnmarshallerTests {
@Test
@Override
+ @SuppressWarnings("unchecked")
public void unmarshalPartialStaxSourceXmlStreamReader() throws Exception {
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
XMLStreamReader streamReader = inputFactory.createXMLStreamReader(new StringReader(INPUT_STRING));
@@ -115,5 +120,18 @@ public class Jaxb2UnmarshallerTests extends AbstractUnmarshallerTests {
testFlight(flight);
}
+ @Test
+ @SuppressWarnings("unchecked")
+ public void unmarshalAnXmlReferingToAWrappedXmlElementDecl() throws Exception {
+ // SPR-10714
+ unmarshaller = new Jaxb2Marshaller();
+ unmarshaller.setPackagesToScan(new String[] { "org.springframework.oxm.jaxb" });
+ unmarshaller.afterPropertiesSet();
+ Source source = new StreamSource(new StringReader(
+ "test"));
+ JAXBElement airplane = (JAXBElement) unmarshaller.unmarshal(source);
+ assertEquals("Unmarshalling via explicit @XmlRegistry tag should return correct type",
+ "test", airplane.getValue().getName());
+ }
}
diff --git a/spring-oxm/src/test/java/org/springframework/oxm/jaxb/XmlRegObjectFactory.java b/spring-oxm/src/test/java/org/springframework/oxm/jaxb/XmlRegObjectFactory.java
new file mode 100644
index 0000000000..a3f6c702af
--- /dev/null
+++ b/spring-oxm/src/test/java/org/springframework/oxm/jaxb/XmlRegObjectFactory.java
@@ -0,0 +1,16 @@
+
+package org.springframework.oxm.jaxb;
+
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.annotation.XmlElementDecl;
+import javax.xml.bind.annotation.XmlRegistry;
+import javax.xml.namespace.QName;
+
+@XmlRegistry
+public class XmlRegObjectFactory {
+
+ @XmlElementDecl(name = "brand-airplane")
+ public JAXBElement createAirplane(Airplane airplane) {
+ return new JAXBElement(new QName("brand-airplane"), Airplane.class, null, airplane);
+ }
+}
\ No newline at end of file