Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

org.w3c.dom.Node.insertBefore: NullPointerException, Bug?

The description of org.w3c.dom.Node.insertBefore of the Android-SDK say the following:

public abstract Node insertBefore (Node newChild, Node refChild)
Inserts the node newChild before the existing child node refChild. If refChild is null, insert newChild at the end of the list of children.

But if I do the following I get NullPointerException that occurs in the insertBefore implementation:

if(doc != null && doc.getFirstChild() != null && tmpNode != null)
    doc.getFirstChild().insertBefore(tmpNode, null);

WARN/System.err(11029): at org.apache.harmony.xml.dom.InnerNodeImpl.insertBefore(InnerNodeImpl.java:86)

I tried this with Android 2.2 and Android 2.3.3!
For me it seems to be a bug. Can anybody confirm/reproduce that?


//edit (18.01.2012 13:05):
I created a new java-project, because I wanted to see if this works in a java application:

public static void main(String[] args) {
    DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
    DocumentBuilder docBuilder;

        try {
            docBuilder = dbfac.newDocumentBuilder();
            Document d = docBuilder.newDocument();

            if(d != null){
                d.appendChild(d.createElement("root"));
                if(d.getFirstChild() != null){
                    d.getFirstChild().insertBefore(d.createElement("foo"), null);
                    System.out.println(d.getFirstChild().getFirstChild().getNodeName());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

This code works perfectly.

I also created a new android project to test this again:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
    DocumentBuilder docBuilder;

    try {
        docBuilder = dbfac.newDocumentBuilder();
        Document d = docBuilder.newDocument();

        if(d != null){
            d.appendChild(d.createElement("root"));
            if(d.getFirstChild() != null){
                d.getFirstChild().insertBefore(d.createElement("foo"), null);
                System.out.println(d.getFirstChild().getFirstChild().getNodeName());
            }
        }
    } catch (Exception e2) {
        e2.printStackTrace();
    }
}

When the application reaches the insertBefore, the Exception shown above is thrown.

So the same code works in normal Java, but not in Android. For me it still seems that it is a bug in the apache harmony implementation of org.w3c.dom. Any other ideas?

like image 267
Marc Avatar asked Jan 17 '12 10:01

Marc


1 Answers

It can be reproduced even with 4.1.2 Implementation for insertBefore from org.apache.harmony.xml.dom is

public Node insertBefore(Node newChild, Node refChild) throws DOMException {
    LeafNodeImpl refChildImpl = (LeafNodeImpl) refChild;

    if (refChildImpl.document != document) {
        throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, null);
    }

    if (refChildImpl.parent != this) {
        throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null);
    }

    return insertChildAt(newChild, refChildImpl.index);
}

As you can see no one checks if refChildImpl is null so refChildImpl.document!=document throws NullPointerException This implementation does not make any sense if following is correct

The description of org.w3c.dom.Node.insertBefore of the Android-SDK says the following:

public abstract Node insertBefore (Node newChild, Node refChild)

Inserts the node newChild before the existing child node refChild. If refChild is null, insert newChild at the end of the list of children.

like image 83
ljupce Avatar answered Sep 21 '22 12:09

ljupce