-
Notifications
You must be signed in to change notification settings - Fork 955
Description
This relates to this original issue, and I also posted there to get more attention: open-telemetry/opentelemetry-java-instrumentation#14125
Describe the bug
When extending OtlpMetricExporterProvider to dynamically inject authentication headers, calling OtlpHttpMetricExporter.toBuilder() causes a classloader mismatch.
The HttpExporterBuilder.copy() method used internally does not retain the original MultipleParentClassLoader from the component loader and instead uses AgentClassLoader.
This results in the new AgentClassLoader being unable to find the JDK sender, breaking metric exporting (in our case we have to use the JDK sender instead of okhttp).
Steps to reproduce
- Create a custom exporter provider by extending
OtlpMetricExporterProviderlike this:
public class AuthenticatedOtlpMetricExporterProvider extends OtlpMetricExporterProvider {
@Override
public MetricExporter createExporter(ConfigProperties config) {
ClientCredentialsAuthenticator auth = ...
MetricExporter metricExporter = super.createExporter(config);
if (metricExporter instanceof OtlpHttpMetricExporter) {
OtlpHttpMetricExporter.Builder otlpHttpBuilder =
((OtlpHttpMetricExporter) metricExporter).toBuilder();
otlpHttpBuilder.setHeaders(auth::getHeaders);
return otlpHttpBuilder.build();
} else if (metricExporter instanceof OtlpGrpcMetricExporter) {
OtlpGrpcMetricExporter.Builder otlpGrpcBuilder =
((OtlpGrpcMetricExporter) metricExporter).toBuilder();
otlpGrpcBuilder.setHeaders(auth::getHeaders);
return otlpGrpcBuilder.build();
} else {
throw new ConfigurationException("Unsupported OTLP metrics exporter: " +
metricExporter.getClass().getName());
}
}
@Override
public String getName() {
return "otlpauth";
}
}What did you expect to see?
Calling .toBuilder() on an exporter should produce a builder instance that retains the original component / class loader, allowing the new exporter instance to function correctly.
What did you see instead?
.toBuilder() calls HttpExporterBuilder.copy() which instantiates a new builder without preserving the original component loader. This results in the use of AgentClassLoader and breaks class loading, making the JDK sender unavailable.
What version and what artifacts are you using?
1.52.0 where ComponentLoader was introduced by @jack-berg in #7446
Environment
(not relevant)
Compiler: Temurin 17.0.7
OS: Ubuntu 24.04
Runtime: OpenJDK 17
OS (runtime): Ubuntu 24.04