Thanks Arturo!

Another sporadic one in org.apache.tomcat.util.net.TestLargeClientHello:

Testcase: testClientHelloLargerThanParseLimit took 4.741 sec
        Caused an ERROR
null
java.util.ConcurrentModificationException
at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1013)
        at java.base/java.util.ArrayList$Itr.next(ArrayList.java:967)
at org.apache.catalina.startup.TomcatBaseTest$LogCapture.hasException(TomcatBaseTest.java:1005) at org.apache.tomcat.util.net.TestLargeClientHello.testClientHelloLargerThanParseLimit(TestLargeClientHello.java:144) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)


Am 09.11.26 um 14:08 schrieb Arturo Bernal via dev:
I looked at the three failures with the 11.0.28 source tarball and Java 17.

1. TestAbstractEndpoint (2 errors) The two virtual thread tests need Java
21 and 11.0.x supports Java 17. Adding
Assume.assumeTrue(JreCompat.isJre21Available()), as
TestStandardVirtualThreadExecutor does, skips them on Java 17 and they
still run on Java 21.

2. TestJspCServletContext.testGetResourceWithUriIllegalCharacters It passes
with a UTF-8 locale and fails with LANG=C (InvalidPathException on
unicode-ü.jsp). An Assume that sun.jnu.encoding can encode the character
skips it in that case.

3. TestUpgrade.testUpgradeInfoUnregisteredWhenConnectionClosed I could not
reproduce it as it is (8 runs with NIO and 8 with NIO2). I think I found
the cause. In ConnectionHandler.process() the processor is taken from the
socket wrapper on entry and only set back at the end. The UpgradeInfo is
registered earlier, in the processor constructor. If the endpoint closes
the  socket in between, which is what stop() does, release(socketWrapper)
finds no processor, recycle() is never called and the UpgradeInfo stays
registered.

To check this I added Thread.sleep(1500) to NoClose.init() in the test.
With  that, NIO2 fails every time with the same message and the same line
(TestUpgrade.java:439) and NIO passes.

This change fixes it, on top of setCurrentProcessor() in process():

     if (wrapper.isClosed()) {
         // The socket was closed while this thread owned the processor so
         // the close could not release it.
         release(wrapper);
     }

takeCurrentProcessor() is atomic so only one thread can release the
processor. With it the sleep version of the test passes with NIO and NIO2,
and  all the coyote tests pass with NIO and NIO2 (75 classes, 9322 tests).

Not tested on main, only on the 11.0.28 tarball.

Arturo


On Mon, Nov 9, 2026 at 1:24 PM Mark Thomas via dev <[email protected]>
wrote:

Thanks Rainer. I'll take a look before I tag 11.0.29

Mark


On 09/11/2026 12:08, Rainer Jung wrote:
plus sporadic failures in org.apache.coyote.http11.upgrade.TestUpgrade
(until now only observed in NIO2, but that might be pure coincidence):

Testcase: testUpgradeInfoUnregisteredWhenConnectionClosed took 10.176 sec
          FAILED
The UpgradeInfo remained registered after the connection was closed.
expected:<0> but was:<1>
junit.framework.AssertionFailedError: The UpgradeInfo remained
registered after the connection was closed. expected:<0> but was:<1>
          at

org.apache.coyote.http11.upgrade.TestUpgrade.testUpgradeInfoUnregisteredWhenConnectionClosed(TestUpgrade.java:439)
          at java.base/
jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at java.base/

jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
          at java.base/

jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to