Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 333697

Summary: JAXB: Null pointer when marshalling via context bootstrapped from TypeMappingInfo[]
Product: z_Archived Reporter: David McCann <david.mccann>
Component: EclipselinkAssignee: David McCann <david.mccann>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P3    
Version: unspecified   
Target Milestone: ---   
Hardware: PC   
OS: Windows XP   
Whiteboard:
Attachments:
Description Flags
Proposed fix.
none
Modified test cases.
none
Proposed fix v2
none
Supporting tests none

Description David McCann CLA 2011-01-06 16:07:06 EST
When a JAXBContext is bootstrapped from a TypeMappingInfo[], one of three marshal methods on our JAXBMarshaller should be used to marshal:

- marshal(Object object, Result result, TypeMappingInfo type)
- marshal(Object object, XMLEventWriter eventWriter, TypeMappingInfo type)
- marshal(Object object, XMLStreamWriter streamWriter, TypeMappingInfo type)

If one of these is not used, and EclipseLink encounters something it can't marshal as-is, such as Float[], the following exception will be thrown:

-----
Exception in thread "main" java.lang.NullPointerException
	at org.eclipse.persistence.jaxb.JAXBMarshaller.createXMLRootFromJAXBElement(JAXBMarshaller.java:150)
	at org.eclipse.persistence.jaxb.JAXBMarshaller.marshal(JAXBMarshaller.java:309)
	at testing.XmlListTest.main(XmlListTest.java:44)
-----

This null pointer exception should bot be thrown;  we should handle this scenario using a JAXBException with a helpful message.

The following test case can be used to reproduce the exception:

-----
public class XmlListTest {
  public static Float[] f = new Float[] { 3.14f };

  public static void main(String[] args) throws Exception {
    TypeMappingInfo ti = new TypeMappingInfo();
    ti.setXmlTagName(new QName("FooFloatListType"));
    ti.setType(Float[].class);
    ti.setElementScope(ElementScope.Global);

    JAXBContext ctx = JAXBContextFactory.createContext(
        new TypeMappingInfo[] { ti }, 
        new HashMap<Object, Object>(),
        Thread.currentThread().getContextClassLoader());
		
    JAXBElement<Float[]> elt = new JAXBElement<Float[]>(
        ti.getXmlTagName(), Float[].class, f);

    Marshaller m = ctx.createMarshaller();
    m.marshal(elt, System.out);
  }
}
-----
Comment 1 David McCann CLA 2011-01-07 14:46:50 EST
Created attachment 186306 [details]
Proposed fix.
Comment 2 David McCann CLA 2011-01-07 14:47:04 EST
Created attachment 186307 [details]
Modified test cases.
Comment 3 David McCann CLA 2011-01-07 15:03:55 EST
Reviewed by:  matt.macivor@oracle.com
Tests:  all unit tests pass as expected
Revision: 8788
Comment 4 David McCann CLA 2011-01-11 14:28:53 EST
Created attachment 186548 [details]
Proposed fix v2

It turns out that we can't switch from throwing MarshalException to JAXBException w/o causing test failures.  Instead, we will add the to the standard EclipseLink 'Descriptor not found' XMLMarshaller exception message.
Comment 5 David McCann CLA 2011-01-11 14:29:16 EST
Created attachment 186549 [details]
Supporting tests
Comment 6 David McCann CLA 2011-01-11 15:01:28 EST
Fix part #2 checked in.  Changing the exception from MarshalException to a JAXBException wrapping a MarshalException caused test failures.  Instead we will modify the standard 'Descriptor not found exception' message to indicate that if JAXB, and the JAXBContext was bootstrapped from TypeMappingInfo[], special marshal methods should be used to avoid this exception.
Reviewed by:  blaise.doughan@oracle.com
Revision: 8800
Comment 7 Eclipse Webmaster CLA 2022-06-09 10:10:12 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink