@@ -1330,7 +1330,7 @@ void testProxyStatement() throws Exception {
13301330 cleanup .deferCleanup (statement );
13311331 cleanup .deferCleanup (connection );
13321332
1333- Statement proxyStatement = ProxyStatementFactory .proxyStatement (statement );
1333+ Statement proxyStatement = ProxyStatementFactory .proxyStatementWithCustomClassLoader (statement );
13341334 ResultSet resultSet =
13351335 testing .runWithSpan ("parent" , () -> proxyStatement .executeQuery ("SELECT 3" ));
13361336
@@ -1737,4 +1737,100 @@ static Stream<Arguments> transactionOperationsStream() throws SQLException {
17371737 Arguments .of (
17381738 "hsqldb" , new JDBCDriver ().connect (jdbcUrls .get ("hsqldb" ), null ), "SA" , "hsqldb:mem:" ));
17391739 }
1740+
1741+ private static PreparedStatement wrapPreparedStatement (PreparedStatement statement ) {
1742+ return ProxyStatementFactory .proxyPreparedStatement (
1743+ (proxy , method , args ) -> {
1744+ if ("isWrapperFor" .equals (method .getName ())
1745+ && args .length == 1
1746+ && args [0 ] == PreparedStatement .class ) {
1747+ return true ;
1748+ }
1749+ if ("unwrap" .equals (method .getName ())
1750+ && args .length == 1
1751+ && args [0 ] == PreparedStatement .class ) {
1752+ return statement ;
1753+ }
1754+ return testing .runWithSpan ("wrapper" , () -> method .invoke (statement , args ));
1755+ });
1756+ }
1757+
1758+ // test that tracing does not start from a wrapper
1759+ // regression test for
1760+ // https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/14733
1761+ @ Test
1762+ void testPreparedStatementWrapper () throws SQLException {
1763+ Connection connection = new org .h2 .Driver ().connect (jdbcUrls .get ("h2" ), null );
1764+ Connection proxyConnection =
1765+ ProxyStatementFactory .proxy (
1766+ Connection .class ,
1767+ (proxy , method , args ) -> {
1768+ // we don't implement unwrapping here as that would also cause the executeQuery
1769+ // instrumentation to get skipped for the prepared statement wrapper
1770+ if ("prepareStatement" .equals (method .getName ())) {
1771+ return wrapPreparedStatement ((PreparedStatement ) method .invoke (connection , args ));
1772+ }
1773+ return method .invoke (connection , args );
1774+ });
1775+ PreparedStatement statement = proxyConnection .prepareStatement ("SELECT 3" );
1776+ cleanup .deferCleanup (statement );
1777+ cleanup .deferCleanup (connection );
1778+
1779+ ResultSet resultSet = testing .runWithSpan ("parent" , () -> statement .executeQuery ());
1780+
1781+ resultSet .next ();
1782+ assertThat (resultSet .getInt (1 )).isEqualTo (3 );
1783+ testing .waitAndAssertTraces (
1784+ trace ->
1785+ trace .hasSpansSatisfyingExactly (
1786+ span -> span .hasName ("parent" ).hasKind (SpanKind .INTERNAL ).hasNoParent (),
1787+ span ->
1788+ span .hasName ("wrapper" ).hasKind (SpanKind .INTERNAL ).hasParent (trace .getSpan (0 )),
1789+ span ->
1790+ span .hasName ("SELECT " + dbNameLower )
1791+ .hasKind (SpanKind .CLIENT )
1792+ .hasParent (trace .getSpan (1 ))));
1793+ }
1794+
1795+ // test that tracing does not start from a wrapper
1796+ // regression test for
1797+ // https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/14733
1798+ @ Test
1799+ void testStatementWrapper () throws SQLException {
1800+ Connection connection = new org .h2 .Driver ().connect (jdbcUrls .get ("h2" ), null );
1801+ Statement statement = connection .createStatement ();
1802+ cleanup .deferCleanup (statement );
1803+ cleanup .deferCleanup (connection );
1804+
1805+ Statement proxyStatement =
1806+ ProxyStatementFactory .proxyStatement (
1807+ (proxy , method , args ) -> {
1808+ if ("isWrapperFor" .equals (method .getName ())
1809+ && args .length == 1
1810+ && args [0 ] == Statement .class ) {
1811+ return true ;
1812+ }
1813+ if ("unwrap" .equals (method .getName ())
1814+ && args .length == 1
1815+ && args [0 ] == Statement .class ) {
1816+ return statement ;
1817+ }
1818+ return testing .runWithSpan ("wrapper" , () -> method .invoke (statement , args ));
1819+ });
1820+ ResultSet resultSet =
1821+ testing .runWithSpan ("parent" , () -> proxyStatement .executeQuery ("SELECT 3" ));
1822+
1823+ resultSet .next ();
1824+ assertThat (resultSet .getInt (1 )).isEqualTo (3 );
1825+ testing .waitAndAssertTraces (
1826+ trace ->
1827+ trace .hasSpansSatisfyingExactly (
1828+ span -> span .hasName ("parent" ).hasKind (SpanKind .INTERNAL ).hasNoParent (),
1829+ span ->
1830+ span .hasName ("wrapper" ).hasKind (SpanKind .INTERNAL ).hasParent (trace .getSpan (0 )),
1831+ span ->
1832+ span .hasName ("SELECT " + dbNameLower )
1833+ .hasKind (SpanKind .CLIENT )
1834+ .hasParent (trace .getSpan (1 ))));
1835+ }
17401836}
0 commit comments