JDK-6333993 : NodeList.item() returns null in 1.5.0_02
  • Type: Bug
  • Component: xml
  • Sub-Component: org.w3c.dom
  • Affected Version: 1.0
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2005-10-07
  • Updated: 2012-04-25
  • Resolved: 2009-12-10
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.4.0 h1189Fixed
Description
FULL PRODUCT VERSION :
does'nt work in JAVA 1.5.0_02. Works on java 1.4.2_04

ADDITIONAL OS VERSION INFORMATION :
Windows Xp and windows 2000

A DESCRIPTION OF THE PROBLEM :
<<<
               // Get first member of contextItem i.e. menuName
                item = (Element)contextItem.item(0); <<<< Returns null in JRE 1.5
               
                if (item.getNodeName().equals("separator"))
                {
                    m_contextActions[i] = new ContextAction();
                }
>>>


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Just run the code given in testcase section.Running  MXCSTestApp.java in java 1.5.0_XX fails. giving output..
When Run On Java 1.5.0_02

>>>MXCSTestApp()
<<<MXCSTestApp()
>>>MXCSTestApp.init()
m_XMLDocument.getDocumentElement();
root.getChildNodes();
root_elems.getLength();
This node has only one icon to display all of the time.MxCS/images/MXCS16.gif
Exception in parseTreeNode()java.lang.NullPointerException
java.lang.NullPointerException
	at MXCSTest.MXCSTestApp.parseGUI(MXCSTestApp.java:194)
	at MXCSTest.MXCSTestApp.parseTreeNode(MXCSTestApp.java:109)
	at MXCSTest.MXCSTestApp.init(MXCSTestApp.java:251)
	at MXCSTest.MXCSTestApp.main(MXCSTestApp.java:303)
<<<MXCSTestApp.init()
>>>MXCSTestApp.start()
<<<MXCSTestApp.start()
================================
When Run on Java 1.4.2_04
>>>MXCSTestApp()
<<<MXCSTestApp()
>>>MXCSTestApp.init()
m_XMLDocument.getDocumentElement();
root.getChildNodes();
root_elems.getLength();
This node has only one icon to display all of the time.MxCS/images/MXCS16.gif
A new ContextAction ServiceStart is added for the menu Item Start and is Enabled
A new ContextAction ServiceStop is added for the menu Item Stop... and is Disabled
parseGUI((Element)root_elems.item(0));
parseChildren((Element)root_elems.item(1));
<<<MXCSTestApp.init()
>>>MXCSTestApp.start()
<<<MXCSTestApp.start()
==================================
List of files.....
./MXCSTest
./MXCSTest/MXCSTestApp.java
./XMLTree
./XMLTree/service.xml
./XMLTree/XMLDocEntityResolver.java
./XMLTree/XMLTreeErrorHandler.java
./XMLTree/XML
./XMLTree/XML/node.dtd
./XMLTree/XML/nodeType.dtd

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
When Run on Java 1.4.2_04
>>>MXCSTestApp()
<<<MXCSTestApp()
>>>MXCSTestApp.init()
m_XMLDocument.getDocumentElement();
root.getChildNodes();
root_elems.getLength();
This node has only one icon to display all of the time.MxCS/images/MXCS16.gif
A new ContextAction ServiceStart is added for the menu Item Start and is Enabled
A new ContextAction ServiceStop is added for the menu Item Stop... and is Disabled
parseGUI((Element)root_elems.item(0));
parseChildren((Element)root_elems.item(1));
<<<MXCSTestApp.init()
>>>MXCSTestApp.start()
<<<MXCSTestApp.start()
==================================
same application fails on java 1.5.0_XX
ACTUAL -
When Run On Java 1.5.0_02

>>>MXCSTestApp()
<<<MXCSTestApp()
>>>MXCSTestApp.init()
m_XMLDocument.getDocumentElement();
root.getChildNodes();
root_elems.getLength();
This node has only one icon to display all of the time.MxCS/images/MXCS16.gif
Exception in parseTreeNode()java.lang.NullPointerException
java.lang.NullPointerException
	at MXCSTest.MXCSTestApp.parseGUI(MXCSTestApp.java:194)
	at MXCSTest.MXCSTestApp.parseTreeNode(MXCSTestApp.java:109)
	at MXCSTest.MXCSTestApp.init(MXCSTestApp.java:251)
	at MXCSTest.MXCSTestApp.main(MXCSTestApp.java:303)
<<<MXCSTestApp.init()
>>>MXCSTestApp.start()
<<<MXCSTestApp.start()
================================

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in parseTreeNode()java.lang.NullPointerException
java.lang.NullPointerException
	at MXCSTest.MXCSTestApp.parseGUI(MXCSTestApp.java:194)
	at MXCSTest.MXCSTestApp.parseTreeNode(MXCSTestApp.java:109)
	at MXCSTest.MXCSTestApp.init(MXCSTestApp.java:251)
	at MXCSTest.MXCSTestApp.main(MXCSTestApp.java:303)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------


-------------------------------------------------------
----- ./MXCSTest/MXCSTestApp.java
-------------------------------------------------------

/*
 * Created on Apr 28, 2005
 * @author NOT Sri Hari.
 * Leveraged entirely from Linville, Kevin original MXCS applet code,
 * This is test applet to reproduce a problem found with MXCS on JRE 1.5.
 */
package MXCSTest;

import java.awt.HeadlessException;
import java.io.IOException;
import java.net.URL;

import javax.swing.JApplet;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;

import XMLTree.XMLDocEntityResolver;
import XMLTree.XMLTreeErrorHandler;

/**
 * @author srihari
 */
public class MXCSTestApp extends JApplet {
    static       URL XMLDocName = null;
	static final String SERVICE_XML = "XMLTree/service.xml";
    
    
	private void loadXML()
	{
		boolean bError = false;
		try
        {
            DocumentBuilderFactory factory =
                                           DocumentBuilderFactory.newInstance();
            factory.setIgnoringElementContentWhitespace(true);
            factory.setValidating(true);
            DocumentBuilder builder = factory.newDocumentBuilder();
            builder.setEntityResolver(new XMLDocEntityResolver());
            builder.setErrorHandler(new XMLTreeErrorHandler());

            XMLDocName = getClass().getClassLoader().getResource(SERVICE_XML);
            m_XMLDocument = builder.parse(XMLDocName.toString());
            
        }
        catch (FactoryConfigurationError fcError)
        {
            bError = true;
        }
        catch (ParserConfigurationException pcException)
        {
            bError = true;
        }
        catch (SAXException sException)
        {
            // This exception will be handled by the XMLTreeErrorHandler,
            // however we still need to still flag that this exception occured.
            bError = true;
        }
        catch (IOException ioException)
        {
            bError = true;
        }
        catch (IllegalArgumentException iaException)
        {
            bError = true;
        }
        finally
        {
            // Nullify erroneous m_XMLDocument if an exception occured.
            // Set all array variables to zero length arrays.
            if (bError)
            {
                String message = "Unable to generate a DOM document from ";
                System.out.println("");
            }
        }
	}
	private void parseTreeNode()
    {
        // Set variables to default values if m_XMLDocument couldn't be loaded.
        if (m_XMLDocument == null)
        {
            return;
        }
        
        try
        {
            Element root = m_XMLDocument.getDocumentElement();
            System.out.println("m_XMLDocument.getDocumentElement();");
            NodeList root_elems = root.getChildNodes();
            System.out.println("root.getChildNodes();");
            // Setup the GUI and children related members.
            int count = root_elems.getLength();
            System.out.println("root_elems.getLength();");
            parseGUI((Element)root_elems.item(0));
            System.out.println("parseGUI((Element)root_elems.item(0));");
            parseChildren((Element)root_elems.item(1));
            System.out.println("parseChildren((Element)root_elems.item(1));");
        }
        catch(Exception e)
        {
           System.out.println("Exception in parseTreeNode()"+e);
           e.printStackTrace();
            
        }
    }
	private void parseGUI(Element e)
    {
        Element icon, member;
        String iconName;
        NodeList members, iconList, contextList;
        int nodeCount = 0;
        int tempCount = 0;

        // Get the GUI nodes.
        members = e.getChildNodes();
        nodeCount = members.getLength();
        
        // Get the name element.
        member = (Element)members.item(0);
        m_strTypeName = ((Text)member.getFirstChild()).getData();
        
        // Get the icon element(s).
        member = (Element)members.item(1);
        iconList = member.getChildNodes();

        // This node has a special list of icons to display.
        tempCount = iconList.getLength();
        String openIcon = "";
        String closedIcon = "";
        String leafIcon = "";

        icon = (Element)iconList.item(0);
        iconName = ((Text)icon.getFirstChild()).getData();

        if (tempCount == 1)
        {
            // This node has only one icon to display all of the time.
        	System.out.println("This node has only one icon to display all of the time."+iconName);
        }
        else
        {
            // This icon has three icons to display
            openIcon = iconName;
            icon = (Element)iconList.item(1);
            closedIcon = ((Text)icon.getFirstChild()).getData();
            icon = (Element)iconList.item(2);
            leafIcon = ((Text)icon.getFirstChild()).getData();
        }

        // Get the context elements.
        if (nodeCount < 3)
        {
            // Context is optional. If it's empty, initialize m_contextActions
            // to an empty Action array.
            System.out.println("So NodeCount< 3 i.e No Contextitems");
        }
        else
        {
            
            String menuName, action;
            NodeList contextItem;
            Element item;
            
            // Get contextMenu Element.
            member = (Element)members.item(2);
            
            // Get list of subelements of contextMenu i.e. list of contextItems
            contextList = member.getChildNodes();
            tempCount = contextList.getLength();

            for (int i = 0; i < tempCount; i++)
            {
                // Get next contextItem
                contextItem = (NodeList)contextList.item(i);
                
                // Get first member of contextItem i.e. menuName
                item = (Element)contextItem.item(0);
               
                if (item.getNodeName().equals("separator"))
                {
                    System.out.println("Oh!. This item is a  separator.");
                }
                else
                {
                    menuName = ((Text)item.getFirstChild()).getData();
                    boolean isEnabled =
                                    item.getAttribute("enabled").equals("true");
                    item = (Element)contextItem.item(1);
                    action = ((Text)item.getFirstChild()).getData();
                    
                    String aStr = (isEnabled) ? "Enabled": "Disabled";
                    System.out.println("A new ContextAction "+action+" is added for the menu Item "+
                    		            menuName+" and is " +aStr);
                    
                }
            }
        }
    }
	
	private void parseChildren(Element e)
    {
        m_bHasDynamicChildren = e.getAttribute("dynamic").equals("true");
    }
	
	public MXCSTestApp() throws HeadlessException {
		super();
		try
		{
		System.out.println(">>>MXCSTestApp() ");
		// Actual code goes here...
		
		}
		finally
		{
		  System.out.println("<<<MXCSTestApp()");
		}
	}
	
	/* (non-Javadoc)
	 * @see java.applet.Applet#init()
	 */
	public void init() {
		super.init();
		try
		{
		System.out.println(">>>MXCSTestApp.init()");
		// Actual code goes here...
		loadXML();
		parseTreeNode();
		}
		finally
		{
		  System.out.println("<<<MXCSTestApp.init()");
		}
		
	}
	
	/* (non-Javadoc)
	 * @see java.applet.Applet#start()
	 */
	public void start() {
		super.start();
		try
		{
		System.out.println(">>>MXCSTestApp.start()");
		// Actual code goes here...
		
		}
		finally
		{
		  System.out.println("<<<MXCSTestApp.start()");
		}
		
	}
	/* (non-Javadoc)
	 * @see java.applet.Applet#stop()
	 */
	public void stop() {
		super.stop();
		try
		{
		System.out.println(">>>MXCSTestApp.stop()");
		// Actual code goes here...
		
		}
		finally
		{
		  System.out.println("<<<MXCSTestApp.stop()");
		}
				
	}
	/* (non-Javadoc)
	 * @see java.applet.Applet#destroy()
	 */
	public void destroy() {
		super.destroy();
	}

	public static void main(String[] args) {
		if(theApp==null)
		{
			theApp = new MXCSTestApp();
		}
		theApp.init();
		theApp.start();
	}
	
	//  Runit as an APP.
	private static MXCSTestApp theApp=null;
	private boolean m_bHasDynamicChildren = false;
	private String m_strTypeName = "";
	private Document m_XMLDocument;
}


-------------------------------------------------------
----- ./XMLTree/service.xml
-------------------------------------------------------

<?xml version="1.0"?>
<!DOCTYPE TreeNodeType SYSTEM "XMLTree/XML/nodeType.dtd">
<TreeNodeType>
  <GUI>
    <name>Service</name>
    <icon>
      <monoIcon>MxCS/images/MXCS16.gif</monoIcon>
    </icon>
    <contextMenu>
      <contextItem>
        <menuName>Start</menuName>
        <action>ServiceStart</action>
      </contextItem>
      <contextItem>
        <menuName enabled = "false">Stop...</menuName>
        <action>ServiceStop</action>
      </contextItem>
    </contextMenu>
  </GUI>
  <children/>
</TreeNodeType>

-------------------------------------------------------
----- ./XMLTree/XMLDocEntityResolver.java
-------------------------------------------------------

/*
 * XMLDocEntityResolver.java
 *
 * Created on April 10, 2003, 12:14 PM
 */

package XMLTree;

import org.xml.sax.*;
import java.net.*;
/**
 *
 * @author  Kevin Linville
 */
/**This class resolves the location of the dtd files that are used for parsing
 * the XML documents used by the <code>XMLTree</code>.
 */
public class XMLDocEntityResolver implements EntityResolver
{
    
    /** Creates a new instance of XMLDocEntityResolver */
    public XMLDocEntityResolver()
    {
    }
    
    public InputSource resolveEntity(String publicId, String systemId)
    {
        URL res;
        
        if (systemId.endsWith("node.dtd"))
        {
            res = getClass().getClassLoader().getResource("XMLTree/XML/node.dtd");
            return new InputSource(res.toString());
        }
        if (systemId.endsWith("nodeType.dtd"))
        {
            res = getClass().getClassLoader().getResource("XMLTree/XML/nodeType.dtd");
            return new InputSource(res.toString());
        }
        
        return null;
    }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
No workaround.

Comments
EVALUATION ChangeSet=http://hg.openjdk.java.net/jdk6/jdk6/jaxp/rev/5c070921580c,ChangeRequest=6923146,ChangeRequest=6917454,ChangeRequest=6472982,ChangeRequest=6909759,ChangeRequest=6333993,ChangeRequest=6900779,ChangeRequest=6900773,ChangeRequest=6900249,ChangeRequest=6675332,ChangeRequest=6889654,ChangeRequest=6889649,ChangeRequest=6863312
18-02-2010

EVALUATION Fixed in JAXP 1.4. Will request integration into JDK6 and 7. Thanks for contributing the test (Submitted On 11-JUN-2008).
10-12-2009

EVALUATION I've rised priority based on popular demand.
26-11-2009

EVALUATION Behavior of NodeList.item() is incorrect, bug accepted. Regression test for J2SE 6.0, Mustang, in addition to J2SE 5.0, Tiger, should be created.
10-12-2005