Add some test cases for CXF-6764 and log a message if the mapper fails
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/24311ae6 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/24311ae6 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/24311ae6 Branch: refs/heads/3.1.x-fixes Commit: 24311ae6d88b2359f61b4def6a6308a90378c596 Parents: df39a9e Author: Daniel Kulp <[email protected]> Authored: Thu Jan 28 15:17:11 2016 -0500 Committer: Daniel Kulp <[email protected]> Committed: Tue Feb 2 12:08:47 2016 -0500 ---------------------------------------------------------------------- .../org/apache/cxf/common/jaxb/JAXBUtils.java | 31 ++++--- .../apache/cxf/jaxb/JAXBDataBindingTest.java | 91 +++++++++++++++++--- 2 files changed, 97 insertions(+), 25 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/24311ae6/core/src/main/java/org/apache/cxf/common/jaxb/JAXBUtils.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/cxf/common/jaxb/JAXBUtils.java b/core/src/main/java/org/apache/cxf/common/jaxb/JAXBUtils.java index 6440c37..f8a21d0 100644 --- a/core/src/main/java/org/apache/cxf/common/jaxb/JAXBUtils.java +++ b/core/src/main/java/org/apache/cxf/common/jaxb/JAXBUtils.java @@ -74,6 +74,7 @@ import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; import org.apache.cxf.common.classloader.ClassLoaderUtils; +import org.apache.cxf.common.logging.LogUtils; import org.apache.cxf.common.util.ASMHelper; import org.apache.cxf.common.util.ASMHelper.ClassWriter; import org.apache.cxf.common.util.ASMHelper.FieldVisitor; @@ -91,6 +92,7 @@ import org.apache.cxf.common.xmlschema.SchemaCollection; import org.apache.cxf.helpers.JavaUtils; public final class JAXBUtils { + public static final Logger LOG = LogUtils.getL7dLogger(JAXBUtils.class); public enum IdentifierType { CLASS, @@ -623,15 +625,17 @@ public final class JAXBUtils { public static Object setNamespaceMapper(final Map<String, String> nspref, Marshaller marshaller) throws PropertyException { Object mapper = createNamespaceWrapper(marshaller.getClass(), nspref); - if (marshaller.getClass().getName().contains(".internal.")) { - marshaller.setProperty("com.sun.xml.internal.bind.namespacePrefixMapper", - mapper); - } else if (marshaller.getClass().getName().contains("com.sun")) { - marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", - mapper); - } else if (marshaller.getClass().getName().contains("eclipse")) { - marshaller.setProperty("eclipselink.namespace-prefix-mapper", - mapper); + if (mapper != null) { + if (marshaller.getClass().getName().contains(".internal.")) { + marshaller.setProperty("com.sun.xml.internal.bind.namespacePrefixMapper", + mapper); + } else if (marshaller.getClass().getName().contains("com.sun")) { + marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", + mapper); + } else if (marshaller.getClass().getName().contains("eclipse")) { + marshaller.setProperty("eclipselink.namespace-prefix-mapper", + mapper); + } } return mapper; } @@ -1084,6 +1088,7 @@ public final class JAXBUtils { String className = "org.apache.cxf.jaxb.NamespaceMapper"; className += postFix; Class<?> cls = helper.findClass(className, JAXBUtils.class); + Throwable t = null; if (cls == null) { try { ClassWriter cw = helper.createClassWriter(); @@ -1092,15 +1097,17 @@ public final class JAXBUtils { } } catch (RuntimeException ex) { // continue + t = ex; } } if (cls == null - && (mcls.getName().contains(".internal.") || mcls.getName().contains("com.sun"))) { + && (!mcls.getName().contains(".internal.") && mcls.getName().contains("com.sun"))) { try { cls = ClassLoaderUtils.loadClass("org.apache.cxf.common.jaxb.NamespaceMapper", JAXBUtils.class); - } catch (ClassNotFoundException ex2) { + } catch (Throwable ex2) { // ignore + t = ex2; } } if (cls != null) { @@ -1108,8 +1115,10 @@ public final class JAXBUtils { return cls.getConstructor(Map.class).newInstance(map); } catch (Exception e) { // ignore + t = e; } } + LOG.log(Level.INFO, "Could not create a NamespaceMapper compatible with Marshaller class " + mcls.getName(), t); return null; } /* http://git-wip-us.apache.org/repos/asf/cxf/blob/24311ae6/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBDataBindingTest.java ---------------------------------------------------------------------- diff --git a/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBDataBindingTest.java b/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBDataBindingTest.java index 4621481..980f2de 100644 --- a/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBDataBindingTest.java +++ b/rt/databinding/jaxb/src/test/java/org/apache/cxf/jaxb/JAXBDataBindingTest.java @@ -38,6 +38,7 @@ import javax.wsdl.Definition; import javax.wsdl.Service; import javax.wsdl.factory.WSDLFactory; import javax.wsdl.xml.WSDLReader; +import javax.xml.bind.JAXBContext; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.adapters.XmlAdapter; @@ -54,6 +55,8 @@ import org.w3c.dom.Node; import org.apache.cxf.Bus; import org.apache.cxf.binding.BindingFactoryManager; import org.apache.cxf.common.logging.LogUtils; +import org.apache.cxf.common.util.ASMHelper; +import org.apache.cxf.common.util.ReflectionUtil; import org.apache.cxf.databinding.DataReader; import org.apache.cxf.databinding.DataWriter; import org.apache.cxf.helpers.CastUtils; @@ -205,32 +208,92 @@ public class JAXBDataBindingTest extends Assert { assertTrue(xml, xml.contains("uri:ultima:thule")); } - @Test - public void testDeclaredNamespaceMapping() throws Exception { + JAXBDataBinding createJaxbContext(boolean internal) throws Exception { JAXBDataBinding db = new JAXBDataBinding(); Map<String, String> nsMap = new HashMap<String, String>(); nsMap.put("uri:ultima:thule", "greenland"); db.setNamespaceMap(nsMap); Map<String, Object> contextProperties = new HashMap<String, Object>(); - //contextProperties.put("com.sun.xml.bind.defaultNamespaceRemap", "uri:ultima:thule"); db.setContextProperties(contextProperties); Set<Class<?>> classes = new HashSet<Class<?>>(); classes.add(QualifiedBean.class); - db.setContext(db.createJAXBContext(classes)); - DataWriter<XMLStreamWriter> writer = db.createWriter(XMLStreamWriter.class); - XMLOutputFactory writerFactory = XMLOutputFactory.newInstance(); - StringWriter stringWriter = new StringWriter(); - XMLStreamWriter xmlWriter = writerFactory.createXMLStreamWriter(stringWriter); - QualifiedBean bean = new QualifiedBean(); - bean.setAriadne("spider"); - writer.write(bean, xmlWriter); - xmlWriter.flush(); - String xml = stringWriter.toString(); - assertTrue(xml, xml.contains("greenland=\"uri:ultima:thule")); + + //have to fastboot to avoid conflicts of generated accessors + System.setProperty("com.sun.xml.bind.v2.runtime.JAXBContextImpl.fastBoot", "true"); + System.setProperty("com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.fastBoot", "true"); + if (internal) { + System.setProperty(JAXBContext.JAXB_CONTEXT_FACTORY, "com.sun.xml.internal.bind.v2.ContextFactory"); + db.setContext(db.createJAXBContext(classes)); + System.clearProperty(JAXBContext.JAXB_CONTEXT_FACTORY); + } else { + db.setContext(db.createJAXBContext(classes)); + } + System.clearProperty("com.sun.xml.bind.v2.runtime.JAXBContextImpl.fastBoot"); + System.clearProperty("com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.fastBoot"); + return db; } + void doNamespaceMappingTest(boolean internal, boolean asm) throws Exception { + if (internal) { + try { + Class.forName("com.sun.xml.internal.bind.v2.ContextFactory"); + } catch (Throwable t) { + //on a JVM (likely IBM's) that doesn't rename the ContextFactory package to include "internal" + return; + } + } + try { + if (!asm) { + ReflectionUtil.setAccessible(ReflectionUtil.getDeclaredField(ASMHelper.class, "badASM")) + .set(null, Boolean.TRUE); + } + + JAXBDataBinding db = createJaxbContext(internal); + + DataWriter<XMLStreamWriter> writer = db.createWriter(XMLStreamWriter.class); + XMLOutputFactory writerFactory = XMLOutputFactory.newInstance(); + StringWriter stringWriter = new StringWriter(); + XMLStreamWriter xmlWriter = writerFactory.createXMLStreamWriter(stringWriter); + QualifiedBean bean = new QualifiedBean(); + bean.setAriadne("spider"); + writer.write(bean, xmlWriter); + xmlWriter.flush(); + String xml = stringWriter.toString(); + assertTrue("Failed to map namespace " + xml, xml.contains("greenland=\"uri:ultima:thule")); + } finally { + if (!asm) { + ReflectionUtil.setAccessible(ReflectionUtil.getDeclaredField(ASMHelper.class, "badASM")) + .set(null, Boolean.FALSE); + } + } + } + + @Test + public void testDeclaredNamespaceMappingRI() throws Exception { + doNamespaceMappingTest(false, true); + } @Test + public void testDeclaredNamespaceMappingInternal() throws Exception { + doNamespaceMappingTest(true, true); + } + @Test + public void testDeclaredNamespaceMappingRINoAsm() throws Exception { + doNamespaceMappingTest(false, false); + } + + @Test + public void testDeclaredNamespaceMappingInternalNoAsm() throws Exception { + try { + doNamespaceMappingTest(true, false); + fail("Internal needs ASM"); + } catch (AssertionError er) { + er.getMessage().contains("Failed to map namespace"); + } + } + + + @Test public void testResursiveType() throws Exception { Set<Class<?>> classes = new HashSet<Class<?>>(); Collection<Object> typeReferences = new ArrayList<Object>();
