-
Bug
-
Resolution: Won't Fix
-
P3
-
6u5
-
x86
-
windows_xp
PLATFORM:
Windows XP. Reproducible with JDK 5 and JDK 6.
DESCRIPTION from Licensee/CU:
A full description and readme for the testcases has been attached to the CR.
This Description is a summary of that readme file.
We use the standard HTML parser and encounter some errors from time to time.
Each thread in our testcase parses one of two files - either component.html or
list.html. When a list tag is encountered while reading component.html, or a
component tag is encountered while reading list.html, an error is reported
using LOG4J and a counter is incremented.
At the end of the test, we report the total number of files parsed by each thread, and the number of parsing errors. The errors we see seem to be caused by concurrency problems, despite the statement in the API documentation that the parse() method should be thread safe:
http://java.sun.com/javase/6/docs/api/javax/swing/text/html/HTMLEditorKit.Parser.html
A suggested fix is included below.
RECREATION INSTRUCTIONS:
The testcase package contains the source code of the testcase as an Eclipse
project. However, there is also an ANT script to run all tests from a shell.
To run it from command prompt you require ANT 1.7.0. You also need to set the
following command line options:
set ANT_HOME=c:\ant
set JAVA_HOME=c:\jdk-1.5.0.05
set PATH=%PATH%;%ANT_HOME%\bin
Then cd to the working directory (i.e where the testcase is) to run the testcases. You can run each test individually with the respective ANT target:
ant testStandardParser
ant testPatchedParser
or you can run "ant all" to execute both tests in turn.
The ant target testStandardParser encounters many errors even with a small number of threads - 5 in total, with the odd numbers parsing component.html and the even numbers parsing list.html.
The ant target testPatchedParser runs the testcase with some modified classes (see SUGGESTED FIX section below, and the readme in the testcase package for details).
The results of running the tests should look something like this, with the testStandardParser producing multiple errors, and testPatchedParser working cleanly:
testStandardParser results (failures marked with "-->"):
[echo] ******************************************************
[echo] * STANDARD PARSER *
[echo] ******************************************************
[java] INFO [main] - LOG4J initialized with /C:/TEMP/ProblemParser/properties/log4j.properties (reload configuration every 15 seconds).
[java] INFO [main] - Testing.
[java] INFO [main] - Using standard JDK HTML parser.
[java] INFO [main] - Launching 6 threads.
[java] INFO [main] - Duration:10 sec
[java] INFO [Thread<0>] - StartedThread<0>
[java] INFO [Thread<1>] - StartedThread<1>
[java] INFO [Thread<3>] - StartedThread<3>
[java] INFO [Thread<2>] - StartedThread<2>
[java] INFO [main] - Waiting 10 sec before stopping the test.
[java] INFO [Thread<5>] - StartedThread<5>
[java] INFO [Thread<4>] - StartedThread<4>
[java] ERROR [Thread<0>] - Tag list in file component.html.
[java] ERROR [Thread<1>] - Tag component in file list.html.
[java] ERROR [Thread<2>] - Tag list in file component.html.
[java] ERROR [Thread<2>] - Tag list in file component.html.
[java] ERROR [Thread<4>] - Tag list in file component.html.
[java] ERROR [Thread<1>] - Tag component in file list.html.
[java] ERROR [Thread<0>] - Tag list in file component.html.
[java] ERROR [Thread<3>] - Tag component in file list.html.
[java] ERROR [Thread<2>] - Tag list in file component.html.
[java] ERROR [Thread<1>] - Tag component in file list.html.
[java] ERROR [Thread<5>] - Tag component in file list.html.
¿
[java] ERROR [Thread<0>] - Tag list in file component.html.
[java] ERROR [Thread<3>] - Tag component in file list.html.
[java] ERROR [Thread<4>] - Tag list in file component.html.
[java] ERROR [Thread<0>] - Tag list in file component.html.
[java] ERROR [Thread<0>] - Tag list in file component.html.
[java] ERROR [Thread<1>] - Tag component in file list.html.
[java] INFO [main] - Waiting for termination of Thread<0>
[java] INFO [Thread<4>] - Stopped Thread<4>
[java] INFO [Thread<5>] - Stopped Thread<5>
[java] INFO [Thread<3>] - Stopped Thread<3>
[java] INFO [Thread<0>] - Stopped Thread<0>
[java] INFO [Thread<1>] - Stopped Thread<1>
[java] INFO [main] - Waiting for termination of Thread<1>
[java] INFO [main] - Waiting for termination of Thread<2>
[java] INFO [Thread<2>] - Stopped Thread<2>
[java] INFO [main] - Waiting for termination of Thread<3>
[java] INFO [main] - Waiting for termination of Thread<4>
[java] INFO [main] - Waiting for termination of Thread<5>
--> [java] ERROR [main] - Count: 2609 Fail: 119 Thread<0>
--> [java] ERROR [main] - Count: 2686 Fail: 120 Thread<1>
--> [java] ERROR [main] - Count: 2606 Fail: 114 Thread<2>
--> [java] ERROR [main] - Count: 2714 Fail: 114 Thread<3>
--> [java] ERROR [main] - Count: 2606 Fail: 98 Thread<4>
--> [java] ERROR [main] - Count: 2727 Fail: 117 Thread<5>
[java] INFO [main] - Existing.
[java] INFO [main] - Done.
testPatchedParser results:
[echo] ******************************************************
[echo] * PATCHED PARSER *
[echo] ******************************************************
[java] INFO [main] - LOG4J initialized with /C:/TEMP/ProblemParser/properties/log4j.properties (reload configurati
on every 15 seconds).
[java] INFO [main] - Testing.
[java] INFO [main] - Using patched parser with clone.
[java] INFO [main] - Launching 6 threads.
[java] INFO [main] - Duration:10 sec
[java] INFO [Thread<0>] - StartedThread<0>
[java] INFO [main] - Waiting 10 sec before stopping the test.
[java] INFO [Thread<1>] - StartedThread<1>
[java] INFO [Thread<2>] - StartedThread<2>
[java] INFO [Thread<4>] - StartedThread<4>
[java] INFO [Thread<3>] - StartedThread<3>
[java] INFO [Thread<5>] - StartedThread<5>
[java] INFO [main] - Waiting for termination of Thread<0>
[java] INFO [Thread<0>] - Stopped Thread<0>
[java] INFO [main] - Waiting for termination of Thread<1>
[java] INFO [Thread<4>] - Stopped Thread<4>
[java] INFO [Thread<3>] - Stopped Thread<3>
[java] INFO [Thread<5>] - Stopped Thread<5>
[java] INFO [Thread<1>] - Stopped Thread<1>
[java] INFO [main] - Waiting for termination of Thread<2>
[java] INFO [Thread<2>] - Stopped Thread<2>
[java] INFO [main] - Waiting for termination of Thread<3>
[java] INFO [main] - Waiting for termination of Thread<4>
[java] INFO [main] - Waiting for termination of Thread<5>
[java] INFO [main] - Count: 2447 Thread<0>
[java] INFO [main] - Count: 2477 Thread<1>
[java] INFO [main] - Count: 2428 Thread<2>
[java] INFO [main] - Count: 2494 Thread<3>
[java] INFO [main] - Count: 2409 Thread<4>
[java] INFO [main] - Count: 2512 Thread<5>
[java] INFO [main] - Existing.
[java] INFO [main] - Done
SUGGESTED FIX:
The problem does not occur if we make the following modifications in the class library code:
Element.java
------------
Class declaration modified to:
class Element implements DTDConstants, Serializable, Cloneable {
^^^^^^^^^
And added clone() implementation:
protected java.lang.Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
throw new Error("ne doit pas arriver");
}
}
Parser.java
-----------
Changed elem = dtd.getElement("unknown");
to elem = (Element)(dtd.getElement("unknown")).clone;
Changed elem = dtd.getElement("unknown");
to elem = (Element)(dtd.getElement("unknown")).clone;
Windows XP. Reproducible with JDK 5 and JDK 6.
DESCRIPTION from Licensee/CU:
A full description and readme for the testcases has been attached to the CR.
This Description is a summary of that readme file.
We use the standard HTML parser and encounter some errors from time to time.
Each thread in our testcase parses one of two files - either component.html or
list.html. When a list tag is encountered while reading component.html, or a
component tag is encountered while reading list.html, an error is reported
using LOG4J and a counter is incremented.
At the end of the test, we report the total number of files parsed by each thread, and the number of parsing errors. The errors we see seem to be caused by concurrency problems, despite the statement in the API documentation that the parse() method should be thread safe:
http://java.sun.com/javase/6/docs/api/javax/swing/text/html/HTMLEditorKit.Parser.html
A suggested fix is included below.
RECREATION INSTRUCTIONS:
The testcase package contains the source code of the testcase as an Eclipse
project. However, there is also an ANT script to run all tests from a shell.
To run it from command prompt you require ANT 1.7.0. You also need to set the
following command line options:
set ANT_HOME=c:\ant
set JAVA_HOME=c:\jdk-1.5.0.05
set PATH=%PATH%;%ANT_HOME%\bin
Then cd to the working directory (i.e where the testcase is) to run the testcases. You can run each test individually with the respective ANT target:
ant testStandardParser
ant testPatchedParser
or you can run "ant all" to execute both tests in turn.
The ant target testStandardParser encounters many errors even with a small number of threads - 5 in total, with the odd numbers parsing component.html and the even numbers parsing list.html.
The ant target testPatchedParser runs the testcase with some modified classes (see SUGGESTED FIX section below, and the readme in the testcase package for details).
The results of running the tests should look something like this, with the testStandardParser producing multiple errors, and testPatchedParser working cleanly:
testStandardParser results (failures marked with "-->"):
[echo] ******************************************************
[echo] * STANDARD PARSER *
[echo] ******************************************************
[java] INFO [main] - LOG4J initialized with /C:/TEMP/ProblemParser/properties/log4j.properties (reload configuration every 15 seconds).
[java] INFO [main] - Testing.
[java] INFO [main] - Using standard JDK HTML parser.
[java] INFO [main] - Launching 6 threads.
[java] INFO [main] - Duration:10 sec
[java] INFO [Thread<0>] - StartedThread<0>
[java] INFO [Thread<1>] - StartedThread<1>
[java] INFO [Thread<3>] - StartedThread<3>
[java] INFO [Thread<2>] - StartedThread<2>
[java] INFO [main] - Waiting 10 sec before stopping the test.
[java] INFO [Thread<5>] - StartedThread<5>
[java] INFO [Thread<4>] - StartedThread<4>
[java] ERROR [Thread<0>] - Tag list in file component.html.
[java] ERROR [Thread<1>] - Tag component in file list.html.
[java] ERROR [Thread<2>] - Tag list in file component.html.
[java] ERROR [Thread<2>] - Tag list in file component.html.
[java] ERROR [Thread<4>] - Tag list in file component.html.
[java] ERROR [Thread<1>] - Tag component in file list.html.
[java] ERROR [Thread<0>] - Tag list in file component.html.
[java] ERROR [Thread<3>] - Tag component in file list.html.
[java] ERROR [Thread<2>] - Tag list in file component.html.
[java] ERROR [Thread<1>] - Tag component in file list.html.
[java] ERROR [Thread<5>] - Tag component in file list.html.
¿
[java] ERROR [Thread<0>] - Tag list in file component.html.
[java] ERROR [Thread<3>] - Tag component in file list.html.
[java] ERROR [Thread<4>] - Tag list in file component.html.
[java] ERROR [Thread<0>] - Tag list in file component.html.
[java] ERROR [Thread<0>] - Tag list in file component.html.
[java] ERROR [Thread<1>] - Tag component in file list.html.
[java] INFO [main] - Waiting for termination of Thread<0>
[java] INFO [Thread<4>] - Stopped Thread<4>
[java] INFO [Thread<5>] - Stopped Thread<5>
[java] INFO [Thread<3>] - Stopped Thread<3>
[java] INFO [Thread<0>] - Stopped Thread<0>
[java] INFO [Thread<1>] - Stopped Thread<1>
[java] INFO [main] - Waiting for termination of Thread<1>
[java] INFO [main] - Waiting for termination of Thread<2>
[java] INFO [Thread<2>] - Stopped Thread<2>
[java] INFO [main] - Waiting for termination of Thread<3>
[java] INFO [main] - Waiting for termination of Thread<4>
[java] INFO [main] - Waiting for termination of Thread<5>
--> [java] ERROR [main] - Count: 2609 Fail: 119 Thread<0>
--> [java] ERROR [main] - Count: 2686 Fail: 120 Thread<1>
--> [java] ERROR [main] - Count: 2606 Fail: 114 Thread<2>
--> [java] ERROR [main] - Count: 2714 Fail: 114 Thread<3>
--> [java] ERROR [main] - Count: 2606 Fail: 98 Thread<4>
--> [java] ERROR [main] - Count: 2727 Fail: 117 Thread<5>
[java] INFO [main] - Existing.
[java] INFO [main] - Done.
testPatchedParser results:
[echo] ******************************************************
[echo] * PATCHED PARSER *
[echo] ******************************************************
[java] INFO [main] - LOG4J initialized with /C:/TEMP/ProblemParser/properties/log4j.properties (reload configurati
on every 15 seconds).
[java] INFO [main] - Testing.
[java] INFO [main] - Using patched parser with clone.
[java] INFO [main] - Launching 6 threads.
[java] INFO [main] - Duration:10 sec
[java] INFO [Thread<0>] - StartedThread<0>
[java] INFO [main] - Waiting 10 sec before stopping the test.
[java] INFO [Thread<1>] - StartedThread<1>
[java] INFO [Thread<2>] - StartedThread<2>
[java] INFO [Thread<4>] - StartedThread<4>
[java] INFO [Thread<3>] - StartedThread<3>
[java] INFO [Thread<5>] - StartedThread<5>
[java] INFO [main] - Waiting for termination of Thread<0>
[java] INFO [Thread<0>] - Stopped Thread<0>
[java] INFO [main] - Waiting for termination of Thread<1>
[java] INFO [Thread<4>] - Stopped Thread<4>
[java] INFO [Thread<3>] - Stopped Thread<3>
[java] INFO [Thread<5>] - Stopped Thread<5>
[java] INFO [Thread<1>] - Stopped Thread<1>
[java] INFO [main] - Waiting for termination of Thread<2>
[java] INFO [Thread<2>] - Stopped Thread<2>
[java] INFO [main] - Waiting for termination of Thread<3>
[java] INFO [main] - Waiting for termination of Thread<4>
[java] INFO [main] - Waiting for termination of Thread<5>
[java] INFO [main] - Count: 2447 Thread<0>
[java] INFO [main] - Count: 2477 Thread<1>
[java] INFO [main] - Count: 2428 Thread<2>
[java] INFO [main] - Count: 2494 Thread<3>
[java] INFO [main] - Count: 2409 Thread<4>
[java] INFO [main] - Count: 2512 Thread<5>
[java] INFO [main] - Existing.
[java] INFO [main] - Done
SUGGESTED FIX:
The problem does not occur if we make the following modifications in the class library code:
Element.java
------------
Class declaration modified to:
class Element implements DTDConstants, Serializable, Cloneable {
^^^^^^^^^
And added clone() implementation:
protected java.lang.Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
throw new Error("ne doit pas arriver");
}
}
Parser.java
-----------
Changed elem = dtd.getElement("unknown");
to elem = (Element)(dtd.getElement("unknown")).clone;
Changed elem = dtd.getElement("unknown");
to elem = (Element)(dtd.getElement("unknown")).clone;