diff --git a/instrumentation/netty/netty-4-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4/common/client/NettySslInstrumentationHandler.java b/instrumentation/netty/netty-4-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4/common/client/NettySslInstrumentationHandler.java index 4e46e8df28e0..27abbd4d6248 100644 --- a/instrumentation/netty/netty-4-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4/common/client/NettySslInstrumentationHandler.java +++ b/instrumentation/netty/netty-4-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4/common/client/NettySslInstrumentationHandler.java @@ -6,9 +6,11 @@ package io.opentelemetry.javaagent.instrumentation.netty.v4.common.client; import io.netty.channel.ChannelDuplexHandler; +import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelPromise; import io.opentelemetry.context.Context; +import io.opentelemetry.instrumentation.api.util.VirtualField; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; @@ -20,6 +22,11 @@ public final class NettySslInstrumentationHandler extends ChannelDuplexHandler { private static final Class SSL_HANDSHAKE_COMPLETION_EVENT; private static final MethodHandle GET_CAUSE; + // this is used elsewhere to manage the link between the underlying (user) handler and our handler + // which is needed below so that we can unlink this handler when we remove it below + private static final VirtualField instrumentationHandlerField = + VirtualField.find(ChannelHandler.class, ChannelHandler.class); + static { Class sslHandshakeCompletionEvent = null; MethodHandle getCause = null; @@ -41,12 +48,15 @@ public final class NettySslInstrumentationHandler extends ChannelDuplexHandler { } private final NettySslInstrumenter instrumenter; + private final ChannelHandler realHandler; private Context parentContext; private NettySslRequest request; private Context context; - public NettySslInstrumentationHandler(NettySslInstrumenter instrumenter) { + public NettySslInstrumentationHandler( + NettySslInstrumenter instrumenter, ChannelHandler realHandler) { this.instrumenter = instrumenter; + this.realHandler = realHandler; } @Override @@ -55,6 +65,7 @@ public void channelRegistered(ChannelHandlerContext ctx) { // are on classpath); checking just to be extra safe if (SSL_HANDSHAKE_COMPLETION_EVENT == null) { ctx.pipeline().remove(this); + instrumentationHandlerField.set(realHandler, null); ctx.fireChannelRegistered(); return; } @@ -94,6 +105,7 @@ public void userEventTriggered(ChannelHandlerContext ctx, Object evt) { if (SSL_HANDSHAKE_COMPLETION_EVENT.isInstance(evt)) { if (ctx.pipeline().context(this) != null) { ctx.pipeline().remove(this); + instrumentationHandlerField.set(realHandler, null); } if (context != null) { diff --git a/instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/NettyChannelPipelineInstrumentation.java b/instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/NettyChannelPipelineInstrumentation.java index faa016c85ade..9da556725cac 100644 --- a/instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/NettyChannelPipelineInstrumentation.java +++ b/instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/NettyChannelPipelineInstrumentation.java @@ -95,7 +95,7 @@ public static void addHandler( // the SslHandler lives in the netty-handler module, using class name comparison to avoid // adding a dependency } else if (handler.getClass().getName().equals("io.netty.handler.ssl.SslHandler")) { - ourHandler = new NettySslInstrumentationHandler(sslInstrumenter()); + ourHandler = new NettySslInstrumentationHandler(sslInstrumenter(), handler); } if (ourHandler != null) { diff --git a/instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/NettyChannelPipelineInstrumentation.java b/instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/NettyChannelPipelineInstrumentation.java index 0cd76a87bf3e..3e2414ec07e5 100644 --- a/instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/NettyChannelPipelineInstrumentation.java +++ b/instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/NettyChannelPipelineInstrumentation.java @@ -120,7 +120,7 @@ public static void addHandler( // the SslHandler lives in the netty-handler module, using class name comparison to avoid // adding a dependency } else if (handler.getClass().getName().equals("io.netty.handler.ssl.SslHandler")) { - ourHandler = new NettySslInstrumentationHandler(sslInstrumenter()); + ourHandler = new NettySslInstrumentationHandler(sslInstrumenter(), handler); } if (ourHandler != null) {