From eae2f255ebc82ceb7beb83afe7ac4d0153d55296 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 14 Nov 2025 19:18:42 +0100 Subject: [PATCH 1/8] debug native image fail --- .../DefaultHttpClientInstrumenterBuilder.java | 3 ++ .../HttpExperimentalAttributesExtractor.java | 6 +++ .../v3_1/SpringWebHttpAttributesGetter.java | 4 ++ .../spring-web-3.1/reflect-config.json | 42 +++++++++++++++++++ .../spring-webflux-5.3/reflect-config.json | 11 +++++ mise.toml | 1 + 6 files changed, 67 insertions(+) create mode 100644 instrumentation/spring/spring-web/spring-web-3.1/library/src/main/resources/META-INF/native-image/io.opentelemetry.instrumentation/spring-web-3.1/reflect-config.json create mode 100644 instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/resources/META-INF/native-image/io.opentelemetry.instrumentation/spring-webflux-5.3/reflect-config.json diff --git a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/builder/internal/DefaultHttpClientInstrumenterBuilder.java b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/builder/internal/DefaultHttpClientInstrumenterBuilder.java index ae11d99892be..bef3851ef165 100644 --- a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/builder/internal/DefaultHttpClientInstrumenterBuilder.java +++ b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/builder/internal/DefaultHttpClientInstrumenterBuilder.java @@ -174,6 +174,9 @@ public DefaultHttpClientInstrumenterBuilder setKnownMethods( @CanIgnoreReturnValue public DefaultHttpClientInstrumenterBuilder setEmitExperimentalHttpClientTelemetry(boolean emitExperimentalHttpClientTelemetry) { + if (emitExperimentalHttpClientTelemetry) { + System.out.println("Experimental HTTP client telemetry is enabled."); + } this.emitExperimentalHttpClientTelemetry = emitExperimentalHttpClientTelemetry; return this; } diff --git a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/http/HttpExperimentalAttributesExtractor.java b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/http/HttpExperimentalAttributesExtractor.java index 4ee1fe09a319..9ff2e5468aca 100644 --- a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/http/HttpExperimentalAttributesExtractor.java +++ b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/http/HttpExperimentalAttributesExtractor.java @@ -60,8 +60,14 @@ public void onEnd( Long requestBodySize = requestBodySize(request); internalSet(attributes, HTTP_REQUEST_BODY_SIZE, requestBodySize); + System.out.println("HttpExperimentalAttributesExtractor - onEnd - response: " + response); + if (response != null) { Long responseBodySize = responseBodySize(request, response); + + System.out.println( + "HttpExperimentalAttributesExtractor - onEnd - responseBodySize: " + responseBodySize); + internalSet(attributes, HTTP_RESPONSE_BODY_SIZE, responseBodySize); } diff --git a/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java b/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java index 9f5446e510e4..802dc782367e 100644 --- a/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java +++ b/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java @@ -68,6 +68,8 @@ enum SpringWebHttpAttributesGetter findGetHeadersMethod(MethodType.methodType(Object.class, Object.class, Object.class)); } GET_HEADERS = methodHandle; + + System.out.println("Get headers " + GET_HEADERS); } private static MethodHandle findGetHeadersMethod(MethodType methodType) { @@ -100,6 +102,8 @@ private static List getHeader(HttpHeaders headers, String name) { try { return (List) GET_HEADERS.invoke(headers, name, emptyList()); } catch (Throwable t) { + System.out.println("error getting headers " + t.getMessage()); + t.printStackTrace(); // ignore } } diff --git a/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/resources/META-INF/native-image/io.opentelemetry.instrumentation/spring-web-3.1/reflect-config.json b/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/resources/META-INF/native-image/io.opentelemetry.instrumentation/spring-web-3.1/reflect-config.json new file mode 100644 index 000000000000..7d27a372a0e5 --- /dev/null +++ b/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/resources/META-INF/native-image/io.opentelemetry.instrumentation/spring-web-3.1/reflect-config.json @@ -0,0 +1,42 @@ +[ + { + "name": "org.springframework.http.client.ClientHttpResponse", + "methods": [ + { + "name": "getStatusCode", + "parameterTypes": [] + } + ] + }, + { + "name": "org.springframework.http.HttpStatusCode", + "methods": [ + { + "name": "value", + "parameterTypes": [] + } + ] + }, + { + "name": "org.springframework.http.HttpStatus", + "methods": [ + { + "name": "value", + "parameterTypes": [] + } + ] + }, + { + "name": "java.util.Map", + "methods": [ + { + "name": "getOrDefault", + "parameterTypes": ["java.lang.String", "java.util.List"] + }, + { + "name": "getOrDefault", + "parameterTypes": ["java.lang.Object", "java.lang.Object"] + } + ] + } +] diff --git a/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/resources/META-INF/native-image/io.opentelemetry.instrumentation/spring-webflux-5.3/reflect-config.json b/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/resources/META-INF/native-image/io.opentelemetry.instrumentation/spring-webflux-5.3/reflect-config.json new file mode 100644 index 000000000000..008c25c2773f --- /dev/null +++ b/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/resources/META-INF/native-image/io.opentelemetry.instrumentation/spring-webflux-5.3/reflect-config.json @@ -0,0 +1,11 @@ +[ + { + "name": "org.springframework.web.reactive.function.client.ClientResponse", + "methods": [ + { + "name": "todo", + "parameterTypes": [] + } + ] + } +] diff --git a/mise.toml b/mise.toml index dd36de16dbfe..a99aabd9a834 100644 --- a/mise.toml +++ b/mise.toml @@ -1,4 +1,5 @@ [tools] +java = "graalvm-community-25.0.0" lychee = "0.21.0" [settings] From 894b326af5a025d4be96b1d3c9b149adeb416b7e Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 14 Nov 2025 21:27:22 +0100 Subject: [PATCH 2/8] fix --- .../web/v3_1/SpringWebHttpAttributesGetter.java | 12 ++++++++---- .../spring-web-3.1/reflect-config.json | 13 +++++++++++-- mise.toml | 2 +- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java b/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java index 802dc782367e..4a5fa1f4c579 100644 --- a/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java +++ b/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java @@ -61,11 +61,11 @@ enum SpringWebHttpAttributesGetter // since spring web 7.0 MethodHandle methodHandle = - findGetHeadersMethod(MethodType.methodType(List.class, String.class, List.class)); + findGetHeadersMethod(MethodType.methodType(List.class, String.class)); if (methodHandle == null) { // up to spring web 7.0 methodHandle = - findGetHeadersMethod(MethodType.methodType(Object.class, Object.class, Object.class)); + findGetHeadersMethod(MethodType.methodType(List.class, Object.class)); } GET_HEADERS = methodHandle; @@ -74,7 +74,7 @@ enum SpringWebHttpAttributesGetter private static MethodHandle findGetHeadersMethod(MethodType methodType) { try { - return MethodHandles.lookup().findVirtual(HttpHeaders.class, "getOrDefault", methodType); + return MethodHandles.lookup().findVirtual(HttpHeaders.class, "get", methodType); } catch (Throwable t) { return null; } @@ -100,7 +100,11 @@ public List getHttpRequestHeader(HttpRequest httpRequest, String name) { private static List getHeader(HttpHeaders headers, String name) { if (GET_HEADERS != null) { try { - return (List) GET_HEADERS.invoke(headers, name, emptyList()); + List result = (List) GET_HEADERS.invoke(headers, name); + if (result == null) { + return emptyList(); + } + return result; } catch (Throwable t) { System.out.println("error getting headers " + t.getMessage()); t.printStackTrace(); diff --git a/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/resources/META-INF/native-image/io.opentelemetry.instrumentation/spring-web-3.1/reflect-config.json b/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/resources/META-INF/native-image/io.opentelemetry.instrumentation/spring-web-3.1/reflect-config.json index 7d27a372a0e5..90a693eb01d2 100644 --- a/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/resources/META-INF/native-image/io.opentelemetry.instrumentation/spring-web-3.1/reflect-config.json +++ b/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/resources/META-INF/native-image/io.opentelemetry.instrumentation/spring-web-3.1/reflect-config.json @@ -31,11 +31,20 @@ "methods": [ { "name": "getOrDefault", - "parameterTypes": ["java.lang.String", "java.util.List"] + "parameterTypes": ["java.lang.Object", "java.lang.Object"] + } + ] + }, + { + "name": "org.springframework.http.HttpHeaders", + "methods": [ + { + "name": "get", + "parameterTypes": ["java.lang.Object"] }, { "name": "getOrDefault", - "parameterTypes": ["java.lang.Object", "java.lang.Object"] + "parameterTypes": ["java.lang.String", "java.util.List"] } ] } diff --git a/mise.toml b/mise.toml index a99aabd9a834..1a890e277cae 100644 --- a/mise.toml +++ b/mise.toml @@ -1,5 +1,5 @@ [tools] -java = "graalvm-community-25.0.0" +java = "graalvm-community-25.0.1" lychee = "0.21.0" [settings] From d79c790a2a372df4597a31859d59fad74ba223f6 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 14 Nov 2025 21:30:03 +0100 Subject: [PATCH 3/8] fix --- .../spring-web-3.1/reflect-config.json | 51 ------------------- 1 file changed, 51 deletions(-) delete mode 100644 instrumentation/spring/spring-web/spring-web-3.1/library/src/main/resources/META-INF/native-image/io.opentelemetry.instrumentation/spring-web-3.1/reflect-config.json diff --git a/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/resources/META-INF/native-image/io.opentelemetry.instrumentation/spring-web-3.1/reflect-config.json b/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/resources/META-INF/native-image/io.opentelemetry.instrumentation/spring-web-3.1/reflect-config.json deleted file mode 100644 index 90a693eb01d2..000000000000 --- a/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/resources/META-INF/native-image/io.opentelemetry.instrumentation/spring-web-3.1/reflect-config.json +++ /dev/null @@ -1,51 +0,0 @@ -[ - { - "name": "org.springframework.http.client.ClientHttpResponse", - "methods": [ - { - "name": "getStatusCode", - "parameterTypes": [] - } - ] - }, - { - "name": "org.springframework.http.HttpStatusCode", - "methods": [ - { - "name": "value", - "parameterTypes": [] - } - ] - }, - { - "name": "org.springframework.http.HttpStatus", - "methods": [ - { - "name": "value", - "parameterTypes": [] - } - ] - }, - { - "name": "java.util.Map", - "methods": [ - { - "name": "getOrDefault", - "parameterTypes": ["java.lang.Object", "java.lang.Object"] - } - ] - }, - { - "name": "org.springframework.http.HttpHeaders", - "methods": [ - { - "name": "get", - "parameterTypes": ["java.lang.Object"] - }, - { - "name": "getOrDefault", - "parameterTypes": ["java.lang.String", "java.util.List"] - } - ] - } -] From 1f986c16c79222a4a635e0037ab2712ef7723b2c Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 14 Nov 2025 21:32:00 +0100 Subject: [PATCH 4/8] cleanup --- .../DefaultHttpClientInstrumenterBuilder.java | 3 --- .../http/HttpExperimentalAttributesExtractor.java | 6 ------ .../web/v3_1/SpringWebHttpAttributesGetter.java | 4 ---- .../spring-webflux-5.3/reflect-config.json | 11 ----------- mise.toml | 1 - 5 files changed, 25 deletions(-) delete mode 100644 instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/resources/META-INF/native-image/io.opentelemetry.instrumentation/spring-webflux-5.3/reflect-config.json diff --git a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/builder/internal/DefaultHttpClientInstrumenterBuilder.java b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/builder/internal/DefaultHttpClientInstrumenterBuilder.java index bef3851ef165..ae11d99892be 100644 --- a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/builder/internal/DefaultHttpClientInstrumenterBuilder.java +++ b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/builder/internal/DefaultHttpClientInstrumenterBuilder.java @@ -174,9 +174,6 @@ public DefaultHttpClientInstrumenterBuilder setKnownMethods( @CanIgnoreReturnValue public DefaultHttpClientInstrumenterBuilder setEmitExperimentalHttpClientTelemetry(boolean emitExperimentalHttpClientTelemetry) { - if (emitExperimentalHttpClientTelemetry) { - System.out.println("Experimental HTTP client telemetry is enabled."); - } this.emitExperimentalHttpClientTelemetry = emitExperimentalHttpClientTelemetry; return this; } diff --git a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/http/HttpExperimentalAttributesExtractor.java b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/http/HttpExperimentalAttributesExtractor.java index 9ff2e5468aca..4ee1fe09a319 100644 --- a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/http/HttpExperimentalAttributesExtractor.java +++ b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/semconv/http/HttpExperimentalAttributesExtractor.java @@ -60,14 +60,8 @@ public void onEnd( Long requestBodySize = requestBodySize(request); internalSet(attributes, HTTP_REQUEST_BODY_SIZE, requestBodySize); - System.out.println("HttpExperimentalAttributesExtractor - onEnd - response: " + response); - if (response != null) { Long responseBodySize = responseBodySize(request, response); - - System.out.println( - "HttpExperimentalAttributesExtractor - onEnd - responseBodySize: " + responseBodySize); - internalSet(attributes, HTTP_RESPONSE_BODY_SIZE, responseBodySize); } diff --git a/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java b/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java index 4a5fa1f4c579..aef7affc67f0 100644 --- a/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java +++ b/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java @@ -68,8 +68,6 @@ enum SpringWebHttpAttributesGetter findGetHeadersMethod(MethodType.methodType(List.class, Object.class)); } GET_HEADERS = methodHandle; - - System.out.println("Get headers " + GET_HEADERS); } private static MethodHandle findGetHeadersMethod(MethodType methodType) { @@ -106,8 +104,6 @@ private static List getHeader(HttpHeaders headers, String name) { } return result; } catch (Throwable t) { - System.out.println("error getting headers " + t.getMessage()); - t.printStackTrace(); // ignore } } diff --git a/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/resources/META-INF/native-image/io.opentelemetry.instrumentation/spring-webflux-5.3/reflect-config.json b/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/resources/META-INF/native-image/io.opentelemetry.instrumentation/spring-webflux-5.3/reflect-config.json deleted file mode 100644 index 008c25c2773f..000000000000 --- a/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/resources/META-INF/native-image/io.opentelemetry.instrumentation/spring-webflux-5.3/reflect-config.json +++ /dev/null @@ -1,11 +0,0 @@ -[ - { - "name": "org.springframework.web.reactive.function.client.ClientResponse", - "methods": [ - { - "name": "todo", - "parameterTypes": [] - } - ] - } -] diff --git a/mise.toml b/mise.toml index 1a890e277cae..dd36de16dbfe 100644 --- a/mise.toml +++ b/mise.toml @@ -1,5 +1,4 @@ [tools] -java = "graalvm-community-25.0.1" lychee = "0.21.0" [settings] From 1599e23d1263813a769007178cbb432cb73a5570 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 14 Nov 2025 21:37:44 +0100 Subject: [PATCH 5/8] fix --- .../spring/webflux/v5_3/HeaderUtil.java | 10 +++++++--- .../v5_3/internal/WebClientHttpAttributesGetter.java | 12 ++++++++---- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/HeaderUtil.java b/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/HeaderUtil.java index a1647d4f1526..e21772cdbc63 100644 --- a/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/HeaderUtil.java +++ b/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/HeaderUtil.java @@ -20,11 +20,11 @@ class HeaderUtil { static { // since spring web 7.0 MethodHandle methodHandle = - findGetHeadersMethod(MethodType.methodType(List.class, String.class, List.class)); + findGetHeadersMethod(MethodType.methodType(List.class, String.class)); if (methodHandle == null) { // up to spring web 7.0 methodHandle = - findGetHeadersMethod(MethodType.methodType(Object.class, Object.class, Object.class)); + findGetHeadersMethod(MethodType.methodType(List.class, Object.class)); } GET_HEADERS = methodHandle; } @@ -41,7 +41,11 @@ private static MethodHandle findGetHeadersMethod(MethodType methodType) { static List getHeader(HttpHeaders headers, String name) { if (GET_HEADERS != null) { try { - return (List) GET_HEADERS.invoke(headers, name, emptyList()); + List result = (List) GET_HEADERS.invoke(headers, name); + if (result == null) { + return emptyList(); + } + return result; } catch (Throwable t) { // ignore } diff --git a/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/internal/WebClientHttpAttributesGetter.java b/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/internal/WebClientHttpAttributesGetter.java index b8b61bf6e5e4..399f9b4da323 100644 --- a/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/internal/WebClientHttpAttributesGetter.java +++ b/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/internal/WebClientHttpAttributesGetter.java @@ -30,18 +30,18 @@ public enum WebClientHttpAttributesGetter static { // since webflux 7.0 MethodHandle methodHandle = - findGetHeadersMethod(MethodType.methodType(List.class, String.class, List.class)); + findGetHeadersMethod(MethodType.methodType(List.class, String.class)); if (methodHandle == null) { // up to webflux 7.0 methodHandle = - findGetHeadersMethod(MethodType.methodType(Object.class, Object.class, Object.class)); + findGetHeadersMethod(MethodType.methodType(List.class, Object.class)); } GET_HEADERS = methodHandle; } private static MethodHandle findGetHeadersMethod(MethodType methodType) { try { - return MethodHandles.lookup().findVirtual(HttpHeaders.class, "getOrDefault", methodType); + return MethodHandles.lookup().findVirtual(HttpHeaders.class, "get", methodType); } catch (Throwable t) { return null; } @@ -62,7 +62,11 @@ public String getHttpRequestMethod(ClientRequest request) { public List getHttpRequestHeader(ClientRequest request, String name) { if (GET_HEADERS != null) { try { - return (List) GET_HEADERS.invoke(request.headers(), name, emptyList()); + List result = (List) GET_HEADERS.invoke(request, name); + if (result == null) { + return emptyList(); + } + return result; } catch (Throwable t) { // ignore } From 5490492666b09c0247efcf9912397cb6d03465f2 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 14 Nov 2025 21:38:31 +0100 Subject: [PATCH 6/8] fix --- .../spring/web/v3_1/SpringWebHttpAttributesGetter.java | 3 +-- .../instrumentation/spring/webflux/v5_3/HeaderUtil.java | 3 +-- .../webflux/v5_3/internal/WebClientHttpAttributesGetter.java | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java b/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java index aef7affc67f0..b1822d1c10f1 100644 --- a/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java +++ b/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java @@ -64,8 +64,7 @@ enum SpringWebHttpAttributesGetter findGetHeadersMethod(MethodType.methodType(List.class, String.class)); if (methodHandle == null) { // up to spring web 7.0 - methodHandle = - findGetHeadersMethod(MethodType.methodType(List.class, Object.class)); + methodHandle = findGetHeadersMethod(MethodType.methodType(List.class, Object.class)); } GET_HEADERS = methodHandle; } diff --git a/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/HeaderUtil.java b/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/HeaderUtil.java index e21772cdbc63..cdd094a6dfe0 100644 --- a/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/HeaderUtil.java +++ b/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/HeaderUtil.java @@ -23,8 +23,7 @@ class HeaderUtil { findGetHeadersMethod(MethodType.methodType(List.class, String.class)); if (methodHandle == null) { // up to spring web 7.0 - methodHandle = - findGetHeadersMethod(MethodType.methodType(List.class, Object.class)); + methodHandle = findGetHeadersMethod(MethodType.methodType(List.class, Object.class)); } GET_HEADERS = methodHandle; } diff --git a/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/internal/WebClientHttpAttributesGetter.java b/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/internal/WebClientHttpAttributesGetter.java index 399f9b4da323..3c9849853b7f 100644 --- a/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/internal/WebClientHttpAttributesGetter.java +++ b/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/internal/WebClientHttpAttributesGetter.java @@ -33,8 +33,7 @@ public enum WebClientHttpAttributesGetter findGetHeadersMethod(MethodType.methodType(List.class, String.class)); if (methodHandle == null) { // up to webflux 7.0 - methodHandle = - findGetHeadersMethod(MethodType.methodType(List.class, Object.class)); + methodHandle = findGetHeadersMethod(MethodType.methodType(List.class, Object.class)); } GET_HEADERS = methodHandle; } From ccf3bcf92e086394d6d6eb2a7292d089c164b650 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 14 Nov 2025 21:40:11 +0100 Subject: [PATCH 7/8] fix --- .../instrumentation/spring/webflux/v5_3/HeaderUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/HeaderUtil.java b/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/HeaderUtil.java index cdd094a6dfe0..27b0de318100 100644 --- a/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/HeaderUtil.java +++ b/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/HeaderUtil.java @@ -30,7 +30,7 @@ class HeaderUtil { private static MethodHandle findGetHeadersMethod(MethodType methodType) { try { - return MethodHandles.lookup().findVirtual(HttpHeaders.class, "getOrDefault", methodType); + return MethodHandles.lookup().findVirtual(HttpHeaders.class, "get", methodType); } catch (Throwable t) { return null; } From 925e44cd6c8a36cdab5ad8fc696c5293968c83a9 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Sat, 15 Nov 2025 11:58:34 +0100 Subject: [PATCH 8/8] fix --- .../v3_1/SpringWebHttpAttributesGetter.java | 39 +++++++++--------- .../spring/webflux/v5_3/HeaderUtil.java | 41 ++++++++++--------- .../WebClientHttpAttributesGetter.java | 38 +++++++++-------- 3 files changed, 61 insertions(+), 57 deletions(-) diff --git a/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java b/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java index b1822d1c10f1..481469051e3c 100644 --- a/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java +++ b/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java @@ -23,7 +23,7 @@ enum SpringWebHttpAttributesGetter @Nullable private static final MethodHandle GET_STATUS_CODE; @Nullable private static final MethodHandle STATUS_CODE_VALUE; - @Nullable private static final MethodHandle GET_HEADERS; + private static final MethodHandle GET_HEADERS; static { MethodHandles.Lookup lookup = MethodHandles.publicLookup(); @@ -58,15 +58,19 @@ enum SpringWebHttpAttributesGetter GET_STATUS_CODE = getStatusCode; STATUS_CODE_VALUE = statusCodeValue; + GET_HEADERS = + isSpring7OrNewer() + ? findGetHeadersMethod(MethodType.methodType(List.class, String.class)) + : findGetHeadersMethod(MethodType.methodType(List.class, Object.class)); + } - // since spring web 7.0 - MethodHandle methodHandle = - findGetHeadersMethod(MethodType.methodType(List.class, String.class)); - if (methodHandle == null) { - // up to spring web 7.0 - methodHandle = findGetHeadersMethod(MethodType.methodType(List.class, Object.class)); + private static boolean isSpring7OrNewer() { + try { + Class.forName("org.springframework.core.Nullness"); + return true; + } catch (ClassNotFoundException e) { + return false; } - GET_HEADERS = methodHandle; } private static MethodHandle findGetHeadersMethod(MethodType methodType) { @@ -94,19 +98,16 @@ public List getHttpRequestHeader(HttpRequest httpRequest, String name) { } @SuppressWarnings("unchecked") // casting MethodHandle.invoke result - private static List getHeader(HttpHeaders headers, String name) { - if (GET_HEADERS != null) { - try { - List result = (List) GET_HEADERS.invoke(headers, name); - if (result == null) { - return emptyList(); - } - return result; - } catch (Throwable t) { - // ignore + static List getHeader(HttpHeaders headers, String name) { + try { + List result = (List) GET_HEADERS.invoke(headers, name); + if (result == null) { + return emptyList(); } + return result; + } catch (Throwable t) { + throw new IllegalStateException(t); } - return emptyList(); } @Override diff --git a/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/HeaderUtil.java b/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/HeaderUtil.java index 27b0de318100..336d484a5359 100644 --- a/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/HeaderUtil.java +++ b/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/HeaderUtil.java @@ -11,45 +11,46 @@ import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.util.List; -import javax.annotation.Nullable; import org.springframework.http.HttpHeaders; class HeaderUtil { - @Nullable private static final MethodHandle GET_HEADERS; + private static final MethodHandle GET_HEADERS; static { - // since spring web 7.0 - MethodHandle methodHandle = - findGetHeadersMethod(MethodType.methodType(List.class, String.class)); - if (methodHandle == null) { - // up to spring web 7.0 - methodHandle = findGetHeadersMethod(MethodType.methodType(List.class, Object.class)); + GET_HEADERS = + isSpring7OrNewer() + ? findGetHeadersMethod(MethodType.methodType(List.class, String.class)) + : findGetHeadersMethod(MethodType.methodType(List.class, Object.class)); + } + + private static boolean isSpring7OrNewer() { + try { + Class.forName("org.springframework.core.Nullness"); + return true; + } catch (ClassNotFoundException e) { + return false; } - GET_HEADERS = methodHandle; } private static MethodHandle findGetHeadersMethod(MethodType methodType) { try { return MethodHandles.lookup().findVirtual(HttpHeaders.class, "get", methodType); } catch (Throwable t) { - return null; + throw new IllegalStateException(t); } } @SuppressWarnings("unchecked") // casting MethodHandle.invoke result static List getHeader(HttpHeaders headers, String name) { - if (GET_HEADERS != null) { - try { - List result = (List) GET_HEADERS.invoke(headers, name); - if (result == null) { - return emptyList(); - } - return result; - } catch (Throwable t) { - // ignore + try { + List result = (List) GET_HEADERS.invoke(headers, name); + if (result == null) { + return emptyList(); } + return result; + } catch (Throwable t) { + throw new IllegalStateException(t); } - return emptyList(); } private HeaderUtil() {} diff --git a/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/internal/WebClientHttpAttributesGetter.java b/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/internal/WebClientHttpAttributesGetter.java index 3c9849853b7f..eb13a258901c 100644 --- a/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/internal/WebClientHttpAttributesGetter.java +++ b/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/internal/WebClientHttpAttributesGetter.java @@ -28,21 +28,26 @@ public enum WebClientHttpAttributesGetter private static final MethodHandle GET_HEADERS; static { - // since webflux 7.0 - MethodHandle methodHandle = - findGetHeadersMethod(MethodType.methodType(List.class, String.class)); - if (methodHandle == null) { - // up to webflux 7.0 - methodHandle = findGetHeadersMethod(MethodType.methodType(List.class, Object.class)); + GET_HEADERS = + isSpring7OrNewer() + ? findGetHeadersMethod(MethodType.methodType(List.class, String.class)) + : findGetHeadersMethod(MethodType.methodType(List.class, Object.class)); + } + + private static boolean isSpring7OrNewer() { + try { + Class.forName("org.springframework.core.Nullness"); + return true; + } catch (ClassNotFoundException e) { + return false; } - GET_HEADERS = methodHandle; } private static MethodHandle findGetHeadersMethod(MethodType methodType) { try { return MethodHandles.lookup().findVirtual(HttpHeaders.class, "get", methodType); } catch (Throwable t) { - return null; + throw new IllegalStateException(t); } } @@ -59,18 +64,15 @@ public String getHttpRequestMethod(ClientRequest request) { @Override @SuppressWarnings("unchecked") // casting MethodHandle.invoke result public List getHttpRequestHeader(ClientRequest request, String name) { - if (GET_HEADERS != null) { - try { - List result = (List) GET_HEADERS.invoke(request, name); - if (result == null) { - return emptyList(); - } - return result; - } catch (Throwable t) { - // ignore + try { + List result = (List) GET_HEADERS.invoke(request.headers(), name); + if (result == null) { + return emptyList(); } + return result; + } catch (Throwable t) { + throw new IllegalStateException(t); } - return emptyList(); } @Override