users@jaxb.java.net

JAXB 1.0.4, subtypes within other types

From: Ben Adida <ben_at_mit.edu>
Date: Tue, 5 Jul 2005 14:15:20 -0400

Hi all,

It seems that a Null Pointer Exception is thrown when trying to marshal
an object that contains a subtyped element that was set to an actual
element instance, rather than a complex type instance.

I have a complex type StuffType, which contains an element "payload"
that is of a base abstract type BaseType. I also have a complex type
ExtensionType which extends BaseType.

I also declare top-level elements Stuff of type StuffType and Extension
of type ExtensionType.

If I create a JAXB object Extension, and a JAXB object Stuff, inside
which I "stuff" the Extension object with .setPayload(), I get a
NullPointerException upon marshalling the Stuff object. If I use an
ExtensionType object instead of an Extension object (an instance of the
complex type instead of an instance of the element), everything is
fine.

I think I see why I should use an instance of the complex type rather
than the element itself, though it seems to me that a
NullPointerException is not the right message.

Thoughts?

-Ben

================================
Java Code:

        public static void main(String[] args) throws JAXBException {
                
                anytest.ObjectFactory factory = new anytest.ObjectFactory();
                Marshaller marshaller = factory.createMarshaller();
                Unmarshaller unmarshaller = factory.createUnmarshaller();

                Stuff stuff = factory.createStuff();
                
                // create an extension element
                Extension extension = factory.createExtension();
                extension.setFoo(BigInteger.ONE);
                extension.setBar(BigInteger.ONE);

                // create an instance of the extension complex type
                ExtensionType extension_type = factory.createExtensionType();
                extension_type.setFoo(BigInteger.ONE);
                extension_type.setBar(BigInteger.ONE);

                // marshal the stuff object containing extension type: this works
                stuff.setPayload(extension_type);
                marshaller.marshal(stuff, System.out);
                
                // marshal the stuff object containing the extension element: this
throws a NullPointer
                stuff.setPayload(extension);
                marshaller.marshal(stuff, System.out);
                
        }
===================================
XSD:

     <complexType name="StuffType" abstract="false">
         <sequence>
             <element name="payload" type="test:BaseType" />
         </sequence>
     </complexType>

     <complexType name="BaseType" abstract="true">
         <sequence>
             <element name="foo" type="integer" />
         </sequence>
     </complexType>

     <complexType name="ExtensionType" abstract="false">
         <complexContent>
             <extension base="test:BaseType">
                 <sequence>
                     <element name="bar" type="integer" />
                 </sequence>
             </extension>
         </complexContent>
     </complexType>