반응형

Development environment: Oracle Java 1.7


This post shows a case when the "createTextNode" method with the null parameter causes "javax.xml.transform.TransformerException: java.lang.NullPointerException" without detailed information (difficult to find the exact line of code causing NullPointerException).


Using DocumentBuilderFactory and TransformerFactory, users can create an XML document with user-defined tags. Usually, I convert a user-defined object into the XMlL representation in String using DocumentBuilderFactory and TransformerFactory. Below is a simple example which causes a NullPointerException:


/* Person.java */

public class Person {

String name;

String phone;


public Person(){ }


public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getPhone() {

return phone;

}

public void setPhone(String phone) {

this.phone = phone;

}

}


/* TestMain.java */

public class TestMain {

public static void main(String[] args){

Person person = new Person();

// person.setName("Smith"); // commented for making NullPointerException

person.setPhone("01011112222");


try {

DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();

DocumentBuilder docBuilder = dbfac.newDocumentBuilder();

Document doc = docBuilder.newDocument();

// root (person) tag

Element ePerson = doc.createElement("person");

doc.appendChild(ePerson);

// name tag

Element eName = doc.createElement("name");

ePerson.appendChild(eName);

Text nameText = doc.createTextNode(person.getName());

eName.appendChild(nameText);

// phone tag

Element ePhone = doc.createElement("phone");

ePerson.appendChild(ePhone);

Text phoneText = doc.createTextNode(person.getPhone());

ePhone.appendChild(phoneText);

//set up a transformer

TransformerFactory transfac = TransformerFactory.newInstance();

Transformer trans = transfac.newTransformer();

trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");

trans.setOutputProperty(OutputKeys.INDENT, "yes");

//create string from xml tree

StringWriter sw = new StringWriter();

StreamResult result = new StreamResult(sw);

DOMSource source = new DOMSource(doc);

trans.transform(source, result); // the line where the Exception indicates

// print the XML output

System.out.println(sw.toString());

} catch (Exception e) {

e.printStackTrace();

}

}

}


As the TestMain.java shows, if the member variable "name" in the Person class is not set, it generates an exception like below:

ERROR:  ''

javax.xml.transform.TransformerException: java.lang.NullPointerException

at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(Unknown Source)

at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(Unknown Source)

at org.usera.xml.TestMain.main(TestMain.java:39)

Caused by: java.lang.NullPointerException

at com.sun.org.apache.xml.internal.serializer.ToUnknownStream.characters(Unknown Source)

at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(Unknown Source)

at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(Unknown Source)

at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(Unknown Source)

at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(Unknown Source)

at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(Unknown Source)

at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transformIdentity(Unknown Source)

... 3 more

---------

java.lang.NullPointerException

at com.sun.org.apache.xml.internal.serializer.ToUnknownStream.characters(Unknown Source)

at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(Unknown Source)

at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(Unknown Source)

at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(Unknown Source)

at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(Unknown Source)

at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(Unknown Source)

at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transformIdentity(Unknown Source)

at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(Unknown Source)

at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(Unknown Source)

at org.usera.xml.TestMain.main(TestMain.java:39)


The exception guides me to "trans.transform(source, result)", but it doesn't seem to contain any null parameter. This means the other parts in the XML document object contains null values.

In this example, we can quickly find that the member variable "name" should be initialized with a valid String because it is a very simplified code. However, if I handle complex  objects including tens of member variables, it is not easy to find which variables are set to null.


Thus, I tried to make a wrapping method which make the "createTextNode" always get a "not null" parameter. The simple solution might be like below:

public static Text createTextNodeWithoutNull(Document doc, String str)

{

Text textNode;

if(str != null) textNode = doc.createTextNode(str);

else textNode = doc.createTextNode("null");

return textNode;

}


Then the modified code (a part of TestMain) is:

// name tag

Element eName = doc.createElement("name");

ePerson.appendChild(eName);

Text nameText = createTextNodeWithoutNull (doc, person.getName());

eName.appendChild(nameText);

// phone tag

Element ePhone = doc.createElement("phone");

ePerson.appendChild(ePhone);

Text phoneText = createTextNodeWithoutNull (doc, person.getPhone());

ePhone.appendChild(phoneText);


Likewise, the XML Document object won't contain any null values inside.



반응형
블로그 이미지

Bryan_

,