This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 10.1.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/10.1.x by this push: new cfbaea4704 Unwrap InvocationTargetException from underlying statement execution cfbaea4704 is described below commit cfbaea4704474b2883214197a2634a0fec2c2a74 Author: Michael Clarke <mcla...@apache.org> AuthorDate: Thu Aug 8 20:26:58 2024 +0100 Unwrap InvocationTargetException from underlying statement execution When executing a wrapped statement, any resulting SQLException is wrapped in an InvocationTargetException by the reflective invocation, which is rethrown by the InvocationHandler as an UndeclaredThrowableException. To ensure the expected SQLException is thrown, the invocation of the wrapped object is being moved into the existing try-catch block, thereby ensuring the InvocationTargetException is unwrapped and the underlying exception thrown by the handler. --- .../apache/tomcat/jdbc/pool/StatementFacade.java | 28 ++++++++++---------- .../tomcat/jdbc/test/ProxiedStatementTest.java | 30 ++++++++++++++++++++++ .../apache/tomcat/jdbc/test/driver/Connection.java | 2 +- .../apache/tomcat/jdbc/test/driver/Statement.java | 22 +++++++++++++++- webapps/docs/changelog.xml | 11 ++++++++ 5 files changed, 77 insertions(+), 16 deletions(-) diff --git a/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/StatementFacade.java b/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/StatementFacade.java index e9cae3a734..ea32d619c5 100644 --- a/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/StatementFacade.java +++ b/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/StatementFacade.java @@ -117,21 +117,21 @@ public class StatementFacade extends AbstractCreateStatementInterceptor { throw new SQLException("Statement closed."); } - if (compare(GET_RESULTSET, method)) { - return getConstructor(RESULTSET_IDX, ResultSet.class) - .newInstance(new ResultSetProxy(method.invoke(delegate, args), proxy)); - } - if (compare(GET_GENERATED_KEYS, method)) { - return getConstructor(RESULTSET_IDX, ResultSet.class) - .newInstance(new ResultSetProxy(method.invoke(delegate, args), proxy)); - } - if (compare(EXECUTE_QUERY, method)) { - return getConstructor(RESULTSET_IDX, ResultSet.class) - .newInstance(new ResultSetProxy(method.invoke(delegate, args), proxy)); - } - - Object result = null; + Object result; try { + if (compare(GET_RESULTSET, method)) { + return getConstructor(RESULTSET_IDX, ResultSet.class) + .newInstance(new ResultSetProxy(method.invoke(delegate, args), proxy)); + } + if (compare(GET_GENERATED_KEYS, method)) { + return getConstructor(RESULTSET_IDX, ResultSet.class) + .newInstance(new ResultSetProxy(method.invoke(delegate, args), proxy)); + } + if (compare(EXECUTE_QUERY, method)) { + return getConstructor(RESULTSET_IDX, ResultSet.class) + .newInstance(new ResultSetProxy(method.invoke(delegate, args), proxy)); + } + // invoke next result = method.invoke(delegate, args); } catch (Throwable t) { diff --git a/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/ProxiedStatementTest.java b/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/ProxiedStatementTest.java index 2c76115c06..0f07663b0e 100644 --- a/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/ProxiedStatementTest.java +++ b/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/ProxiedStatementTest.java @@ -58,4 +58,34 @@ public class ProxiedStatementTest extends DefaultTestCase { Assert.assertNotEquals(statement, new org.apache.tomcat.jdbc.test.driver.Statement()); } } + + @Test + public void shouldUnwrapInvocationTargetExceptionFromGetResultSet() throws SQLException { + this.datasource.setDriverClassName(Driver.class.getName()); + this.datasource.setUrl("jdbc:tomcat:test"); + try (Connection con = this.datasource.getConnection(); + Statement statement = con.prepareStatement("sql", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT)) { + Assert.assertThrows("Throwing exception on execute", SQLException.class, statement::getResultSet); + } + } + + @Test + public void shouldUnwrapInvocationTargetExceptionFromExecute() throws SQLException { + this.datasource.setDriverClassName(Driver.class.getName()); + this.datasource.setUrl("jdbc:tomcat:test"); + try (Connection con = this.datasource.getConnection(); + Statement statement = con.prepareStatement("sql", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT)) { + Assert.assertThrows("Throwing exception on execute", SQLException.class, () -> statement.executeQuery("")); + } + } + + @Test + public void shouldUnwrapInvocationTargetExceptionFromGetGeneratedKeys() throws SQLException { + this.datasource.setDriverClassName(Driver.class.getName()); + this.datasource.setUrl("jdbc:tomcat:test"); + try (Connection con = this.datasource.getConnection(); + Statement statement = con.prepareStatement("sql", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT)) { + Assert.assertThrows("Throwing exception on execute", SQLException.class, statement::getGeneratedKeys); + } + } } diff --git a/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/driver/Connection.java b/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/driver/Connection.java index 2c614e74a1..55ca60acff 100644 --- a/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/driver/Connection.java +++ b/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/driver/Connection.java @@ -218,7 +218,7 @@ public class Connection implements java.sql.Connection { @Override public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { - return new org.apache.tomcat.jdbc.test.driver.Statement(); + return new org.apache.tomcat.jdbc.test.driver.Statement(true); } @Override diff --git a/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/driver/Statement.java b/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/driver/Statement.java index d5a8e8ead6..16572487cb 100644 --- a/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/driver/Statement.java +++ b/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/driver/Statement.java @@ -41,7 +41,18 @@ import java.util.Calendar; import java.util.Map; public class Statement implements CallableStatement { - int timeout=-1; + + private boolean throwExceptionOnExecute = false; + private int timeout=-1; + + public Statement() { + this(false); + } + + public Statement(boolean throwExceptionOnExecute) { + this.throwExceptionOnExecute = throwExceptionOnExecute; + } + @Override public Array getArray(int parameterIndex) throws SQLException { // TODO Auto-generated method stub @@ -1099,6 +1110,9 @@ public class Statement implements CallableStatement { @Override public ResultSet executeQuery(String sql) throws SQLException { + if (throwExceptionOnExecute) { + throw new SQLException("Throwing exception on execute"); + } return new org.apache.tomcat.jdbc.test.driver.ResultSet(this); } @@ -1146,6 +1160,9 @@ public class Statement implements CallableStatement { @Override public ResultSet getGeneratedKeys() throws SQLException { + if (throwExceptionOnExecute) { + throw new SQLException("Throwing exception on execute"); + } return new org.apache.tomcat.jdbc.test.driver.ResultSet(this); } @@ -1180,6 +1197,9 @@ public class Statement implements CallableStatement { @Override public ResultSet getResultSet() throws SQLException { + if (throwExceptionOnExecute) { + throw new SQLException("Throwing exception on execute"); + } return new org.apache.tomcat.jdbc.test.driver.ResultSet(this); } diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 2bf7fccf50..12668d0383 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -135,6 +135,17 @@ </fix> </changelog> </subsection> + <subsection name="jdbc-pool"> + <changelog> + <fix> + <bug>69255</bug>: Correct a regression in the fix for <bug>69206</bug> + that meant exceptions executing statements were wrapped in an + <code>java.lang.reflect.UndeclaredThrowableException</code> rather than + the applicaiton seeing the original <code>SQLException</code>. Fixed + by pull request <pr>744</pr> provided by Michael Clarke. (markt) + </fix> + </changelog> + </subsection> <subsection name="Other"> <changelog> <add> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org