You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by "Markus Jung (Jira)" <ji...@apache.org> on 2026/07/20 16:02:00 UTC

[jira] [Updated] (TOMEE-4652) UserTransaction state leaks across pooled Tomcat threads between requests

     [ https://issues.apache.org/jira/browse/TOMEE-4652?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Markus Jung updated TOMEE-4652:
-------------------------------
    Description: 
h2. Description
When a servlet or JSP request leaves a {{UserTransaction}} in a non-clean state, the next request served on the same pooled Tomcat exec thread inherits that state. The victim request then either misses an expected {{IllegalStateException}} or gets an exception it does not expect. This is a leaker/victim pair: the same test fails in one vehicle and passes in the other, and which tests fail depends on which request lands on which thread.

The Transactions 2.0 TCK web vehicles show this directly. At the full baseline (no exclusions), 49 tests run, 40 pass, 9 fail. All three signature-test vehicles pass, so the fault sits in {{UserTransaction}} handling, not in transaction propagation itself. The first failures in test order sit in the rollback area, before any {{setTransactionTimeout}} call runs, which rules out a timeout-related cause for those failures.

Run alone on a fresh server, each area behaves correctly on its own: the rollback area passes 10 of 10, {{settransactiontimeout}} passes 4 of 4, and {{setrollbackonly}} passes 7 of 8 (its one failure, the last request in that area, is a victim of its own earlier request, not a new bug). There is no gap around commit-after-timeout: {{settransactiontimeout001}} sleeps 30 seconds before calling {{commit()}}, and when it reaches that call in isolation, {{commit()}} throws as required.

Because a failing request poisons whichever request follows it on the same thread, excluding only the ids that fail at baseline just moves the failure onto different tests (a 9-id exclusion list leaves 4 different tests failing). All three areas are excluded whole in the harness so the default run stays stable and green.

h2. Steps to reproduce / TCK reference
Run the Jakarta Transactions 2.0 TCK web vehicles (servlet and JSP) against TomEE 11 without exclusions. Affected test classes and methods, currently excluded in {{runner-standalone/exclusions/transactions.txt}} in the apache/tomee-tck harness repo:
* {{com/sun/ts/tests/jta/ee/usertransaction/rollback/UserRollbackClient.java}} — {{testUserRollback001}} through {{testUserRollback005}}, each {{_from_jsp}} and {{_from_servlet}}
* {{com/sun/ts/tests/jta/ee/usertransaction/setrollbackonly/UserSetRollbackOnlyClient.java}} — {{testUserSetRollbackOnly001}} through {{testUserSetRollbackOnly004}}, each {{_from_jsp}} and {{_from_servlet}}
* {{com/sun/ts/tests/jta/ee/usertransaction/settransactiontimeout/UserSetTransactionTimeoutClient.java}} — {{testUserSetTransactionTimeout001}} and {{testUserSetTransactionTimeout002}}, each {{_from_jsp}} and {{_from_servlet}}

To confirm the fix, remove these three areas from {{transactions.txt}} and rerun the full baseline; all 49 tests should pass regardless of thread-to-request assignment.

  was:
h2. Summary
UserTransaction state leaks across pooled Tomcat threads, poisoning the next servlet/JSP request

h2. Description
When a servlet or JSP request leaves a {{UserTransaction}} in a non-clean state, the next request served on the same pooled Tomcat exec thread inherits that state. The victim request then either misses an expected {{IllegalStateException}} or gets an exception it does not expect. This is a leaker/victim pair: the same test fails in one vehicle and passes in the other, and which tests fail depends on which request lands on which thread.

The Transactions 2.0 TCK web vehicles show this directly. At the full baseline (no exclusions), 49 tests run, 40 pass, 9 fail. All three signature-test vehicles pass, so the fault sits in {{UserTransaction}} handling, not in transaction propagation itself. The first failures in test order sit in the rollback area, before any {{setTransactionTimeout}} call runs, which rules out a timeout-related cause for those failures.

Run alone on a fresh server, each area behaves correctly on its own: the rollback area passes 10 of 10, {{settransactiontimeout}} passes 4 of 4, and {{setrollbackonly}} passes 7 of 8 (its one failure, the last request in that area, is a victim of its own earlier request, not a new bug). There is no gap around commit-after-timeout: {{settransactiontimeout001}} sleeps 30 seconds before calling {{commit()}}, and when it reaches that call in isolation, {{commit()}} throws as required.

Because a failing request poisons whichever request follows it on the same thread, excluding only the ids that fail at baseline just moves the failure onto different tests (a 9-id exclusion list leaves 4 different tests failing). All three areas are excluded whole in the harness so the default run stays stable and green.

h2. Steps to reproduce / TCK reference
Run the Jakarta Transactions 2.0 TCK web vehicles (servlet and JSP) against TomEE 11 without exclusions. Affected test classes and methods, currently excluded in {{runner-standalone/exclusions/transactions.txt}} in the apache/tomee-tck harness repo:
* {{com/sun/ts/tests/jta/ee/usertransaction/rollback/UserRollbackClient.java}} — {{testUserRollback001}} through {{testUserRollback005}}, each {{_from_jsp}} and {{_from_servlet}}
* {{com/sun/ts/tests/jta/ee/usertransaction/setrollbackonly/UserSetRollbackOnlyClient.java}} — {{testUserSetRollbackOnly001}} through {{testUserSetRollbackOnly004}}, each {{_from_jsp}} and {{_from_servlet}}
* {{com/sun/ts/tests/jta/ee/usertransaction/settransactiontimeout/UserSetTransactionTimeoutClient.java}} — {{testUserSetTransactionTimeout001}} and {{testUserSetTransactionTimeout002}}, each {{_from_jsp}} and {{_from_servlet}}

To confirm the fix, remove these three areas from {{transactions.txt}} and rerun the full baseline; all 49 tests should pass regardless of thread-to-request assignment.


> UserTransaction state leaks across pooled Tomcat threads between requests
> -------------------------------------------------------------------------
>
>                 Key: TOMEE-4652
>                 URL: https://issues.apache.org/jira/browse/TOMEE-4652
>             Project: TomEE
>          Issue Type: Bug
>          Components: TomEE Core Server
>            Reporter: Markus Jung
>            Priority: Major
>
> h2. Description
> When a servlet or JSP request leaves a {{UserTransaction}} in a non-clean state, the next request served on the same pooled Tomcat exec thread inherits that state. The victim request then either misses an expected {{IllegalStateException}} or gets an exception it does not expect. This is a leaker/victim pair: the same test fails in one vehicle and passes in the other, and which tests fail depends on which request lands on which thread.
> The Transactions 2.0 TCK web vehicles show this directly. At the full baseline (no exclusions), 49 tests run, 40 pass, 9 fail. All three signature-test vehicles pass, so the fault sits in {{UserTransaction}} handling, not in transaction propagation itself. The first failures in test order sit in the rollback area, before any {{setTransactionTimeout}} call runs, which rules out a timeout-related cause for those failures.
> Run alone on a fresh server, each area behaves correctly on its own: the rollback area passes 10 of 10, {{settransactiontimeout}} passes 4 of 4, and {{setrollbackonly}} passes 7 of 8 (its one failure, the last request in that area, is a victim of its own earlier request, not a new bug). There is no gap around commit-after-timeout: {{settransactiontimeout001}} sleeps 30 seconds before calling {{commit()}}, and when it reaches that call in isolation, {{commit()}} throws as required.
> Because a failing request poisons whichever request follows it on the same thread, excluding only the ids that fail at baseline just moves the failure onto different tests (a 9-id exclusion list leaves 4 different tests failing). All three areas are excluded whole in the harness so the default run stays stable and green.
> h2. Steps to reproduce / TCK reference
> Run the Jakarta Transactions 2.0 TCK web vehicles (servlet and JSP) against TomEE 11 without exclusions. Affected test classes and methods, currently excluded in {{runner-standalone/exclusions/transactions.txt}} in the apache/tomee-tck harness repo:
> * {{com/sun/ts/tests/jta/ee/usertransaction/rollback/UserRollbackClient.java}} — {{testUserRollback001}} through {{testUserRollback005}}, each {{_from_jsp}} and {{_from_servlet}}
> * {{com/sun/ts/tests/jta/ee/usertransaction/setrollbackonly/UserSetRollbackOnlyClient.java}} — {{testUserSetRollbackOnly001}} through {{testUserSetRollbackOnly004}}, each {{_from_jsp}} and {{_from_servlet}}
> * {{com/sun/ts/tests/jta/ee/usertransaction/settransactiontimeout/UserSetTransactionTimeoutClient.java}} — {{testUserSetTransactionTimeout001}} and {{testUserSetTransactionTimeout002}}, each {{_from_jsp}} and {{_from_servlet}}
> To confirm the fix, remove these three areas from {{transactions.txt}} and rerun the full baseline; all 49 tests should pass regardless of thread-to-request assignment.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)