-
Bug
-
Resolution: Unresolved
-
P4
-
None
-
6
-
x86
-
windows_xp
FULL PRODUCT VERSION :
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
The DOM importNode method fails to copy text node content correctly. This appears to be related to the deferred node loading mechanism. When the node to be imported has not been traversed it is not imported correctly.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
(Details in provided code).
Create two documents by each parsing an InputStream. Adopt an element containing a text node from one document to the other. Examine the getTextContent of the element or the getNodeValue of the text node.
Tested and failed in JRE 1.6 and some 1.5 variants.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The content of the element or text node should match the source document.
ACTUAL -
Random contents depending upon the exact nature of the input.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
/**
* JUnit {@link TestCase} that demostrates a bug in DOM when using adoptNode.
* <br/>
* The value of a text node that is the child of an element node does not retain its value
* after being adopted from another document.
* <br/>
* The actual value returned from the text node seems to depend upon the input document in
* a very random way.
* <br/>
* The use of a "tickle" flag demonstrates that the behavior could be related to deferring node expansion.
* When the importee node is tickled, the error is not reproduced.
* <br/>
*/
public class AdoptNodeTestCase extends TestCase
{
public void testAdoptNode() throws Exception
{
// This one passes.
doAdoptNode(true);
// This one fails.
doAdoptNode(false);
}
/**
* @param tickle Touching the adoptee node avoids the error.
*/
private void doAdoptNode(final boolean tickle) throws Exception
{
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
final DocumentBuilder builder = factory.newDocumentBuilder();
final InputStream istreamA = getClass().getResourceAsStream("docA.xml");
final Document docA = builder.parse(istreamA);
assertNotNull(docA);
final Element docElementA = docA.getDocumentElement();
assertNotNull(docElementA);
final InputStream istreamB = getClass().getResourceAsStream("docB.xml");
final Document docB = builder.parse(istreamB);
assertNotNull(docB);
final Element docElementB = docB.getDocumentElement();
assertNotNull(docElementB);
final Node adopteeB = docElementB.getFirstChild().getNextSibling();
assertNotNull(adopteeB);
if (tickle)
{
assertEquals("123", adopteeB.getTextContent());
}
final Node adoptedA = docA.adoptNode(adopteeB);
assertNotNull(adoptedA);
final Node textA = adoptedA.getFirstChild();
assertEquals(Node.TEXT_NODE, textA.getNodeType());
assertEquals("123", textA.getNodeValue());
// Similarly...
assertEquals("123", adoptedA.getTextContent());
docElementA.appendChild(adoptedA);
}
}
docA:
<?xml version="1.0" encoding="UTF-8"?>
<rootA/>
docB:
<?xml version="1.0" encoding="UTF-8"?>
<rootB>
<thing>123</thing>
</rootB>
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Accessing the node to be imported bypasses the error. I suspect that traversing the input node causes it to be expanded.
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
The DOM importNode method fails to copy text node content correctly. This appears to be related to the deferred node loading mechanism. When the node to be imported has not been traversed it is not imported correctly.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
(Details in provided code).
Create two documents by each parsing an InputStream. Adopt an element containing a text node from one document to the other. Examine the getTextContent of the element or the getNodeValue of the text node.
Tested and failed in JRE 1.6 and some 1.5 variants.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The content of the element or text node should match the source document.
ACTUAL -
Random contents depending upon the exact nature of the input.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
/**
* JUnit {@link TestCase} that demostrates a bug in DOM when using adoptNode.
* <br/>
* The value of a text node that is the child of an element node does not retain its value
* after being adopted from another document.
* <br/>
* The actual value returned from the text node seems to depend upon the input document in
* a very random way.
* <br/>
* The use of a "tickle" flag demonstrates that the behavior could be related to deferring node expansion.
* When the importee node is tickled, the error is not reproduced.
* <br/>
*/
public class AdoptNodeTestCase extends TestCase
{
public void testAdoptNode() throws Exception
{
// This one passes.
doAdoptNode(true);
// This one fails.
doAdoptNode(false);
}
/**
* @param tickle Touching the adoptee node avoids the error.
*/
private void doAdoptNode(final boolean tickle) throws Exception
{
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
final DocumentBuilder builder = factory.newDocumentBuilder();
final InputStream istreamA = getClass().getResourceAsStream("docA.xml");
final Document docA = builder.parse(istreamA);
assertNotNull(docA);
final Element docElementA = docA.getDocumentElement();
assertNotNull(docElementA);
final InputStream istreamB = getClass().getResourceAsStream("docB.xml");
final Document docB = builder.parse(istreamB);
assertNotNull(docB);
final Element docElementB = docB.getDocumentElement();
assertNotNull(docElementB);
final Node adopteeB = docElementB.getFirstChild().getNextSibling();
assertNotNull(adopteeB);
if (tickle)
{
assertEquals("123", adopteeB.getTextContent());
}
final Node adoptedA = docA.adoptNode(adopteeB);
assertNotNull(adoptedA);
final Node textA = adoptedA.getFirstChild();
assertEquals(Node.TEXT_NODE, textA.getNodeType());
assertEquals("123", textA.getNodeValue());
// Similarly...
assertEquals("123", adoptedA.getTextContent());
docElementA.appendChild(adoptedA);
}
}
docA:
<?xml version="1.0" encoding="UTF-8"?>
<rootA/>
docB:
<?xml version="1.0" encoding="UTF-8"?>
<rootB>
<thing>123</thing>
</rootB>
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Accessing the node to be imported bypasses the error. I suspect that traversing the input node causes it to be expanded.