This is an automated email from the ASF dual-hosted git repository. rmaucher pushed a commit to branch 9.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 8e5e9196c513e25eb7f76db83e4d68aeeff9c494 Author: opencode <[email protected]> AuthorDate: Thu Nov 5 15:02:05 2026 +0100 Use the base class key for anonymous timer MBeans ResetAbandonedTimer built its JMX key from getClass().getSimpleName(). An anonymous subclass has an empty simple name, so the key became ,JdbcInterceptor= and the registration failed on every borrow while the base class worked. Fall back to ResetAbandonedTimer.class.getSimpleName() when the subclass name is empty. Add a test that binds an anonymous timer to a pooled connection and asserts its MBean is published under the base-class key. --- .../jdbc/pool/interceptor/ResetAbandonedTimer.java | 9 +++++- .../TestResetAbandonedTimerMBeanIdle.java | 34 ++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/ResetAbandonedTimer.java b/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/ResetAbandonedTimer.java index 8beaf71f38..ee5da06fb1 100644 --- a/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/ResetAbandonedTimer.java +++ b/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/ResetAbandonedTimer.java @@ -161,7 +161,14 @@ public class ResetAbandonedTimer extends AbstractQueryReport implements ResetAba // level, with the exception behind it. A refused name is // not claimed here, so it stays the property of whoever // holds it and the next borrow tries again. - String keyprop = ",JdbcInterceptor=" + getClass().getSimpleName(); + String simpleName = getClass().getSimpleName(); + if (simpleName.isEmpty()) { + // An anonymous subclass has no simple name; fall back + // to the base class's name so the JMX key is never + // empty. + simpleName = ResetAbandonedTimer.class.getSimpleName(); + } + String keyprop = ",JdbcInterceptor=" + simpleName; oname = JmxUtil.registerJmx(pcon.getObjectName(), keyprop, this); } } diff --git a/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/pool/interceptor/TestResetAbandonedTimerMBeanIdle.java b/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/pool/interceptor/TestResetAbandonedTimerMBeanIdle.java index ceda27f1c3..6c017d1a21 100644 --- a/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/pool/interceptor/TestResetAbandonedTimerMBeanIdle.java +++ b/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/pool/interceptor/TestResetAbandonedTimerMBeanIdle.java @@ -280,4 +280,38 @@ class TestResetAbandonedTimerMBeanIdle extends JdbcPoolBaseTest { "the release must be the idle check's own, which is the bookkeeping the pokes defeated"); awaitSessions(0); } + + @Test + void anAnonymousSubclassPublishesUnderTheBaseClassKey() throws Exception { + MBeanServer server = ManagementFactory.getPlatformMBeanServer(); + String uid = Long.toString(System.nanoTime()); + DataSource ds = newDataSource(); + ds.getPoolProperties().setJmxEnabled(true); + ds.getPoolProperties().setInitialSize(0); + ds.getPoolProperties().setTimeBetweenEvictionRunsMillis(0); + ds.createPool(); + ds.preRegister(server, new ObjectName( + "tomcat:type=ResetAbandonedTimerMBeanTest,role=anonymous,uid=" + uid)); + pool = ds; + + try (Connection connection = ds.getConnection()) { + PooledConnection pc = connection.unwrap(PooledConnection.class); + ResetAbandonedTimer anonymous = new ResetAbandonedTimer() { + }; + anonymous.reset(ds.getPool(), pc); + try { + ObjectName timerName = null; + for (ObjectName name : server.queryNames(new ObjectName("tomcat.jdbc:*"), null)) { + if (ResetAbandonedTimer.class.getSimpleName().equals(name.getKeyProperty("JdbcInterceptor")) + && uid.equals(name.getKeyProperty("uid"))) { + timerName = name; + } + } + Assertions.assertNotNull(timerName, + "an anonymous timer has no simple name and must publish under the base class key"); + } finally { + anonymous.reset(null, null); + } + } + } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
