ArrayIndexOutOfBoundsException regression iterating children (original) (raw)
I have a repository of benchmarks where some Java DOM implementations are compared (JDK DOM, DOM4J, CSS4J-DOM4J, CSS4J DOM and finally Jsoup). You can see the results here: https://css4j.github.io/dom-mark.html
Until 1.19.1 I could run the basic Jsoup element iterator benchmark that just counts children, but 1.20.1 and 1.21.1 both produce errors. This one is from 1.21.1:
$ java -Xmx3G -jar buildMaven/benchmarks.jar DOMIteratorSmallMark.markElementIteratorJsoup
JMH version: 1.37
VM version: JDK 21.0.7, OpenJDK 64-Bit Server VM, 21.0.7+6-LTS
VM invoker: [...]\jdk-21.0.7.6-hotspot\bin\java.exe
VM options: -Xmx3G
Blackhole mode: compiler (auto-detected, use -Djmh.blackhole.autoDetect=false to disable)
Warmup: 6 iterations, 10 s each
Measurement: 16 iterations, 10 s each
Timeout: 10 min per iteration
Threads: 4 threads, will synchronize iterations
Benchmark mode: Throughput, ops/time
Benchmark: io.sf.carte.mark.dom.DOMIteratorSmallMark.markElementIteratorJsoup
Run progress: 0,00% complete, ETA 00:07:20
Fork: 1 of 2
Warmup Iteration 1:
java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3 at org.jsoup.nodes.Attributes.addObject(Attributes.java:147) at org.jsoup.nodes.Attributes.userData(Attributes.java:179) at org.jsoup.nodes.Element.cachedChildren(Element.java:407) at org.jsoup.nodes.Element.childElementsList(Element.java:394) at org.jsoup.nodes.Element.children(Element.java:385) at io.sf.carte.mark.dom.DOMIteratorSmallMark.iterateJsoupElements(DOMIteratorSmallMark.java:157) at io.sf.carte.mark.dom.DOMIteratorSmallMark.iterateJsoupElements(DOMIteratorSmallMark.java:157) at io.sf.carte.mark.dom.DOMIteratorSmallMark.iterateJsoupElements(DOMIteratorSmallMark.java:157) at io.sf.carte.mark.dom.DOMIteratorSmallMark.iterateJsoupElements(DOMIteratorSmallMark.java:157) at io.sf.carte.mark.dom.DOMIteratorSmallMark.iterateJsoupElements(DOMIteratorSmallMark.java:157) at io.sf.carte.mark.dom.DOMIteratorSmallMark.iterateJsoupElements(DOMIteratorSmallMark.java:157) at io.sf.carte.mark.dom.DOMIteratorSmallMark.markElementIteratorJsoup(DOMIteratorSmallMark.java:146) at io.sf.carte.mark.dom.jmh_generated.DOMIteratorSmallMark_markElementIteratorJsoup_jmhTest.markElementIteratorJsoup_Throughput(DOMIteratorSmallMark_markElementIteratorJsoup_jmhTest.java:80) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:527) at org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:504) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) at java.base/java.lang.Thread.run(Thread.java:1583)
java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3 at org.jsoup.nodes.Attributes.addObject(Attributes.java:147) at org.jsoup.nodes.Attributes.userData(Attributes.java:179) at org.jsoup.nodes.Element.cachedChildren(Element.java:407) at org.jsoup.nodes.Element.childElementsList(Element.java:394) at org.jsoup.nodes.Element.children(Element.java:385) at io.sf.carte.mark.dom.DOMIteratorSmallMark.iterateJsoupElements(DOMIteratorSmallMark.java:157) at io.sf.carte.mark.dom.DOMIteratorSmallMark.iterateJsoupElements(DOMIteratorSmallMark.java:157) at io.sf.carte.mark.dom.DOMIteratorSmallMark.iterateJsoupElements(DOMIteratorSmallMark.java:157) at io.sf.carte.mark.dom.DOMIteratorSmallMark.iterateJsoupElements(DOMIteratorSmallMark.java:157) at io.sf.carte.mark.dom.DOMIteratorSmallMark.iterateJsoupElements(DOMIteratorSmallMark.java:157) at io.sf.carte.mark.dom.DOMIteratorSmallMark.iterateJsoupElements(DOMIteratorSmallMark.java:157) at io.sf.carte.mark.dom.DOMIteratorSmallMark.markElementIteratorJsoup(DOMIteratorSmallMark.java:146) at io.sf.carte.mark.dom.jmh_generated.DOMIteratorSmallMark_markElementIteratorJsoup_jmhTest.markElementIteratorJsoup_thrpt_jmhStub(DOMIteratorSmallMark_markElementIteratorJsoup_jmhTest.java:147) at io.sf.carte.mark.dom.jmh_generated.DOMIteratorSmallMark_markElementIteratorJsoup_jmhTest.markElementIteratorJsoup_Throughput(DOMIteratorSmallMark_markElementIteratorJsoup_jmhTest.java:86) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:527) at org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:504) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) at java.base/java.lang.Thread.run(Thread.java:1583)
The code is somewhat simple, just count children: https://github.com/css4j/benchmark/blob/f02fe560c5baba4730379e4a1c203f0d75e9066e/src/io/sf/carte/mark/dom/DOMIteratorSmallMark.java
How to reproduce
Clone the benchmark repository:
git clone https://github.com/css4j/benchmark.git
In the repository copy, produce the jar files in any of the supported ways, for example to build with Maven you would modify the pom.xml file to bump the Jsoup version to 1.21.1:
https://github.com/css4j/benchmark/blob/f02fe560c5baba4730379e4a1c203f0d75e9066e/pom.xml#L86-L90
then run
Then execute the Jsoup element iterator benchmark:
java -Xmx3G -jar buildMaven/benchmarks.jar DOMIteratorSmallMark.markElementIteratorJsoup