Skip to content

Commit 6a164a9

Browse files
authored
fix(httpclient): ensure proper closure of HttpClient in shutdown method (#7390)
1 parent 67e3f7b commit 6a164a9

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

exporters/sender/jdk/src/main/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSender.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,13 @@ public CompletableResultCode shutdown() {
390390
if (managedExecutor) {
391391
executorService.shutdown();
392392
}
393+
if (AutoCloseable.class.isInstance(client)) {
394+
try {
395+
AutoCloseable.class.cast(client).close();
396+
} catch (Exception e) {
397+
return CompletableResultCode.ofExceptionalFailure(e);
398+
}
399+
}
393400
return CompletableResultCode.ofSuccess();
394401
}
395402
}

exporters/sender/jdk/src/test/java/io/opentelemetry/exporter/sender/jdk/internal/JdkHttpSenderTest.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616

1717
import io.opentelemetry.exporter.internal.marshal.Marshaler;
1818
import io.opentelemetry.exporter.internal.marshal.Serializer;
19+
import io.opentelemetry.sdk.common.CompletableResultCode;
1920
import io.opentelemetry.sdk.common.export.RetryPolicy;
2021
import java.io.IOException;
22+
import java.lang.reflect.Method;
2123
import java.net.ConnectException;
2224
import java.net.ServerSocket;
2325
import java.net.http.HttpClient;
@@ -29,6 +31,7 @@
2931
import org.assertj.core.api.InstanceOfAssertFactories;
3032
import org.junit.jupiter.api.BeforeEach;
3133
import org.junit.jupiter.api.Test;
34+
import org.junit.jupiter.api.condition.EnabledForJreRange;
3235
import org.junit.jupiter.api.extension.ExtendWith;
3336
import org.mockito.Mock;
3437
import org.mockito.junit.jupiter.MockitoExtension;
@@ -66,6 +69,33 @@ void setup() throws IOException, InterruptedException {
6669
null);
6770
}
6871

72+
@Test
73+
@EnabledForJreRange(
74+
minVersion = 21,
75+
disabledReason = "HttpClient#close has been added in Java 21")
76+
void testShutdown() throws Exception {
77+
CompletableResultCode result = sender.shutdown();
78+
result.join(1, TimeUnit.SECONDS);
79+
assertThat(result.isSuccess()).isTrue();
80+
Method close = HttpClient.class.getMethod("close");
81+
close.invoke(verify(mockHttpClient));
82+
}
83+
84+
@Test
85+
@EnabledForJreRange(
86+
minVersion = 21,
87+
disabledReason = "HttpClient#close has been added in Java 21")
88+
void testShutdownException() throws Exception {
89+
Method close = HttpClient.class.getMethod("close");
90+
close.invoke(doThrow(new RuntimeException("testShutdownException")).when(mockHttpClient));
91+
92+
CompletableResultCode result = sender.shutdown();
93+
result.join(1, TimeUnit.SECONDS);
94+
assertThat(result.isSuccess()).isFalse();
95+
assertThat(result.getFailureThrowable()).isInstanceOf(RuntimeException.class);
96+
assertThat(result.getFailureThrowable().getMessage()).isEqualTo("testShutdownException");
97+
}
98+
6999
@Test
70100
void sendInternal_RetryableConnectTimeoutException() throws IOException, InterruptedException {
71101
assertThatThrownBy(() -> sender.sendInternal(new NoOpMarshaler()))

0 commit comments

Comments
 (0)