Skip to main content

@XmlElementWrapper, unmarshalling, and NullPointerException

4 replies [Last post]
derecho80
Offline
Joined: 2007-04-25
Points: 0

I am getting a NullPointerException from unmarshalling XML that was generated by JAXB 2.0.
This only occurs when I use the @XmlElementWrapper annotation. If I remove it, all
is well (except I do not get the XML I really want). Has anyone else seen this behavior
during unmarshalling?

Here is the JUnit code I am using to drive the test:

------------------
import java.io.StringReader;
import java.io.StringWriter;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

import junit.framework.TestCase;

public class ConceptDefinitionMarshallTest extends TestCase {

public void testMarshallUnMarshall() throws Exception {
JAXBContext cdContext = JAXBContext.newInstance(ConceptDefinition.class);
Marshaller m = cdContext.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
StringWriter strw = new StringWriter();
m.marshal(createDef(), strw ) ;

System.err.println(strw.getBuffer());
StringReader strr = new StringReader(strw.getBuffer().toString());
Object obj = cdContext.createUnmarshaller().unmarshal(strr);
assertEquals( ConceptDefinition.class , obj.getClass());

ConceptDefinition cd = (ConceptDefinition)obj;
assertEquals(3, cd.getFields().size());
assertEquals(TextFieldDefinition.class, cd.getFields().get(0).getClass());
assertEquals(TextFieldDefinition.class, cd.getFields().get(1).getClass());
assertEquals(IntegerFieldDefinition.class, cd.getFields().get(2).getClass());

}

private ConceptDefinition createDef() {
ConceptDefinition cd = new ConceptDefinition();
cd.setId("123");
cd.setName("NAME");

TextFieldDefinition text = new TextFieldDefinition();
text.setName("TEXT PARAMETER 1");
text.setMaxLength(10);
cd.getFields().add(text);
text = new TextFieldDefinition();
text.setName("TEXT PARAMETER 2");
text.setMaxLength(10);
cd.getFields().add(text);

IntegerFieldDefinition integer = new IntegerFieldDefinition();
integer.setName( "INT PARAMETER 1");
integer.setMinValue(1000);

integer.setMaxDigits(2000);
cd.getFields().add(integer);

return cd;
}
}
-----------------------

This is the ConceptDefinition class:

-------------------------

import java.util.LinkedList;
import java.util.List;

import javax.xml.bind.annotation.AccessType;
import javax.xml.bind.annotation.AccessorOrder;
import javax.xml.bind.annotation.XmlAccessorOrder;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlElementRefs;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
@XmlAccessorType(value = AccessType.FIELD)
@XmlAccessorOrder(value = AccessorOrder.ALPHABETICAL)
public class ConceptDefinition {

private String id;

private String name;

@XmlElementWrapper
@XmlElementRefs( { @XmlElementRef(type = TextFieldDefinition.class),
@XmlElementRef(type = IntegerFieldDefinition.class),
@XmlElementRef(type = DateTimeFieldDefinition.class),
@XmlElementRef(type = FieldGroupDefinition.class),
@XmlElementRef(type = BoolFieldDefinition.class), @XmlElementRef() })
private List fields = new LinkedList();

public List getFields() {
return fields;
}

public void setFields(List fields) {
this.fields = fields;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

This is the failure trace:
java.lang.NullPointerException
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:54)
at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36)
at java.lang.reflect.Field.get(Field.java:385)
at com.sun.xml.bind.v2.runtime.reflect.Accessor$FieldReflection.get(Accessor.java:185)
at com.sun.xml.bind.v2.runtime.reflect.Lister$CollectionLister.startPacking(Lister.java:249)
at com.sun.xml.bind.v2.runtime.reflect.Lister$CollectionLister.startPacking(Lister.java:224)
at com.sun.xml.bind.v2.runtime.unmarshaller.Scope.add(Scope.java:78)
at com.sun.xml.bind.v2.runtime.property.ArrayERProperty$ReceiverImpl.receive(ArrayERProperty.java:150)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.endElement(UnmarshallingContext.java:404)
at com.sun.xml.bind.v2.runtime.unmarshaller.SAXConnector.endElement(SAXConnector.java:125)
at org.apache.xerces.parsers.AbstractSAXParser.endElement(Unknown Source)
at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanEndElement(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:200)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:173)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:137)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:194)
at com.siemens.soarian.se.cr.business.definition.ConceptDefinitionMarshallTest.testMarshallUnMarshall(ConceptDefinitionMarshallTest.java:22)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:615)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:128)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)

This is the XML that is created correctly and attempted to be unmarshalled:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

false
TEXT PARAMETER 1
false
0
10

false
TEXT PARAMETER 2
false
0
10

false
INT PARAMETER 1
false
0
2000
1000

123
NAME

If I remove the @XmlElementWrapper annotation, I get this XML and the failure does not occur:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

false
TEXT PARAMETER 1
false
0
10

false
TEXT PARAMETER 2
false
0
10

false
INT PARAMETER 1
false
0
2000
1000

123
NAME

Thanks (sorry for the long post)

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
kohsuke
Offline
Joined: 2003-06-09
Points: 0

I remember this bug. Can you upgrade to a newer version of the JAXB RI?

derecho80
Offline
Joined: 2007-04-25
Points: 0

Thank you for the reply. I will check into the version.

derecho80
Offline
Joined: 2007-04-25
Points: 0

The formatting of the code and the XML in this post is not easy to read. Is there some technique that I should use to get it in a more readable format? Perhaps that is why there have not been any replies?

Thanks.

kohsuke
Offline
Joined: 2003-06-09
Points: 0

Try wrapping them with [ c o d e ] and [ / c o d e ] (without space).