This is an automated email from the ASF dual-hosted git repository.
markt-asf pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/9.0.x by this push:
new d2917ea453 Fix BZ 69236 - reset JDBC interceptors in declaration order
d2917ea453 is described below
commit d2917ea4537b15740f23dab7efd3838fb6465a40
Author: Arturo Bernal <[email protected]>
AuthorDate: Fri Oct 23 14:07:55 2026 +0200
Fix BZ 69236 - reset JDBC interceptors in declaration order
When a pooled connection was created, the interceptor chain was built
from the last interceptor to the first and each interceptor was reset as
it was added, so reset() was called in reverse order. For a connection
taken from the pool the chain was reset from the first interceptor to
the last. Build the chain first and then reset it in declaration order
in both cases.
---
.../apache/tomcat/jdbc/pool/ConnectionPool.java | 11 ++-
.../jdbc/test/InterceptorResetOrderTest.java | 106 +++++++++++++++++++++
2 files changed, 113 insertions(+), 4 deletions(-)
diff --git
a/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
b/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
index 533b4244ee..b9ad952c1f 100644
---
a/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
+++
b/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
@@ -311,8 +311,6 @@ public class ConnectionPool {
interceptor.setProperties(proxies[i].getProperties());
//setup the chain
interceptor.setNext(handler);
- //call reset
- interceptor.reset(this, con);
//configure the last one to be held by the connection
handler = interceptor;
}catch(Exception x) {
@@ -323,13 +321,18 @@ public class ConnectionPool {
}
//cache handler for the next iteration
con.setHandler(handler);
- } else {
+ }
+ //reset the chain in the order the interceptors are declared, for new
and cached handlers alike
+ try {
JdbcInterceptor next = handler;
- //we have a cached handler, reset it
while (next!=null) {
next.reset(this, con);
next = next.getNext();
}
+ }catch(Exception x) {
+ SQLException sx = new SQLException("Unable to reset interceptor
chain.");
+ sx.initCause(x);
+ throw sx;
}
// setup statement proxy
if (getPoolProperties().getUseStatementFacade()) {
diff --git
a/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/InterceptorResetOrderTest.java
b/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/InterceptorResetOrderTest.java
new file mode 100644
index 0000000000..a4824702cf
--- /dev/null
+++
b/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/InterceptorResetOrderTest.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.jdbc.test;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.apache.tomcat.jdbc.pool.ConnectionPool;
+import org.apache.tomcat.jdbc.pool.JdbcInterceptor;
+import org.apache.tomcat.jdbc.pool.PooledConnection;
+import org.apache.tomcat.jdbc.test.driver.Driver;
+
+/**
+ * The reset order of the interceptors must follow the order in which they are
declared, whether the connection is new
+ * or is taken from the pool.
+ */
+public class InterceptorResetOrderTest extends DefaultTestCase {
+
+ private static final List<String> RESETS =
Collections.synchronizedList(new ArrayList<>());
+
+ @Before
+ public void setUp() {
+ RESETS.clear();
+ datasource.setDriverClassName(Driver.class.getName());
+ datasource.setUrl("jdbc:tomcat:test");
+ datasource.setMaxActive(1);
+ datasource.setInitialSize(0);
+ datasource.setMinIdle(0);
+ datasource.setJdbcInterceptors(First.class.getName() + ";" +
Second.class.getName());
+ }
+
+ @Test
+ public void testResetOrderOnNewConnection() throws SQLException {
+ datasource.getConnection().close();
+ Assert.assertEquals(Arrays.asList("first", "second"), RESETS);
+ }
+
+ @Test
+ public void testResetOrderOnReusedConnection() throws SQLException {
+ datasource.getConnection().close();
+ RESETS.clear();
+ datasource.getConnection().close();
+ Assert.assertEquals(Arrays.asList("first", "second"), RESETS);
+ }
+
+ @Test
+ public void testResetFailureIsReportedAsSQLException() {
+ datasource.setJdbcInterceptors(Failing.class.getName());
+
+ SQLException e = Assert.assertThrows(SQLException.class, () ->
datasource.getConnection());
+
+ Assert.assertTrue(e.getCause() instanceof IllegalStateException);
+ }
+
+ public static class Failing extends JdbcInterceptor {
+
+ @Override
+ public void reset(ConnectionPool parent, PooledConnection con) {
+ if (parent != null) {
+ throw new IllegalStateException();
+ }
+ }
+ }
+
+ public static class First extends JdbcInterceptor {
+
+ @Override
+ public void reset(ConnectionPool parent, PooledConnection con) {
+ // the pool also resets interceptors without a parent when a
connection is discarded
+ if (parent != null) {
+ RESETS.add("first");
+ }
+ }
+ }
+
+ public static class Second extends JdbcInterceptor {
+
+ @Override
+ public void reset(ConnectionPool parent, PooledConnection con) {
+ if (parent != null) {
+ RESETS.add("second");
+ }
+ }
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]