From 5a86ea9a8bed209b15e520a4b25e7546f0087460 Mon Sep 17 00:00:00 2001 From: Gareth Edwards - TASS <113149910+garethedwards-tass@users.noreply.github.com> Date: Thu, 10 Jul 2025 14:26:35 +1000 Subject: [PATCH 1/5] 14218 - Add setObject to advice for java.sql.PreparedStatement --- .../jdbc/PreparedStatementInstrumentation.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/instrumentation/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/PreparedStatementInstrumentation.java b/instrumentation/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/PreparedStatementInstrumentation.java index 38fad89aa090..9f9af2222d42 100644 --- a/instrumentation/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/PreparedStatementInstrumentation.java +++ b/instrumentation/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/PreparedStatementInstrumentation.java @@ -77,7 +77,8 @@ public void transform(TypeTransformer transformer) { "setTimestamp", "setURL", "setRowId", - "setNString") + "setNString", + "setObject") .and(takesArgument(0, int.class)) .and(takesArguments(2)) .and(isPublic()), @@ -89,6 +90,13 @@ public void transform(TypeTransformer transformer) { .and(takesArguments(3)) .and(isPublic()), PreparedStatementInstrumentation.class.getName() + "$SetTimeParameter3Advice"); + transformer.applyAdviceToMethod( + namedOneOf("setObject") + .and(takesArgument(0, int.class)) + .and(takesArgument(2, int.class)) + .and(takesArguments(3)) + .and(isPublic()), + PreparedStatementInstrumentation.class.getName() + "$SetParameter2Advice"); transformer.applyAdviceToMethod( named("clearParameters").and(takesNoArguments()).and(isPublic()), PreparedStatementInstrumentation.class.getName() + "$ClearParametersAdvice"); From bac4cfda50e13b18a7c1af71580d0d9bf3e420a2 Mon Sep 17 00:00:00 2001 From: Gareth Edwards Date: Thu, 10 Jul 2025 18:03:03 +1000 Subject: [PATCH 2/5] Add tests for setObject --- .../test/PreparedStatementParametersTest.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/instrumentation/jdbc/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jdbc/test/PreparedStatementParametersTest.java b/instrumentation/jdbc/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jdbc/test/PreparedStatementParametersTest.java index fc5db502d82d..b9e622ff7fe2 100644 --- a/instrumentation/jdbc/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jdbc/test/PreparedStatementParametersTest.java +++ b/instrumentation/jdbc/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jdbc/test/PreparedStatementParametersTest.java @@ -28,6 +28,7 @@ import java.math.BigDecimal; import java.sql.Connection; import java.sql.Date; +import java.sql.JDBCType; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @@ -306,6 +307,56 @@ void testStringPreparedStatementParameter( "S"); } + @ParameterizedTest + @MethodSource("preparedStatementStream") + void testObjectPreparedStatementParameter( + String system, + Connection connection, + String username, + String query, + String sanitizedQuery, + String spanName, + String url, + String table) + throws SQLException { + test( + system, + connection, + username, + query, + sanitizedQuery, + spanName, + url, + table, + statement -> statement.setObject(1, "S"), + "S"); + } + + @ParameterizedTest + @MethodSource("preparedStatementStream") + void testObjectWithTypePreparedStatementParameter( + String system, + Connection connection, + String username, + String query, + String sanitizedQuery, + String spanName, + String url, + String table) + throws SQLException { + test( + system, + connection, + username, + query, + sanitizedQuery, + spanName, + url, + table, + statement -> statement.setObject(1, "S", JDBCType.CHAR), + "S"); + } + @ParameterizedTest @MethodSource("preparedStatementStream") void testDate2PreparedStatementParameter( From 0dd43981dd863c3d8c59e2d364206f0cb34f8424 Mon Sep 17 00:00:00 2001 From: Gareth Edwards Date: Thu, 10 Jul 2025 21:49:01 +1000 Subject: [PATCH 3/5] Fix java.sqlTypes and setObject tests --- .../PreparedStatementInstrumentation.java | 34 ++++++++++++++++++- .../test/PreparedStatementParametersTest.java | 4 +-- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/instrumentation/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/PreparedStatementInstrumentation.java b/instrumentation/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/PreparedStatementInstrumentation.java index 9f9af2222d42..ea0ec5302c23 100644 --- a/instrumentation/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/PreparedStatementInstrumentation.java +++ b/instrumentation/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/PreparedStatementInstrumentation.java @@ -96,7 +96,7 @@ public void transform(TypeTransformer transformer) { .and(takesArgument(2, int.class)) .and(takesArguments(3)) .and(isPublic()), - PreparedStatementInstrumentation.class.getName() + "$SetParameter2Advice"); + PreparedStatementInstrumentation.class.getName() + "$SetParameter3Advice"); transformer.applyAdviceToMethod( named("clearParameters").and(takesNoArguments()).and(isPublic()), PreparedStatementInstrumentation.class.getName() + "$ClearParametersAdvice"); @@ -200,6 +200,38 @@ public static void onExit( } } + @SuppressWarnings("unused") + public static class SetParameter3Advice { + @Advice.OnMethodExit(suppress = Throwable.class) + public static void onExit( + @Advice.This PreparedStatement statement, + @Advice.Argument(0) int index, + @Advice.Argument(1) Object value, + @Advice.Argument(2) int targetSqlType) { + if (!CAPTURE_QUERY_PARAMETERS) { + return; + } + + String str = null; + + if (value instanceof Boolean + // Short, Int, Long, Float, Double, BigDecimal + || value instanceof Number + || value instanceof String + || value instanceof Date + || value instanceof Time + || value instanceof Timestamp + || value instanceof URL + || value instanceof RowId) { + str = value.toString(); + } + + if (str != null) { + JdbcData.addParameter(statement, Integer.toString(index - 1), str); + } + } + } + @SuppressWarnings("unused") public static class SetTimeParameter3Advice { @Advice.OnMethodExit(suppress = Throwable.class) diff --git a/instrumentation/jdbc/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jdbc/test/PreparedStatementParametersTest.java b/instrumentation/jdbc/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jdbc/test/PreparedStatementParametersTest.java index b9e622ff7fe2..570bbb8df8bf 100644 --- a/instrumentation/jdbc/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jdbc/test/PreparedStatementParametersTest.java +++ b/instrumentation/jdbc/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jdbc/test/PreparedStatementParametersTest.java @@ -28,7 +28,7 @@ import java.math.BigDecimal; import java.sql.Connection; import java.sql.Date; -import java.sql.JDBCType; +import java.sql.Types; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @@ -353,7 +353,7 @@ void testObjectWithTypePreparedStatementParameter( spanName, url, table, - statement -> statement.setObject(1, "S", JDBCType.CHAR), + statement -> statement.setObject(1, "S", Types.CHAR), "S"); } From 25b748365769ba916075bc00727b7da060985e88 Mon Sep 17 00:00:00 2001 From: Gareth Edwards Date: Thu, 10 Jul 2025 21:54:03 +1000 Subject: [PATCH 4/5] Spotless fix --- .../jdbc/test/PreparedStatementParametersTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/jdbc/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jdbc/test/PreparedStatementParametersTest.java b/instrumentation/jdbc/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jdbc/test/PreparedStatementParametersTest.java index 570bbb8df8bf..26d78cdc5f6b 100644 --- a/instrumentation/jdbc/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jdbc/test/PreparedStatementParametersTest.java +++ b/instrumentation/jdbc/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jdbc/test/PreparedStatementParametersTest.java @@ -28,12 +28,12 @@ import java.math.BigDecimal; import java.sql.Connection; import java.sql.Date; -import java.sql.Types; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Time; import java.sql.Timestamp; +import java.sql.Types; import java.util.Calendar; import java.util.Locale; import java.util.Map; From e00368d5a8475b5a032a97c76e4d44d12874a3f0 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Thu, 10 Jul 2025 15:54:53 +0300 Subject: [PATCH 5/5] run test only with latest deps --- instrumentation/jdbc/javaagent/build.gradle.kts | 1 + .../jdbc/test/PreparedStatementParametersTest.java | 3 +++ 2 files changed, 4 insertions(+) diff --git a/instrumentation/jdbc/javaagent/build.gradle.kts b/instrumentation/jdbc/javaagent/build.gradle.kts index 213dc1718f55..894616e9cf9e 100644 --- a/instrumentation/jdbc/javaagent/build.gradle.kts +++ b/instrumentation/jdbc/javaagent/build.gradle.kts @@ -104,6 +104,7 @@ tasks { tasks { withType().configureEach { + systemProperty("testLatestDeps", findProperty("testLatestDeps") as Boolean) jvmArgs("-Dotel.instrumentation.jdbc.experimental.transaction.enabled=true") } } diff --git a/instrumentation/jdbc/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jdbc/test/PreparedStatementParametersTest.java b/instrumentation/jdbc/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jdbc/test/PreparedStatementParametersTest.java index 26d78cdc5f6b..6af380167147 100644 --- a/instrumentation/jdbc/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jdbc/test/PreparedStatementParametersTest.java +++ b/instrumentation/jdbc/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jdbc/test/PreparedStatementParametersTest.java @@ -344,6 +344,9 @@ void testObjectWithTypePreparedStatementParameter( String url, String table) throws SQLException { + // we are using old database drivers that don't support the tested setObject method + Assumptions.assumeTrue(Boolean.getBoolean("testLatestDeps")); + test( system, connection,