From 78a917da2e8f4bc3645f4fb10361e3e844aab9fb Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Thu, 10 Jul 2025 17:29:25 -0500 Subject: [PATCH] Promote ComponentLoader to new opentelemetry-api-util, standardize SPI loading (#7446) --- README.md | 1 + .../io/opentelemetry/all/SdkDesignTest.java | 8 +++- .../config/DeclarativeConfigProperties.java | 4 ++ .../EmptyDeclarativeConfigProperties.java | 8 ++++ common/build.gradle.kts | 12 ++++++ .../opentelemetry/common/ComponentLoader.java | 28 +++++++++++++ .../common/ServiceLoaderComponentLoader.java | 27 ++++++++++++ context/build.gradle.kts | 1 + .../io/opentelemetry/context/LazyStorage.java | 7 ++-- .../opentelemetry-common.txt | 7 ++++ .../opentelemetry-exporter-otlp.txt | 19 ++++++++- ...emetry-sdk-extension-autoconfigure-spi.txt | 4 +- ...ntelemetry-sdk-extension-autoconfigure.txt | 4 +- .../internal/compression/CompressorUtil.java | 17 ++++---- .../internal/grpc/GrpcExporterBuilder.java | 20 ++++----- .../internal/http/HttpExporterBuilder.java | 20 ++++----- .../compression/CompressorUtilTest.java | 31 +++++++------- .../grpc/GrpcExporterBuilderTest.java | 6 ++- .../http/HttpExporterBuilderTest.java | 6 ++- .../otlp/AbstractOtlpStdoutExporterTest.java | 38 ++++++++--------- .../otlp/OtlpStdoutMetricExporterTest.java | 4 +- .../OtlpHttpLogRecordExporterBuilder.java | 13 +++++- .../OtlpHttpMetricExporterBuilder.java | 12 +++++- .../trace/OtlpHttpSpanExporterBuilder.java | 12 +++++- .../otlp/internal/OtlpConfigUtil.java | 4 ++ .../internal/OtlpDeclarativeConfigUtil.java | 4 ++ ...rpcLogRecordExporterComponentProvider.java | 1 + ...lpGrpcMetricExporterComponentProvider.java | 1 + ...OtlpGrpcSpanExporterComponentProvider.java | 1 + ...ttpLogRecordExporterComponentProvider.java | 1 + ...lpHttpMetricExporterComponentProvider.java | 1 + ...OtlpHttpSpanExporterComponentProvider.java | 1 + .../OtlpLogRecordExporterProvider.java | 2 + .../internal/OtlpMetricExporterProvider.java | 2 + .../internal/OtlpSpanExporterProvider.java | 2 + .../OtlpGrpcLogRecordExporterBuilder.java | 12 +++++- .../OtlpGrpcMetricExporterBuilder.java | 12 +++++- .../trace/OtlpGrpcSpanExporterBuilder.java | 12 +++++- .../otlp/internal/OtlpConfigUtilTest.java | 1 + .../OtlpLogRecordExporterProviderTest.java | 3 ++ .../OtlpMetricExporterProviderTest.java | 6 +++ .../OtlpSpanExporterProviderTest.java | 6 +++ .../OtlpGrpcProfilesExporterBuilder.java | 14 ++++++- .../autoconfigure/spi/ConfigProperties.java | 6 +++ .../spi/internal/DefaultConfigProperties.java | 23 ++++++++-- .../spi/internal/ConfigPropertiesTest.java | 10 +++-- ...AutoConfiguredOpenTelemetrySdkBuilder.java | 11 ++--- .../sdk/autoconfigure/IncubatingUtil.java | 7 ++-- .../autoconfigure/ResourceConfiguration.java | 6 ++- .../internal/AutoConfigureUtil.java | 16 ------- .../internal/ComponentLoader.java | 15 +++---- .../sdk/autoconfigure/internal/SpiHelper.java | 22 +--------- .../AutoConfiguredOpenTelemetrySdkTest.java | 35 +++++++++------- .../ResourceConfigurationTest.java | 6 ++- .../autoconfigure/internal/SpiHelperTest.java | 1 + .../ResourceConfigurationTest.java | 10 +++-- .../DeclarativeConfigurationTest.java | 42 ++++++++++++++----- .../fileconfig/DeclarativeConfiguration.java | 4 +- .../fileconfig/SdkConfigProvider.java | 20 +++++++-- .../fileconfig/ServiceResourceDetector.java | 3 +- .../YamlDeclarativeConfigProperties.java | 3 +- .../DeclarativeConfigurationCreateTest.java | 4 +- settings.gradle.kts | 1 + 63 files changed, 444 insertions(+), 196 deletions(-) create mode 100644 common/build.gradle.kts create mode 100644 common/src/main/java/io/opentelemetry/common/ComponentLoader.java create mode 100644 common/src/main/java/io/opentelemetry/common/ServiceLoaderComponentLoader.java create mode 100644 docs/apidiffs/current_vs_latest/opentelemetry-common.txt diff --git a/README.md b/README.md index 05629a1132..fed6d177db 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,7 @@ The OpenTelemetry API for recording telemetry. | [API](./api/all) | OpenTelemetry API, including metrics, traces, baggage, context | `opentelemetry-api` | 1.51.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api) | | [API Incubator](./api/incubator) | API incubator, including pass through propagator, and extended tracer, and Event API | `opentelemetry-api-incubator` | 1.51.0-alpha | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-api-incubator.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-api-incubator) | | [Context API](./context) | OpenTelemetry context API | `opentelemetry-context` | 1.51.0 | [![Javadocs](https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-context.svg)](https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-context) | +| [Common](./common) | Common utility methods used across API components | `opentelemetry-common` | TODO: add after first publish | TODO: add link after first publish |
diff --git a/all/src/test/java/io/opentelemetry/all/SdkDesignTest.java b/all/src/test/java/io/opentelemetry/all/SdkDesignTest.java index 1a1271b7c2..fe2fb0045e 100644 --- a/all/src/test/java/io/opentelemetry/all/SdkDesignTest.java +++ b/all/src/test/java/io/opentelemetry/all/SdkDesignTest.java @@ -28,7 +28,7 @@ class SdkDesignTest { * Ensures that all SDK methods that: - are defined in classes that extend or implement API model * and are public (to exclude protected builders) - are public (avoids issues with protected * methods returning classes unavailable to test's CL) - override or implement parent method - * return only API, Context or generic Java type. + * return only API, Context, Common, or generic Java type. */ @Test void sdkImplementationOfApiClassesShouldReturnApiTypeOnly() { @@ -45,7 +45,11 @@ class SdkDesignTest { .and(implementOrOverride()) .should() .haveRawReturnType( - inPackage("io.opentelemetry.api..", "io.opentelemetry.context..", "java..")) + inPackage( + "io.opentelemetry.api..", + "io.opentelemetry.context..", + "io.opentelemetry.common..", + "java..")) .orShould() .haveRawReturnType("void"); diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/DeclarativeConfigProperties.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/DeclarativeConfigProperties.java index 3cd862dade..cf98312c9e 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/DeclarativeConfigProperties.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/DeclarativeConfigProperties.java @@ -7,6 +7,7 @@ package io.opentelemetry.api.incubator.config; import static io.opentelemetry.api.internal.ConfigUtil.defaultIfNull; +import io.opentelemetry.common.ComponentLoader; import java.util.List; import java.util.Map; import java.util.Set; @@ -228,4 +229,7 @@ public interface DeclarativeConfigProperties { * @return the configuration property keys */ Set getPropertyKeys(); + + /** Return a {@link ComponentLoader} that should be used to load SPIs. */ + ComponentLoader getComponentLoader(); } diff --git a/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/EmptyDeclarativeConfigProperties.java b/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/EmptyDeclarativeConfigProperties.java index 77b8a26549..6c3a85f1ee 100644 --- a/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/EmptyDeclarativeConfigProperties.java +++ b/api/incubator/src/main/java/io/opentelemetry/api/incubator/config/EmptyDeclarativeConfigProperties.java @@ -5,6 +5,7 @@ package io.opentelemetry.api.incubator.config; +import io.opentelemetry.common.ComponentLoader; import java.util.Collections; import java.util.List; import java.util.Set; @@ -15,6 +16,8 @@ final class EmptyDeclarativeConfigProperties implements DeclarativeConfigPropert private static final EmptyDeclarativeConfigProperties INSTANCE = new EmptyDeclarativeConfigProperties(); + private static final ComponentLoader COMPONENT_LOADER = + ComponentLoader.forClassLoader(EmptyDeclarativeConfigProperties.class.getClassLoader()); private EmptyDeclarativeConfigProperties() {} @@ -74,4 +77,9 @@ final class EmptyDeclarativeConfigProperties implements DeclarativeConfigPropert public Set getPropertyKeys() { return Collections.emptySet(); } + + @Override + public ComponentLoader getComponentLoader() { + return COMPONENT_LOADER; + } } diff --git a/common/build.gradle.kts b/common/build.gradle.kts new file mode 100644 index 0000000000..ffeef6877f --- /dev/null +++ b/common/build.gradle.kts @@ -0,0 +1,12 @@ +plugins { + id("otel.java-conventions") + id("otel.publish-conventions") + + id("otel.animalsniffer-conventions") +} + +description = "OpenTelemetry API Common" +otelJava.moduleName.set("io.opentelemetry.common") + +dependencies { +} diff --git a/common/src/main/java/io/opentelemetry/common/ComponentLoader.java b/common/src/main/java/io/opentelemetry/common/ComponentLoader.java new file mode 100644 index 0000000000..17dab36a1b --- /dev/null +++ b/common/src/main/java/io/opentelemetry/common/ComponentLoader.java @@ -0,0 +1,28 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.common; + +import java.util.ServiceLoader; + +/** A loader for components that are discovered via SPI. */ +public interface ComponentLoader { + /** + * Load implementations of an SPI. + * + * @param spiClass the SPI class + * @param the SPI type + * @return iterable of SPI implementations + */ + Iterable load(Class spiClass); + + /** + * Create an instance for the {@code classLoader} using {@link ServiceLoader#load(Class, + * ClassLoader)}. + */ + static ComponentLoader forClassLoader(ClassLoader classLoader) { + return new ServiceLoaderComponentLoader(classLoader); + } +} diff --git a/common/src/main/java/io/opentelemetry/common/ServiceLoaderComponentLoader.java b/common/src/main/java/io/opentelemetry/common/ServiceLoaderComponentLoader.java new file mode 100644 index 0000000000..5f2d0c58cd --- /dev/null +++ b/common/src/main/java/io/opentelemetry/common/ServiceLoaderComponentLoader.java @@ -0,0 +1,27 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.common; + +import java.util.ServiceLoader; + +class ServiceLoaderComponentLoader implements ComponentLoader { + + private final ClassLoader classLoader; + + ServiceLoaderComponentLoader(ClassLoader classLoader) { + this.classLoader = classLoader; + } + + @Override + public Iterable load(Class spiClass) { + return ServiceLoader.load(spiClass, classLoader); + } + + @Override + public String toString() { + return "ServiceLoaderComponentLoader{classLoader=" + classLoader + "}"; + } +} diff --git a/context/build.gradle.kts b/context/build.gradle.kts index 6c8fa63837..b3a3562051 100644 --- a/context/build.gradle.kts +++ b/context/build.gradle.kts @@ -10,6 +10,7 @@ description = "OpenTelemetry Context (Incubator)" otelJava.moduleName.set("io.opentelemetry.context") dependencies { + api(project(":common")) // MustBeClosed compileOnly("com.google.errorprone:error_prone_annotations") diff --git a/context/src/main/java/io/opentelemetry/context/LazyStorage.java b/context/src/main/java/io/opentelemetry/context/LazyStorage.java index 5cce59d253..428b87dc48 100644 --- a/context/src/main/java/io/opentelemetry/context/LazyStorage.java +++ b/context/src/main/java/io/opentelemetry/context/LazyStorage.java @@ -37,9 +37,9 @@ package io.opentelemetry.context; +import io.opentelemetry.common.ComponentLoader; import java.util.ArrayList; import java.util.List; -import java.util.ServiceLoader; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; import java.util.logging.Level; @@ -103,9 +103,10 @@ final class LazyStorage { return ContextStorage.defaultStorage(); } + ComponentLoader componentLoader = + ComponentLoader.forClassLoader(LazyStorage.class.getClassLoader()); List providers = new ArrayList<>(); - for (ContextStorageProvider provider : - ServiceLoader.load(ContextStorageProvider.class, LazyStorage.class.getClassLoader())) { + for (ContextStorageProvider provider : componentLoader.load(ContextStorageProvider.class)) { if (provider .getClass() .getName() diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-common.txt b/docs/apidiffs/current_vs_latest/opentelemetry-common.txt new file mode 100644 index 0000000000..515236fbc7 --- /dev/null +++ b/docs/apidiffs/current_vs_latest/opentelemetry-common.txt @@ -0,0 +1,7 @@ +Comparing source compatibility of opentelemetry-common-1.52.0-SNAPSHOT.jar against ++++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.common.ComponentLoader (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.common.ComponentLoader forClassLoader(java.lang.ClassLoader) + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.Iterable load(java.lang.Class) + GENERIC TEMPLATES: +++ T:java.lang.Object diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt index 50c76ab468..2cb2483fd0 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-otlp.txt @@ -1,2 +1,19 @@ Comparing source compatibility of opentelemetry-exporter-otlp-1.52.0-SNAPSHOT.jar against opentelemetry-exporter-otlp-1.51.0.jar -No changes. \ No newline at end of file +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder setComponentLoader(io.opentelemetry.common.ComponentLoader) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder setComponentLoader(io.opentelemetry.common.ComponentLoader) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder setComponentLoader(io.opentelemetry.common.ComponentLoader) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder setComponentLoader(io.opentelemetry.common.ComponentLoader) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder setComponentLoader(io.opentelemetry.common.ComponentLoader) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder setComponentLoader(io.opentelemetry.common.ComponentLoader) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt index e39912ab8a..464dfcf5d0 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -1,2 +1,4 @@ Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-spi-1.52.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-spi-1.51.0.jar -No changes. \ No newline at end of file +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.common.ComponentLoader getComponentLoader() diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt index 6dcf9a630a..ba20f69aaf 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt @@ -1,2 +1,4 @@ Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.52.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-1.51.0.jar -No changes. \ No newline at end of file +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder setComponentLoader(io.opentelemetry.common.ComponentLoader) diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/CompressorUtil.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/CompressorUtil.java index ef4785ae6c..92b7d2d9c6 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/CompressorUtil.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/compression/CompressorUtil.java @@ -8,9 +8,9 @@ package io.opentelemetry.exporter.internal.compression; import static io.opentelemetry.api.internal.Utils.checkArgument; import static java.util.stream.Collectors.joining; +import io.opentelemetry.common.ComponentLoader; import java.util.HashMap; import java.util.Map; -import java.util.ServiceLoader; import java.util.Set; import javax.annotation.Nullable; @@ -25,7 +25,8 @@ import javax.annotation.Nullable; public final class CompressorUtil { private static final Map compressorRegistry = - buildCompressorRegistry(CompressorUtil.class.getClassLoader()); + buildCompressorRegistry( + ComponentLoader.forClassLoader(CompressorUtil.class.getClassLoader())); private CompressorUtil() {} @@ -44,16 +45,16 @@ public final class CompressorUtil { * Validate that the {@code compressionMethod} is "none" or matches a registered compressor. * * @param compressionMethod the compression method to validate and resolve - * @param classLoader the class loader to use for loading SPI implementations, or null to use the - * default + * @param componentLoader the component loader to use for loading SPI implementations, or null to + * use the default * @return {@code null} if {@code compressionMethod} is "none" or the registered compressor * @throws IllegalArgumentException if no match is found */ @Nullable public static Compressor validateAndResolveCompressor( - String compressionMethod, @Nullable ClassLoader classLoader) { + String compressionMethod, @Nullable ComponentLoader componentLoader) { Map registry = - classLoader == null ? compressorRegistry : buildCompressorRegistry(classLoader); + componentLoader == null ? compressorRegistry : buildCompressorRegistry(componentLoader); Set supportedEncodings = registry.keySet(); Compressor compressor = registry.get(compressionMethod); @@ -64,9 +65,9 @@ public final class CompressorUtil { return compressor; } - private static Map buildCompressorRegistry(ClassLoader classLoader) { + private static Map buildCompressorRegistry(ComponentLoader componentLoader) { Map compressors = new HashMap<>(); - for (CompressorProvider spi : ServiceLoader.load(CompressorProvider.class, classLoader)) { + for (CompressorProvider spi : componentLoader.load(CompressorProvider.class)) { Compressor compressor = spi.getInstance(); compressors.put(compressor.getEncoding(), compressor); } diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java index 15028492ae..27d06b7116 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilder.java @@ -5,16 +5,16 @@ package io.opentelemetry.exporter.internal.grpc; -import static java.util.Objects.requireNonNull; - import io.grpc.Channel; import io.grpc.ManagedChannel; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.internal.ConfigUtil; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.exporter.internal.ExporterBuilderUtil; import io.opentelemetry.exporter.internal.TlsConfigHelper; import io.opentelemetry.exporter.internal.compression.Compressor; +import io.opentelemetry.exporter.internal.compression.CompressorProvider; import io.opentelemetry.exporter.internal.compression.CompressorUtil; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.common.InternalTelemetryVersion; @@ -29,7 +29,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.ServiceLoader; import java.util.StringJoiner; import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; @@ -70,7 +69,8 @@ public class GrpcExporterBuilder { private Supplier meterProviderSupplier = GlobalOpenTelemetry::getMeterProvider; private InternalTelemetryVersion internalTelemetryVersion = InternalTelemetryVersion.LEGACY; - private ClassLoader serviceClassLoader = GrpcExporterBuilder.class.getClassLoader(); + private ComponentLoader componentLoader = + ComponentLoader.forClassLoader(GrpcExporterBuilder.class.getClassLoader()); @Nullable private ExecutorService executorService; // Use Object type since gRPC may not be on the classpath. @@ -124,9 +124,8 @@ public class GrpcExporterBuilder { * methods is available by implementing {@link Compressor} and {@link CompressorProvider}. */ public GrpcExporterBuilder setCompression(String compressionMethod) { - requireNonNull(compressionMethod, "compressionMethod"); Compressor compressor = - CompressorUtil.validateAndResolveCompressor(compressionMethod, serviceClassLoader); + CompressorUtil.validateAndResolveCompressor(compressionMethod, componentLoader); return setCompression(compressor); } @@ -173,8 +172,8 @@ public class GrpcExporterBuilder { return this; } - public GrpcExporterBuilder setServiceClassLoader(ClassLoader serviceClassLoader) { - this.serviceClassLoader = serviceClassLoader; + public GrpcExporterBuilder setComponentLoader(ComponentLoader componentLoader) { + this.componentLoader = componentLoader; return this; } @@ -283,7 +282,7 @@ public class GrpcExporterBuilder { if (grpcChannel != null) { joiner.add("grpcChannel=" + grpcChannel); } - joiner.add("serviceClassLoader=" + serviceClassLoader); + joiner.add("componentLoader=" + componentLoader); if (executorService != null) { joiner.add("executorService=" + executorService); } @@ -317,8 +316,7 @@ public class GrpcExporterBuilder { */ private GrpcSenderProvider resolveGrpcSenderProvider() { Map grpcSenderProviders = new HashMap<>(); - for (GrpcSenderProvider spi : - ServiceLoader.load(GrpcSenderProvider.class, serviceClassLoader)) { + for (GrpcSenderProvider spi : componentLoader.load(GrpcSenderProvider.class)) { grpcSenderProviders.put(spi.getClass().getName(), spi); } diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java index a2aa14a3ab..42d55cb0a2 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilder.java @@ -5,14 +5,14 @@ package io.opentelemetry.exporter.internal.http; -import static java.util.Objects.requireNonNull; - import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.internal.ConfigUtil; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.exporter.internal.ExporterBuilderUtil; import io.opentelemetry.exporter.internal.TlsConfigHelper; import io.opentelemetry.exporter.internal.compression.Compressor; +import io.opentelemetry.exporter.internal.compression.CompressorProvider; import io.opentelemetry.exporter.internal.compression.CompressorUtil; import io.opentelemetry.exporter.internal.marshal.Marshaler; import io.opentelemetry.sdk.common.InternalTelemetryVersion; @@ -27,7 +27,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.ServiceLoader; import java.util.StringJoiner; import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; @@ -67,7 +66,8 @@ public final class HttpExporterBuilder { @Nullable private RetryPolicy retryPolicy = RetryPolicy.getDefault(); private Supplier meterProviderSupplier = GlobalOpenTelemetry::getMeterProvider; private InternalTelemetryVersion internalTelemetryVersion = InternalTelemetryVersion.LEGACY; - private ClassLoader serviceClassLoader = HttpExporterBuilder.class.getClassLoader(); + private ComponentLoader componentLoader = + ComponentLoader.forClassLoader(HttpExporterBuilder.class.getClassLoader()); @Nullable private ExecutorService executorService; public HttpExporterBuilder( @@ -104,9 +104,8 @@ public final class HttpExporterBuilder { * methods is available by implementing {@link Compressor} and {@link CompressorProvider}. */ public HttpExporterBuilder setCompression(String compressionMethod) { - requireNonNull(compressionMethod, "compressionMethod"); Compressor compressor = - CompressorUtil.validateAndResolveCompressor(compressionMethod, serviceClassLoader); + CompressorUtil.validateAndResolveCompressor(compressionMethod, componentLoader); return setCompression(compressor); } @@ -158,8 +157,8 @@ public final class HttpExporterBuilder { return this; } - public HttpExporterBuilder setServiceClassLoader(ClassLoader serviceClassLoader) { - this.serviceClassLoader = serviceClassLoader; + public HttpExporterBuilder setComponentLoader(ComponentLoader componentLoader) { + this.componentLoader = componentLoader; return this; } @@ -280,7 +279,7 @@ public final class HttpExporterBuilder { if (retryPolicy != null) { joiner.add("retryPolicy=" + retryPolicy); } - joiner.add("serviceClassLoader=" + serviceClassLoader); + joiner.add("componentLoader=" + componentLoader); if (executorService != null) { joiner.add("executorService=" + executorService); } @@ -314,8 +313,7 @@ public final class HttpExporterBuilder { */ private HttpSenderProvider resolveHttpSenderProvider() { Map httpSenderProviders = new HashMap<>(); - for (HttpSenderProvider spi : - ServiceLoader.load(HttpSenderProvider.class, serviceClassLoader)) { + for (HttpSenderProvider spi : componentLoader.load(HttpSenderProvider.class)) { httpSenderProviders.put(spi.getClass().getName(), spi); } diff --git a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/compression/CompressorUtilTest.java b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/compression/CompressorUtilTest.java index d0c9a8eac6..d8dcffd3c4 100644 --- a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/compression/CompressorUtilTest.java +++ b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/compression/CompressorUtilTest.java @@ -8,12 +8,16 @@ package io.opentelemetry.exporter.internal.compression; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import io.opentelemetry.common.ComponentLoader; import java.net.URL; import java.net.URLClassLoader; import org.junit.jupiter.api.Test; class CompressorUtilTest { + private final ComponentLoader componentLoader = + ComponentLoader.forClassLoader(CompressorUtilTest.class.getClassLoader()); + @Test void validateAndResolveCompressor_none() { assertThat(CompressorUtil.validateAndResolveCompressor("none")).isNull(); @@ -34,21 +38,19 @@ class CompressorUtilTest { @Test void validateAndResolveCompressor_withClassLoader_none() { - ClassLoader classLoader = CompressorUtilTest.class.getClassLoader(); - assertThat(CompressorUtil.validateAndResolveCompressor("none", classLoader)).isNull(); + assertThat(CompressorUtil.validateAndResolveCompressor("none", componentLoader)).isNull(); } @Test void validateAndResolveCompressor_withClassLoader_gzip() { - ClassLoader classLoader = CompressorUtilTest.class.getClassLoader(); - assertThat(CompressorUtil.validateAndResolveCompressor("gzip", classLoader)) + assertThat(CompressorUtil.validateAndResolveCompressor("gzip", componentLoader)) .isEqualTo(GzipCompressor.getInstance()); } @Test void validateAndResolveCompressor_withClassLoader_invalid() { - ClassLoader classLoader = CompressorUtilTest.class.getClassLoader(); - assertThatThrownBy(() -> CompressorUtil.validateAndResolveCompressor("invalid", classLoader)) + assertThatThrownBy( + () -> CompressorUtil.validateAndResolveCompressor("invalid", componentLoader)) .isInstanceOf(IllegalArgumentException.class) .hasMessageContaining("Unsupported compressionMethod"); } @@ -56,18 +58,19 @@ class CompressorUtilTest { @Test void validateAndResolveCompressor_emptyClassLoader() { // Create a class loader that cannot load CompressorProvider services - ClassLoader emptyClassLoader = new URLClassLoader(new URL[0], null); + ComponentLoader emptyComponentLoader = + ComponentLoader.forClassLoader(new URLClassLoader(new URL[0], null)); // Gzip should still work because it's hardcoded - assertThat(CompressorUtil.validateAndResolveCompressor("gzip", emptyClassLoader)) + assertThat(CompressorUtil.validateAndResolveCompressor("gzip", emptyComponentLoader)) .isEqualTo(GzipCompressor.getInstance()); // None should still work because it doesn't require loading services - assertThat(CompressorUtil.validateAndResolveCompressor("none", emptyClassLoader)).isNull(); + assertThat(CompressorUtil.validateAndResolveCompressor("none", emptyComponentLoader)).isNull(); // Any SPI-based compressor should not be available assertThatThrownBy( - () -> CompressorUtil.validateAndResolveCompressor("base64", emptyClassLoader)) + () -> CompressorUtil.validateAndResolveCompressor("base64", emptyComponentLoader)) .isInstanceOf(IllegalArgumentException.class) .hasMessageContaining("Unsupported compressionMethod"); } @@ -76,13 +79,9 @@ class CompressorUtilTest { void validateAndResolveCompressor_delegatesCorrectly() { // Test that single-parameter method delegates to two-parameter method assertThat(CompressorUtil.validateAndResolveCompressor("gzip")) - .isEqualTo( - CompressorUtil.validateAndResolveCompressor( - "gzip", CompressorUtil.class.getClassLoader())); + .isEqualTo(CompressorUtil.validateAndResolveCompressor("gzip", componentLoader)); assertThat(CompressorUtil.validateAndResolveCompressor("none")) - .isEqualTo( - CompressorUtil.validateAndResolveCompressor( - "none", CompressorUtil.class.getClassLoader())); + .isEqualTo(CompressorUtil.validateAndResolveCompressor("none", componentLoader)); } } diff --git a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilderTest.java b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilderTest.java index 0763309f50..b17f3cdb59 100644 --- a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilderTest.java +++ b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/grpc/GrpcExporterBuilderTest.java @@ -8,6 +8,7 @@ package io.opentelemetry.exporter.internal.grpc; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.compression.GzipCompressor; import io.opentelemetry.exporter.internal.marshal.Marshaler; @@ -83,8 +84,9 @@ class GrpcExporterBuilderTest { @Test void compressionString_usesServiceClassLoader() { // Create a class loader that cannot load CompressorProvider services - ClassLoader emptyClassLoader = new URLClassLoader(new URL[0], null); - builder.setServiceClassLoader(emptyClassLoader); + ComponentLoader emptyComponentLoader = + ComponentLoader.forClassLoader(new URLClassLoader(new URL[0], null)); + builder.setComponentLoader(emptyComponentLoader); // This should still work because gzip compressor is hardcoded builder.setCompression("gzip"); diff --git a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilderTest.java b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilderTest.java index 9e0f74401a..c924dcd9af 100644 --- a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilderTest.java +++ b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/http/HttpExporterBuilderTest.java @@ -8,6 +8,7 @@ package io.opentelemetry.exporter.internal.http; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.compression.GzipCompressor; import io.opentelemetry.exporter.internal.marshal.Marshaler; @@ -78,8 +79,9 @@ class HttpExporterBuilderTest { @Test void compressionString_usesServiceClassLoader() { // Create a class loader that cannot load CompressorProvider services - ClassLoader emptyClassLoader = new URLClassLoader(new URL[0], null); - builder.setServiceClassLoader(emptyClassLoader); + ComponentLoader emptyComponentLoader = + ComponentLoader.forClassLoader(new URLClassLoader(new URL[0], null)); + builder.setComponentLoader(emptyComponentLoader); // This should still work because gzip compressor is hardcoded builder.setCompression("gzip"); diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/AbstractOtlpStdoutExporterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/AbstractOtlpStdoutExporterTest.java index ed7b79f65e..44b046aca4 100644 --- a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/AbstractOtlpStdoutExporterTest.java +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/AbstractOtlpStdoutExporterTest.java @@ -9,11 +9,10 @@ import static java.util.Collections.emptyMap; import static java.util.Collections.singletonMap; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import com.google.common.collect.ImmutableList; -import com.google.common.collect.Streams; import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; @@ -29,10 +28,10 @@ import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; -import java.util.ServiceLoader; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import java.util.stream.Stream; +import java.util.stream.StreamSupport; import javax.annotation.Nullable; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -306,7 +305,7 @@ abstract class AbstractOtlpStdoutExporterTest { @Test void componentProviderConfig() { - DeclarativeConfigProperties properties = mock(DeclarativeConfigProperties.class); + DeclarativeConfigProperties properties = spy(DeclarativeConfigProperties.empty()); T exporter = exporterFromComponentProvider(properties); assertThat(exporter).extracting("wrapperJsonObject").isEqualTo(true); @@ -330,22 +329,22 @@ abstract class AbstractOtlpStdoutExporterTest { @SuppressWarnings("unchecked") protected T exporterFromComponentProvider(DeclarativeConfigProperties properties) { return (T) - ((ComponentProvider) - loadSpi(ComponentProvider.class) - .filter( - p -> { - ComponentProvider c = (ComponentProvider) p; - return "otlp_file/development".equals(c.getName()) - && c.getType().equals(componentProviderType); - }) - .findFirst() - .orElseThrow(() -> new IllegalStateException("No provider found"))) + StreamSupport.stream( + properties.getComponentLoader().load(ComponentProvider.class).spliterator(), false) + .filter( + p -> { + ComponentProvider c = p; + return "otlp_file/development".equals(c.getName()) + && c.getType().equals(componentProviderType); + }) + .findFirst() + .orElseThrow(() -> new IllegalStateException("No provider found")) .create(properties); } @SuppressWarnings("unchecked") protected T exporterFromProvider(ConfigProperties config) { - Object provider = loadProvider(); + Object provider = loadProvider(config); try { return (T) @@ -358,8 +357,9 @@ abstract class AbstractOtlpStdoutExporterTest { } } - private Object loadProvider() { - return loadSpi(providerClass) + private Object loadProvider(ConfigProperties config) { + return StreamSupport.stream( + config.getComponentLoader().load(providerClass).spliterator(), false) .filter( p -> { try { @@ -372,8 +372,4 @@ abstract class AbstractOtlpStdoutExporterTest { .findFirst() .orElseThrow(() -> new IllegalStateException("No provider found")); } - - protected static Stream loadSpi(Class type) { - return Streams.stream(ServiceLoader.load(type, type.getClassLoader()).iterator()); - } } diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutMetricExporterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutMetricExporterTest.java index df91f1e2cb..28b0b2e358 100644 --- a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutMetricExporterTest.java +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpStdoutMetricExporterTest.java @@ -7,7 +7,7 @@ package io.opentelemetry.exporter.logging.otlp; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; -import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import com.google.common.collect.ImmutableMap; @@ -81,7 +81,7 @@ class OtlpStdoutMetricExporterTest @Test void componentProviderMetricConfig() { - DeclarativeConfigProperties properties = mock(DeclarativeConfigProperties.class); + DeclarativeConfigProperties properties = spy(DeclarativeConfigProperties.empty()); when(properties.getString("temporality_preference")).thenReturn("DELTA"); when(properties.getString("default_histogram_aggregation")) .thenReturn("BASE2_EXPONENTIAL_BUCKET_HISTOGRAM"); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java index 8ebc132595..b960691907 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/logs/OtlpHttpLogRecordExporterBuilder.java @@ -10,6 +10,7 @@ import static java.util.Objects.requireNonNull; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; import io.opentelemetry.exporter.internal.marshal.Marshaler; @@ -114,6 +115,7 @@ public final class OtlpHttpLogRecordExporterBuilder { * supported by providing custom {@link Compressor} implementations via the service loader. */ public OtlpHttpLogRecordExporterBuilder setCompression(String compressionMethod) { + requireNonNull(compressionMethod, "compressionMethod"); delegate.setCompression(compressionMethod); return this; } @@ -241,13 +243,20 @@ public final class OtlpHttpLogRecordExporterBuilder { } /** - * Set the {@link ClassLoader} used to load the sender API. + * Set the {@link ClassLoader} used to load the sender API. Variant of {@link + * #setComponentLoader(ComponentLoader)}. * * @since 1.48.0 */ public OtlpHttpLogRecordExporterBuilder setServiceClassLoader(ClassLoader serviceClassLoader) { requireNonNull(serviceClassLoader, "serviceClassLoader"); - delegate.setServiceClassLoader(serviceClassLoader); + return setComponentLoader(ComponentLoader.forClassLoader(serviceClassLoader)); + } + + /** Set the {@link ComponentLoader} used to load the sender API. */ + public OtlpHttpLogRecordExporterBuilder setComponentLoader(ComponentLoader componentLoader) { + requireNonNull(componentLoader, "componentLoader"); + delegate.setComponentLoader(componentLoader); return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java index 9eb5716ea9..07f24dac91 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java @@ -10,6 +10,7 @@ import static java.util.Objects.requireNonNull; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; import io.opentelemetry.exporter.internal.marshal.Marshaler; @@ -301,13 +302,20 @@ public final class OtlpHttpMetricExporterBuilder { } /** - * Set the {@link ClassLoader} used to load the sender API. + * Set the {@link ClassLoader} used to load the sender API. Variant of {@link + * #setComponentLoader(ComponentLoader)}. * * @since 1.48.0 */ public OtlpHttpMetricExporterBuilder setServiceClassLoader(ClassLoader serviceClassLoader) { requireNonNull(serviceClassLoader, "serviceClassLoader"); - delegate.setServiceClassLoader(serviceClassLoader); + return setComponentLoader(ComponentLoader.forClassLoader(serviceClassLoader)); + } + + /** Set the {@link ComponentLoader} used to load the sender API. */ + public OtlpHttpMetricExporterBuilder setComponentLoader(ComponentLoader componentLoader) { + requireNonNull(componentLoader, "componentLoader"); + delegate.setComponentLoader(componentLoader); return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java index 48864b4639..f8289010b5 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/http/trace/OtlpHttpSpanExporterBuilder.java @@ -10,6 +10,7 @@ import static java.util.Objects.requireNonNull; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.http.HttpExporterBuilder; import io.opentelemetry.exporter.internal.marshal.Marshaler; @@ -243,13 +244,20 @@ public final class OtlpHttpSpanExporterBuilder { } /** - * Set the {@link ClassLoader} used to load the sender API. + * Set the {@link ClassLoader} used to load the sender API. Variant of {@link + * #setComponentLoader(ComponentLoader)}. * * @since 1.48.0 */ public OtlpHttpSpanExporterBuilder setServiceClassLoader(ClassLoader serviceClassLoader) { requireNonNull(serviceClassLoader, "serviceClassLoader"); - delegate.setServiceClassLoader(serviceClassLoader); + return setComponentLoader(ComponentLoader.forClassLoader(serviceClassLoader)); + } + + /** Set the {@link ComponentLoader} used to load the sender API. */ + public OtlpHttpSpanExporterBuilder setComponentLoader(ComponentLoader componentLoader) { + requireNonNull(componentLoader, "componentLoader"); + delegate.setComponentLoader(componentLoader); return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java index 8bfcb4b396..427d79e7ac 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtil.java @@ -5,6 +5,7 @@ package io.opentelemetry.exporter.otlp.internal; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.exporter.internal.ExporterBuilderUtil; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; @@ -53,6 +54,7 @@ public final class OtlpConfigUtil { public static void configureOtlpExporterBuilder( String dataType, ConfigProperties config, + Consumer setComponentLoader, Consumer setEndpoint, BiConsumer addHeader, Consumer setCompression, @@ -61,6 +63,8 @@ public final class OtlpConfigUtil { BiConsumer setClientTls, Consumer setRetryPolicy, Consumer setMemoryMode) { + setComponentLoader.accept(config.getComponentLoader()); + String protocol = getOtlpProtocol(dataType, config); boolean isHttpProtobuf = protocol.equals(PROTOCOL_HTTP_PROTOBUF); URL endpoint = diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpDeclarativeConfigUtil.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpDeclarativeConfigUtil.java index dfcd6740bf..b2f174ae3d 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpDeclarativeConfigUtil.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpDeclarativeConfigUtil.java @@ -11,6 +11,7 @@ import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.readFileByt import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.validateEndpoint; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.exporter.internal.IncubatingExporterBuilderUtil; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; @@ -47,6 +48,7 @@ public final class OtlpDeclarativeConfigUtil { public static void configureOtlpExporterBuilder( String dataType, DeclarativeConfigProperties config, + Consumer setComponentLoader, Consumer setEndpoint, BiConsumer addHeader, Consumer setCompression, @@ -56,6 +58,8 @@ public final class OtlpDeclarativeConfigUtil { Consumer setRetryPolicy, Consumer setMemoryMode, boolean isHttpProtobuf) { + setComponentLoader.accept(config.getComponentLoader()); + URL endpoint = validateEndpoint(config.getString("endpoint"), isHttpProtobuf); if (endpoint != null) { setEndpoint.accept(endpoint.toString()); diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcLogRecordExporterComponentProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcLogRecordExporterComponentProvider.java index 08b6b65d30..f8faab7a00 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcLogRecordExporterComponentProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcLogRecordExporterComponentProvider.java @@ -39,6 +39,7 @@ public class OtlpGrpcLogRecordExporterComponentProvider OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder( DATA_TYPE_LOGS, config, + builder::setComponentLoader, builder::setEndpoint, builder::addHeader, builder::setCompression, diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcMetricExporterComponentProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcMetricExporterComponentProvider.java index f55ab3795c..25f8341fb0 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcMetricExporterComponentProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcMetricExporterComponentProvider.java @@ -39,6 +39,7 @@ public class OtlpGrpcMetricExporterComponentProvider implements ComponentProvide OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder( DATA_TYPE_METRICS, config, + builder::setComponentLoader, builder::setEndpoint, builder::addHeader, builder::setCompression, diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcSpanExporterComponentProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcSpanExporterComponentProvider.java index c84afce9e6..84e230ca51 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcSpanExporterComponentProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcSpanExporterComponentProvider.java @@ -38,6 +38,7 @@ public class OtlpGrpcSpanExporterComponentProvider implements ComponentProvider< OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder( DATA_TYPE_TRACES, config, + builder::setComponentLoader, builder::setEndpoint, builder::addHeader, builder::setCompression, diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpLogRecordExporterComponentProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpLogRecordExporterComponentProvider.java index eb9143b181..e6a513e898 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpLogRecordExporterComponentProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpLogRecordExporterComponentProvider.java @@ -39,6 +39,7 @@ public class OtlpHttpLogRecordExporterComponentProvider OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder( DATA_TYPE_LOGS, config, + builder::setComponentLoader, builder::setEndpoint, builder::addHeader, builder::setCompression, diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpMetricExporterComponentProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpMetricExporterComponentProvider.java index f22059d9a7..d6cc1bf62d 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpMetricExporterComponentProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpMetricExporterComponentProvider.java @@ -39,6 +39,7 @@ public class OtlpHttpMetricExporterComponentProvider implements ComponentProvide OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder( DATA_TYPE_METRICS, config, + builder::setComponentLoader, builder::setEndpoint, builder::addHeader, builder::setCompression, diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpSpanExporterComponentProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpSpanExporterComponentProvider.java index 2c9b876979..752e9698dc 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpSpanExporterComponentProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpSpanExporterComponentProvider.java @@ -38,6 +38,7 @@ public class OtlpHttpSpanExporterComponentProvider implements ComponentProvider< OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder( DATA_TYPE_TRACES, config, + builder::setComponentLoader, builder::setEndpoint, builder::addHeader, builder::setCompression, diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProvider.java index 67ed44c754..1262bc7250 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProvider.java @@ -45,6 +45,7 @@ public class OtlpLogRecordExporterProvider OtlpConfigUtil.configureOtlpExporterBuilder( DATA_TYPE_LOGS, config, + builder::setComponentLoader, builder::setEndpoint, builder::addHeader, builder::setCompression, @@ -62,6 +63,7 @@ public class OtlpLogRecordExporterProvider OtlpConfigUtil.configureOtlpExporterBuilder( DATA_TYPE_LOGS, config, + builder::setComponentLoader, builder::setEndpoint, builder::addHeader, builder::setCompression, diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProvider.java index a60f57a250..ebfaaacf29 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProvider.java @@ -38,6 +38,7 @@ public class OtlpMetricExporterProvider implements ConfigurableMetricExporterPro OtlpConfigUtil.configureOtlpExporterBuilder( DATA_TYPE_METRICS, config, + builder::setComponentLoader, builder::setEndpoint, builder::addHeader, builder::setCompression, @@ -58,6 +59,7 @@ public class OtlpMetricExporterProvider implements ConfigurableMetricExporterPro OtlpConfigUtil.configureOtlpExporterBuilder( DATA_TYPE_METRICS, config, + builder::setComponentLoader, builder::setEndpoint, builder::addHeader, builder::setCompression, diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProvider.java index e6fad237d8..1561c057b2 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProvider.java @@ -44,6 +44,7 @@ public class OtlpSpanExporterProvider OtlpConfigUtil.configureOtlpExporterBuilder( DATA_TYPE_TRACES, config, + builder::setComponentLoader, builder::setEndpoint, builder::addHeader, builder::setCompression, @@ -61,6 +62,7 @@ public class OtlpSpanExporterProvider OtlpConfigUtil.configureOtlpExporterBuilder( DATA_TYPE_TRACES, config, + builder::setComponentLoader, builder::setEndpoint, builder::addHeader, builder::setCompression, diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java index d1cf9f5798..467aa0cd6a 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/logs/OtlpGrpcLogRecordExporterBuilder.java @@ -11,6 +11,7 @@ import static java.util.Objects.requireNonNull; import io.grpc.ManagedChannel; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; import io.opentelemetry.exporter.internal.marshal.Marshaler; @@ -271,13 +272,20 @@ public final class OtlpGrpcLogRecordExporterBuilder { } /** - * Set the {@link ClassLoader} used to load the sender API. + * Set the {@link ClassLoader} used to load the sender API. Variant of {@link + * #setComponentLoader(ComponentLoader)}. * * @since 1.48.0 */ public OtlpGrpcLogRecordExporterBuilder setServiceClassLoader(ClassLoader serviceClassLoader) { requireNonNull(serviceClassLoader, "serviceClassLoader"); - delegate.setServiceClassLoader(serviceClassLoader); + return setComponentLoader(ComponentLoader.forClassLoader(serviceClassLoader)); + } + + /** Set the {@link ComponentLoader} used to load the sender API. */ + public OtlpGrpcLogRecordExporterBuilder setComponentLoader(ComponentLoader componentLoader) { + requireNonNull(componentLoader, "componentLoader"); + delegate.setComponentLoader(componentLoader); return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java index e787408331..ef3403c735 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java @@ -11,6 +11,7 @@ import static java.util.Objects.requireNonNull; import io.grpc.ManagedChannel; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; import io.opentelemetry.exporter.internal.marshal.Marshaler; @@ -329,13 +330,20 @@ public final class OtlpGrpcMetricExporterBuilder { } /** - * Set the {@link ClassLoader} used to load the sender API. + * Set the {@link ClassLoader} used to load the sender API. Variant of {@link + * #setComponentLoader(ComponentLoader)}. * * @since 1.48.0 */ public OtlpGrpcMetricExporterBuilder setServiceClassLoader(ClassLoader serviceClassLoader) { requireNonNull(serviceClassLoader, "serviceClassLoader"); - delegate.setServiceClassLoader(serviceClassLoader); + return setComponentLoader(ComponentLoader.forClassLoader(serviceClassLoader)); + } + + /** Set the {@link ComponentLoader} used to load the sender API. */ + public OtlpGrpcMetricExporterBuilder setComponentLoader(ComponentLoader componentLoader) { + requireNonNull(componentLoader, "componentLoader"); + delegate.setComponentLoader(componentLoader); return this; } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java index d145ed5b06..fa7523b5b9 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/trace/OtlpGrpcSpanExporterBuilder.java @@ -11,6 +11,7 @@ import static java.util.Objects.requireNonNull; import io.grpc.ManagedChannel; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; import io.opentelemetry.exporter.internal.marshal.Marshaler; @@ -268,13 +269,20 @@ public final class OtlpGrpcSpanExporterBuilder { } /** - * Set the {@link ClassLoader} used to load the sender API. + * Set the {@link ClassLoader} used to load the sender API. Variant of {@link + * #setComponentLoader(ComponentLoader)}. * * @since 1.48.0 */ public OtlpGrpcSpanExporterBuilder setServiceClassLoader(ClassLoader serviceClassLoader) { requireNonNull(serviceClassLoader, "serviceClassLoader"); - delegate.setServiceClassLoader(serviceClassLoader); + return setComponentLoader(ComponentLoader.forClassLoader(serviceClassLoader)); + } + + /** Set the {@link ComponentLoader} used to load the sender API. */ + public OtlpGrpcSpanExporterBuilder setComponentLoader(ComponentLoader componentLoader) { + requireNonNull(componentLoader, "componentLoader"); + delegate.setComponentLoader(componentLoader); return this; } diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtilTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtilTest.java index 5716d604ec..fb1061ae3f 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtilTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpConfigUtilTest.java @@ -371,6 +371,7 @@ class OtlpConfigUtilTest { OtlpConfigUtil.configureOtlpExporterBuilder( dataType, DefaultConfigProperties.createFromMap(properties), + value -> {}, endpoint::set, (value1, value2) -> {}, value -> {}, diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProviderTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProviderTest.java index 47ed7859cd..9fe5bad768 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProviderTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpLogRecordExporterProviderTest.java @@ -122,6 +122,7 @@ class OtlpLogRecordExporterProviderTest { provider.createExporter(DefaultConfigProperties.createFromMap(Collections.emptyMap()))) { assertThat(exporter).isInstanceOf(OtlpGrpcLogRecordExporter.class); verify(grpcBuilder, times(1)).build(); + verify(grpcBuilder).setComponentLoader(any()); verify(grpcBuilder, never()).setEndpoint(any()); verify(grpcBuilder, never()).addHeader(any(), any()); verify(grpcBuilder, never()).setCompression(any()); @@ -154,6 +155,7 @@ class OtlpLogRecordExporterProviderTest { provider.createExporter(DefaultConfigProperties.createFromMap(config))) { assertThat(exporter).isInstanceOf(OtlpGrpcLogRecordExporter.class); verify(grpcBuilder, times(1)).build(); + verify(grpcBuilder).setComponentLoader(any()); verify(grpcBuilder).setEndpoint("https://localhost:443/"); verify(grpcBuilder).addHeader("header-key", "header-value"); verify(grpcBuilder).setCompression("gzip"); @@ -189,6 +191,7 @@ class OtlpLogRecordExporterProviderTest { provider.createExporter(DefaultConfigProperties.createFromMap(config))) { assertThat(exporter).isInstanceOf(OtlpGrpcLogRecordExporter.class); verify(grpcBuilder, times(1)).build(); + verify(grpcBuilder).setComponentLoader(any()); verify(grpcBuilder).setEndpoint("https://localhost:443/"); verify(grpcBuilder).addHeader("header-key", "header-value"); verify(grpcBuilder).setCompression("gzip"); diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProviderTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProviderTest.java index 3d0a409832..e028c6a957 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProviderTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpMetricExporterProviderTest.java @@ -121,6 +121,7 @@ class OtlpMetricExporterProviderTest { provider.createExporter(DefaultConfigProperties.createFromMap(Collections.emptyMap()))) { assertThat(exporter).isInstanceOf(OtlpGrpcMetricExporter.class); verify(grpcBuilder, times(1)).build(); + verify(grpcBuilder).setComponentLoader(any()); verify(grpcBuilder, never()).setEndpoint(any()); verify(grpcBuilder, never()).addHeader(any(), any()); verify(grpcBuilder, never()).setCompression(any()); @@ -149,6 +150,7 @@ class OtlpMetricExporterProviderTest { provider.createExporter(DefaultConfigProperties.createFromMap(config))) { assertThat(exporter).isInstanceOf(OtlpGrpcMetricExporter.class); verify(grpcBuilder, times(1)).build(); + verify(grpcBuilder).setComponentLoader(any()); verify(grpcBuilder).setEndpoint("https://localhost:443/"); verify(grpcBuilder).addHeader("header-key", "header-value"); verify(grpcBuilder).setCompression("gzip"); @@ -184,6 +186,7 @@ class OtlpMetricExporterProviderTest { provider.createExporter(DefaultConfigProperties.createFromMap(config))) { assertThat(exporter).isInstanceOf(OtlpGrpcMetricExporter.class); verify(grpcBuilder, times(1)).build(); + verify(grpcBuilder).setComponentLoader(any()); verify(grpcBuilder).setEndpoint("https://localhost:443/"); verify(grpcBuilder).addHeader("header-key", "header-value"); verify(grpcBuilder).setCompression("gzip"); @@ -205,6 +208,7 @@ class OtlpMetricExporterProviderTest { "otel.exporter.otlp.metrics.protocol", "http/protobuf")))) { assertThat(exporter).isInstanceOf(OtlpHttpMetricExporter.class); verify(httpBuilder, times(1)).build(); + verify(httpBuilder).setComponentLoader(any()); verify(httpBuilder, never()).setEndpoint(any()); verify(httpBuilder, never()).addHeader(any(), any()); verify(httpBuilder, never()).setCompression(any()); @@ -234,6 +238,7 @@ class OtlpMetricExporterProviderTest { provider.createExporter(DefaultConfigProperties.createFromMap(config))) { assertThat(exporter).isInstanceOf(OtlpHttpMetricExporter.class); verify(httpBuilder, times(1)).build(); + verify(httpBuilder).setComponentLoader(any()); verify(httpBuilder).setEndpoint("https://localhost:443/v1/metrics"); verify(httpBuilder).addHeader("header-key", "header-value"); verify(httpBuilder).setCompression("gzip"); @@ -271,6 +276,7 @@ class OtlpMetricExporterProviderTest { provider.createExporter(DefaultConfigProperties.createFromMap(config))) { assertThat(exporter).isInstanceOf(OtlpHttpMetricExporter.class); verify(httpBuilder, times(1)).build(); + verify(httpBuilder).setComponentLoader(any()); verify(httpBuilder).setEndpoint("https://localhost:443/v1/metrics"); verify(httpBuilder).addHeader("header-key", "header-value"); verify(httpBuilder).setCompression("gzip"); diff --git a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProviderTest.java b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProviderTest.java index 46d2e8ea21..1454d209da 100644 --- a/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProviderTest.java +++ b/exporters/otlp/all/src/test/java/io/opentelemetry/exporter/otlp/internal/OtlpSpanExporterProviderTest.java @@ -123,6 +123,7 @@ class OtlpSpanExporterProviderTest { provider.createExporter(DefaultConfigProperties.createFromMap(Collections.emptyMap()))) { assertThat(exporter).isInstanceOf(OtlpGrpcSpanExporter.class); verify(grpcBuilder, times(1)).build(); + verify(grpcBuilder).setComponentLoader(any()); verify(grpcBuilder, never()).setEndpoint(any()); verify(grpcBuilder, never()).addHeader(any(), any()); verify(grpcBuilder, never()).setCompression(any()); @@ -155,6 +156,7 @@ class OtlpSpanExporterProviderTest { provider.createExporter(DefaultConfigProperties.createFromMap(config))) { assertThat(exporter).isInstanceOf(OtlpGrpcSpanExporter.class); verify(grpcBuilder, times(1)).build(); + verify(grpcBuilder).setComponentLoader(any()); verify(grpcBuilder).setEndpoint("https://localhost:443/"); verify(grpcBuilder).addHeader("header-key", "header-value"); verify(grpcBuilder).setCompression("gzip"); @@ -190,6 +192,7 @@ class OtlpSpanExporterProviderTest { provider.createExporter(DefaultConfigProperties.createFromMap(config))) { assertThat(exporter).isInstanceOf(OtlpGrpcSpanExporter.class); verify(grpcBuilder, times(1)).build(); + verify(grpcBuilder).setComponentLoader(any()); verify(grpcBuilder).setEndpoint("https://localhost:443/"); verify(grpcBuilder).addHeader("header-key", "header-value"); verify(grpcBuilder).setCompression("gzip"); @@ -210,6 +213,7 @@ class OtlpSpanExporterProviderTest { Collections.singletonMap("otel.exporter.otlp.traces.protocol", "http/protobuf")))) { assertThat(exporter).isInstanceOf(OtlpHttpSpanExporter.class); verify(httpBuilder, times(1)).build(); + verify(httpBuilder).setComponentLoader(any()); verify(httpBuilder, never()).setEndpoint(any()); verify(httpBuilder, never()).addHeader(any(), any()); verify(httpBuilder, never()).setCompression(any()); @@ -240,6 +244,7 @@ class OtlpSpanExporterProviderTest { provider.createExporter(DefaultConfigProperties.createFromMap(config))) { assertThat(exporter).isInstanceOf(OtlpHttpSpanExporter.class); verify(httpBuilder, times(1)).build(); + verify(httpBuilder).setComponentLoader(any()); verify(httpBuilder).setEndpoint("https://localhost:443/v1/traces"); verify(httpBuilder).addHeader("header-key1", "header value1"); verify(httpBuilder).addHeader("header-key2", "header value2"); @@ -279,6 +284,7 @@ class OtlpSpanExporterProviderTest { provider.createExporter(DefaultConfigProperties.createFromMap(config))) { assertThat(exporter).isInstanceOf(OtlpHttpSpanExporter.class); verify(httpBuilder, times(1)).build(); + verify(httpBuilder).setComponentLoader(any()); verify(httpBuilder).setEndpoint("https://localhost:443/v1/traces"); verify(httpBuilder).addHeader("header-key", "header-value"); verify(httpBuilder).setCompression("gzip"); diff --git a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfilesExporterBuilder.java b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfilesExporterBuilder.java index 0489cb25f9..18e19ca51b 100644 --- a/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfilesExporterBuilder.java +++ b/exporters/otlp/profiles/src/main/java/io/opentelemetry/exporter/otlp/profiles/OtlpGrpcProfilesExporterBuilder.java @@ -10,6 +10,7 @@ import static java.util.Objects.requireNonNull; import io.grpc.ManagedChannel; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.exporter.internal.compression.Compressor; import io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder; import io.opentelemetry.exporter.internal.marshal.Marshaler; @@ -201,10 +202,19 @@ public final class OtlpGrpcProfilesExporterBuilder { return this; } - /** Set the {@link ClassLoader} used to load the sender API. */ + /** + * Set the {@link ClassLoader} used to load the sender API. Variant of {@link + * #setComponentLoader(ComponentLoader)}. + */ public OtlpGrpcProfilesExporterBuilder setServiceClassLoader(ClassLoader serviceClassLoader) { requireNonNull(serviceClassLoader, "serviceClassLoader"); - delegate.setServiceClassLoader(serviceClassLoader); + return setComponentLoader(ComponentLoader.forClassLoader(serviceClassLoader)); + } + + /** Set the {@link ComponentLoader} used to load the sender API. */ + public OtlpGrpcProfilesExporterBuilder setComponentLoader(ComponentLoader componentLoader) { + requireNonNull(componentLoader, "componentLoader"); + delegate.setComponentLoader(componentLoader); return this; } diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/ConfigProperties.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/ConfigProperties.java index 9480b66ac8..0485597edc 100644 --- a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/ConfigProperties.java +++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/ConfigProperties.java @@ -7,6 +7,7 @@ package io.opentelemetry.sdk.autoconfigure.spi; import static io.opentelemetry.api.internal.ConfigUtil.defaultIfNull; +import io.opentelemetry.common.ComponentLoader; import java.time.Duration; import java.util.List; import java.util.Map; @@ -204,4 +205,9 @@ public interface ConfigProperties { Map value = getMap(name); return value.isEmpty() ? defaultValue : value; } + + /** Return a {@link ComponentLoader} that should be used to load SPIs. */ + default ComponentLoader getComponentLoader() { + return ComponentLoader.forClassLoader(ConfigProperties.class.getClassLoader()); + } } diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/DefaultConfigProperties.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/DefaultConfigProperties.java index b5496df7c4..f8818c015b 100644 --- a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/DefaultConfigProperties.java +++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/DefaultConfigProperties.java @@ -10,6 +10,7 @@ import static java.util.stream.Collectors.joining; import io.opentelemetry.api.internal.ConfigUtil; import io.opentelemetry.api.internal.StringUtils; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import java.time.Duration; @@ -38,6 +39,7 @@ import javax.annotation.Nullable; public final class DefaultConfigProperties implements ConfigProperties { private final Map config; + private final ComponentLoader componentLoader; /** * Creates a {@link DefaultConfigProperties} by merging system properties, environment variables, @@ -46,9 +48,10 @@ public final class DefaultConfigProperties implements ConfigProperties { *

Environment variables take priority over {@code defaultProperties}. System properties take * priority over environment variables. */ - public static DefaultConfigProperties create(Map defaultProperties) { + public static DefaultConfigProperties create( + Map defaultProperties, ComponentLoader componentLoader) { return new DefaultConfigProperties( - ConfigUtil.safeSystemProperties(), System.getenv(), defaultProperties); + ConfigUtil.safeSystemProperties(), System.getenv(), defaultProperties, componentLoader); } /** @@ -56,13 +59,18 @@ public final class DefaultConfigProperties implements ConfigProperties { * properties and environment variables. */ public static DefaultConfigProperties createFromMap(Map properties) { - return new DefaultConfigProperties(properties, Collections.emptyMap(), Collections.emptyMap()); + return new DefaultConfigProperties( + properties, + Collections.emptyMap(), + Collections.emptyMap(), + ComponentLoader.forClassLoader(DefaultConfigProperties.class.getClassLoader())); } private DefaultConfigProperties( Map systemProperties, Map environmentVariables, - Map defaultProperties) { + Map defaultProperties, + ComponentLoader componentLoader) { Map config = new HashMap<>(); defaultProperties.forEach( (name, value) -> config.put(ConfigUtil.normalizePropertyKey(name), value)); @@ -73,6 +81,7 @@ public final class DefaultConfigProperties implements ConfigProperties { config.put(ConfigUtil.normalizePropertyKey(key.toString()), value.toString())); this.config = config; + this.componentLoader = componentLoader; } private DefaultConfigProperties( @@ -82,6 +91,7 @@ public final class DefaultConfigProperties implements ConfigProperties { overrides.forEach((name, value) -> config.put(ConfigUtil.normalizePropertyKey(name), value)); this.config = config; + this.componentLoader = previousProperties.componentLoader; } @Override @@ -233,6 +243,11 @@ public final class DefaultConfigProperties implements ConfigProperties { Map.Entry::getKey, Map.Entry::getValue, (first, next) -> next, LinkedHashMap::new)); } + @Override + public ComponentLoader getComponentLoader() { + return componentLoader; + } + /** * Return a new {@link DefaultConfigProperties} by overriding the {@code previousProperties} with * the {@code overrides}. diff --git a/sdk-extensions/autoconfigure-spi/src/test/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ConfigPropertiesTest.java b/sdk-extensions/autoconfigure-spi/src/test/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ConfigPropertiesTest.java index 78cc6806c0..4a119e600c 100644 --- a/sdk-extensions/autoconfigure-spi/src/test/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ConfigPropertiesTest.java +++ b/sdk-extensions/autoconfigure-spi/src/test/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ConfigPropertiesTest.java @@ -11,6 +11,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.entry; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import java.time.Duration; @@ -22,6 +23,9 @@ import org.junit.jupiter.api.Test; class ConfigPropertiesTest { + private static final ComponentLoader COMPONENT_LOADER = + ComponentLoader.forClassLoader(ConfigPropertiesTest.class.getClassLoader()); + @Test void allValid() { Map properties = makeTestProps(); @@ -246,7 +250,7 @@ class ConfigPropertiesTest { expectedMap.put("bear", "growl"); Map map = makeTestProps(); - ConfigProperties properties = DefaultConfigProperties.create(map); + ConfigProperties properties = DefaultConfigProperties.create(map, COMPONENT_LOADER); assertThat(properties.getBoolean("test.boolean", false)).isTrue(); assertThat(properties.getString("test.string", "nah")).isEqualTo("str"); assertThat(properties.getDouble("test.double", 65.535)).isEqualTo(5.4); @@ -260,7 +264,7 @@ class ConfigPropertiesTest { @Test void defaultMethodsFallBack() { - ConfigProperties properties = DefaultConfigProperties.create(emptyMap()); + ConfigProperties properties = DefaultConfigProperties.create(emptyMap(), COMPONENT_LOADER); assertThat(properties.getBoolean("foo", true)).isTrue(); assertThat(properties.getString("foo", "bar")).isEqualTo("bar"); assertThat(properties.getDouble("foo", 65.535)).isEqualTo(65.535); @@ -271,7 +275,7 @@ class ConfigPropertiesTest { @Test void defaultCollectionTypes() { - ConfigProperties properties = DefaultConfigProperties.create(emptyMap()); + ConfigProperties properties = DefaultConfigProperties.create(emptyMap(), COMPONENT_LOADER); assertThat(properties.getList("foo", Arrays.asList("1", "2", "3"))) .containsExactly("1", "2", "3"); assertThat(properties.getList("foo")).isEmpty(); diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java index 124231fa32..1b0e43c1f1 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java @@ -8,11 +8,11 @@ package io.opentelemetry.sdk.autoconfigure; import static java.util.Objects.requireNonNull; import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.context.propagation.ContextPropagators; import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.OpenTelemetrySdkBuilder; -import io.opentelemetry.sdk.autoconfigure.internal.ComponentLoader; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer; import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider; @@ -117,7 +117,7 @@ public final class AutoConfiguredOpenTelemetrySdkBuilder implements AutoConfigur Function.identity(); private ComponentLoader componentLoader = - SpiHelper.serviceComponentLoader(AutoConfiguredOpenTelemetrySdk.class.getClassLoader()); + ComponentLoader.forClassLoader(AutoConfiguredOpenTelemetrySdk.class.getClassLoader()); private boolean registerShutdownHook = true; @@ -410,12 +410,12 @@ public final class AutoConfiguredOpenTelemetrySdkBuilder implements AutoConfigur public AutoConfiguredOpenTelemetrySdkBuilder setServiceClassLoader( ClassLoader serviceClassLoader) { requireNonNull(serviceClassLoader, "serviceClassLoader"); - this.componentLoader = SpiHelper.serviceComponentLoader(serviceClassLoader); + this.componentLoader = ComponentLoader.forClassLoader(serviceClassLoader); return this; } /** Sets the {@link ComponentLoader} to be used to load SPI implementations. */ - AutoConfiguredOpenTelemetrySdkBuilder setComponentLoader(ComponentLoader componentLoader) { + public AutoConfiguredOpenTelemetrySdkBuilder setComponentLoader(ComponentLoader componentLoader) { requireNonNull(componentLoader, "componentLoader"); this.componentLoader = componentLoader; return this; @@ -628,7 +628,8 @@ public final class AutoConfiguredOpenTelemetrySdkBuilder implements AutoConfigur } private ConfigProperties computeConfigProperties() { - DefaultConfigProperties properties = DefaultConfigProperties.create(propertiesSupplier.get()); + DefaultConfigProperties properties = + DefaultConfigProperties.create(propertiesSupplier.get(), componentLoader); for (Function> customizer : propertiesCustomizers) { Map overrides = customizer.apply(properties); properties = properties.withOverrides(overrides); diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/IncubatingUtil.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/IncubatingUtil.java index a1280e241d..df2686ece5 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/IncubatingUtil.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/IncubatingUtil.java @@ -8,8 +8,8 @@ package io.opentelemetry.sdk.autoconfigure; import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.api.incubator.config.GlobalConfigProvider; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.autoconfigure.internal.ComponentLoader; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.resources.Resource; import java.io.FileInputStream; @@ -51,8 +51,9 @@ final class IncubatingUtil { Class sdkConfigProvider = Class.forName("io.opentelemetry.sdk.extension.incubator.fileconfig.SdkConfigProvider"); Method createFileConfigProvider = - sdkConfigProvider.getMethod("create", openTelemetryConfiguration); - ConfigProvider configProvider = (ConfigProvider) createFileConfigProvider.invoke(null, model); + sdkConfigProvider.getMethod("create", openTelemetryConfiguration, ComponentLoader.class); + ConfigProvider configProvider = + (ConfigProvider) createFileConfigProvider.invoke(null, model, componentLoader); // Note: can't access file configuration resource without reflection so setting a dummy // resource return AutoConfiguredOpenTelemetrySdk.create( diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ResourceConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ResourceConfiguration.java index 8e00ee19ab..6f15adfc03 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ResourceConfiguration.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ResourceConfiguration.java @@ -8,6 +8,7 @@ package io.opentelemetry.sdk.autoconfigure; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.AttributesBuilder; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; @@ -59,7 +60,10 @@ public final class ResourceConfiguration { * @return the resource. */ public static Resource createEnvironmentResource() { - return createEnvironmentResource(DefaultConfigProperties.create(Collections.emptyMap())); + return createEnvironmentResource( + DefaultConfigProperties.create( + Collections.emptyMap(), + ComponentLoader.forClassLoader(ResourceConfiguration.class.getClassLoader()))); } /** diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/AutoConfigureUtil.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/AutoConfigureUtil.java index 52f0236e8d..8bf42005ba 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/AutoConfigureUtil.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/AutoConfigureUtil.java @@ -59,22 +59,6 @@ public final class AutoConfigureUtil { } } - /** Sets the {@link ComponentLoader} to be used in the auto-configuration process. */ - public static AutoConfiguredOpenTelemetrySdkBuilder setComponentLoader( - AutoConfiguredOpenTelemetrySdkBuilder builder, ComponentLoader componentLoader) { - try { - Method method = - AutoConfiguredOpenTelemetrySdkBuilder.class.getDeclaredMethod( - "setComponentLoader", ComponentLoader.class); - method.setAccessible(true); - method.invoke(builder, componentLoader); - return builder; - } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { - throw new IllegalStateException( - "Error calling setComponentLoader on AutoConfiguredOpenTelemetrySdkBuilder", e); - } - } - /** Sets the {@link ConfigProperties} customizer to be used in the auto-configuration process. */ public static AutoConfiguredOpenTelemetrySdkBuilder setConfigPropertiesCustomizer( AutoConfiguredOpenTelemetrySdkBuilder builder, diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/ComponentLoader.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/ComponentLoader.java index 49bfc4e52f..b7f29db27e 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/ComponentLoader.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/ComponentLoader.java @@ -10,14 +10,9 @@ package io.opentelemetry.sdk.autoconfigure.internal; * *

This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. + * + * @deprecated Use {@link io.opentelemetry.common.ComponentLoader} instead */ -public interface ComponentLoader { - /** - * Load implementations of an SPI. - * - * @param spiClass the SPI class - * @param the SPI type - * @return iterable of SPI implementations - */ - Iterable load(Class spiClass); -} +@Deprecated +// TODO(jack-berg): delete after 1.54.0 release +public interface ComponentLoader extends io.opentelemetry.common.ComponentLoader {} diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java index db4ca4ff64..d1d00aed57 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java @@ -5,6 +5,7 @@ package io.opentelemetry.sdk.autoconfigure.internal; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.Ordered; import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener; @@ -15,7 +16,6 @@ import java.util.HashMap; import java.util.IdentityHashMap; import java.util.List; import java.util.Map; -import java.util.ServiceLoader; import java.util.Set; import java.util.function.BiFunction; import java.util.function.Function; @@ -37,7 +37,7 @@ public final class SpiHelper { /** Create a {@link SpiHelper} which loads SPIs using the {@code classLoader}. */ public static SpiHelper create(ClassLoader classLoader) { - return new SpiHelper(serviceComponentLoader(classLoader)); + return new SpiHelper(ComponentLoader.forClassLoader(classLoader)); } /** Create a {@link SpiHelper} which loads SPIs using the {@code componentLoader}. */ @@ -45,11 +45,6 @@ public final class SpiHelper { return new SpiHelper(componentLoader); } - /** Create a {@link ComponentLoader} which loads using the {@code classLoader}. */ - public static ComponentLoader serviceComponentLoader(ClassLoader classLoader) { - return new ServiceLoaderComponentLoader(classLoader); - } - /** Return the backing underlying {@link ComponentLoader}. */ public ComponentLoader getComponentLoader() { return componentLoader; @@ -125,17 +120,4 @@ public final class SpiHelper { public Set getListeners() { return Collections.unmodifiableSet(listeners); } - - private static class ServiceLoaderComponentLoader implements ComponentLoader { - private final ClassLoader classLoader; - - private ServiceLoaderComponentLoader(ClassLoader classLoader) { - this.classLoader = classLoader; - } - - @Override - public Iterable load(Class spiClass) { - return ServiceLoader.load(spiClass, classLoader); - } - } } diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java index 45d2630832..3283cd8af6 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java @@ -28,6 +28,7 @@ import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanId; import io.opentelemetry.api.trace.TraceId; import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.context.Context; import io.opentelemetry.context.ContextKey; import io.opentelemetry.context.propagation.TextMapGetter; @@ -35,7 +36,6 @@ import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.internal.AutoConfigureUtil; -import io.opentelemetry.sdk.autoconfigure.internal.ComponentLoader; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; @@ -65,6 +65,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Properties; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; @@ -255,22 +256,28 @@ class AutoConfiguredOpenTelemetrySdkTest { SpiHelper spiHelper = SpiHelper.create(AutoConfiguredOpenTelemetrySdkBuilder.class.getClassLoader()); - AutoConfigureUtil.setComponentLoader( - builder, - new ComponentLoader() { - @SuppressWarnings("unchecked") - @Override - public Iterable load(Class spiClass) { - if (spiClass.equals(AutoConfigurationCustomizerProvider.class)) { - return Collections.singletonList((T) customizerProvider); - } - return spiHelper.load(spiClass); - } - }) - .build(); + ComponentLoader componentLoader = + new ComponentLoader() { + @SuppressWarnings("unchecked") + @Override + public Iterable load(Class spiClass) { + if (spiClass.equals(AutoConfigurationCustomizerProvider.class)) { + return Collections.singletonList((T) customizerProvider); + } + return spiHelper.load(spiClass); + } + }; + AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk = + builder.setComponentLoader(componentLoader).build(); + + assertThat( + Objects.requireNonNull(autoConfiguredOpenTelemetrySdk.getConfig()).getComponentLoader()) + .isSameAs(componentLoader); verify(customizerProvider).customize(any()); verifyNoMoreInteractions(customizerProvider); + + autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk().shutdown().join(10, TimeUnit.SECONDS); } @Test diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java index e2c94a68aa..1678fb2957 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java @@ -12,6 +12,7 @@ import static java.util.Collections.singletonMap; import com.google.common.collect.ImmutableMap; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; @@ -25,6 +26,9 @@ import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) class ResourceConfigurationTest { + private static final ComponentLoader componentLoader = + ComponentLoader.forClassLoader(ResourceConfigurationTest.class.getClassLoader()); + @Test void customConfigResourceWithDisabledKeys() { Map props = new HashMap<>(); @@ -35,7 +39,7 @@ class ResourceConfigurationTest { assertThat( ResourceConfiguration.configureResource( - DefaultConfigProperties.create(props), + DefaultConfigProperties.create(props, componentLoader), SpiHelper.create(ResourceConfigurationTest.class.getClassLoader()), (r, c) -> r)) .isEqualTo( diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelperTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelperTest.java index ad7a96704e..b1497079a9 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelperTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelperTest.java @@ -15,6 +15,7 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java index ae2342aeff..8683dd6de3 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java @@ -9,6 +9,7 @@ import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.asser import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; @@ -29,14 +30,15 @@ import org.junit.jupiter.params.provider.MethodSource; @SuppressLogger(ResourceConfiguration.class) class ResourceConfigurationTest { - private final SpiHelper spiHelper = - SpiHelper.create(ResourceConfigurationTest.class.getClassLoader()); + private final ComponentLoader componentLoader = + ComponentLoader.forClassLoader(ResourceConfigurationTest.class.getClassLoader()); + private final SpiHelper spiHelper = SpiHelper.create(componentLoader); @Test void configureResource_EmptyClassLoader() { Attributes attributes = ResourceConfiguration.configureResource( - DefaultConfigProperties.create(Collections.emptyMap()), + DefaultConfigProperties.create(Collections.emptyMap(), componentLoader), SpiHelper.create(new URLClassLoader(new URL[0], null)), (r, c) -> r) .getAttributes(); @@ -66,7 +68,7 @@ class ResourceConfigurationTest { } Attributes attributes = ResourceConfiguration.configureResource( - DefaultConfigProperties.create(config), spiHelper, (r, c) -> r) + DefaultConfigProperties.create(config, componentLoader), spiHelper, (r, c) -> r) .getAttributes(); attributeAssertion.accept(assertThat(attributes)); diff --git a/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationTest.java b/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationTest.java index f92c1027cc..a29a9f581d 100644 --- a/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationTest.java @@ -7,6 +7,7 @@ package io.opentelemetry.sdk.autoconfigure; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static java.util.Collections.singletonMap; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; @@ -23,6 +24,7 @@ import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.api.incubator.config.GlobalConfigProvider; import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.exporter.logging.LoggingSpanExporter; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.internal.testing.slf4j.SuppressLogger; @@ -40,7 +42,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays; import java.util.Collections; -import org.assertj.core.api.Assertions; +import java.util.Optional; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -134,17 +136,39 @@ class DeclarativeConfigurationTest { builder.setConfig(config).build(); cleanup.addCloseable(autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk()); - Assertions.assertThat(autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk().toString()) + assertThat(autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk().toString()) .isEqualTo(expectedSdk.toString()); // AutoConfiguredOpenTelemetrySdk#getResource() is set to a dummy value when configuring from // file - Assertions.assertThat(autoConfiguredOpenTelemetrySdk.getResource()) - .isEqualTo(Resource.getDefault()); + assertThat(autoConfiguredOpenTelemetrySdk.getResource()).isEqualTo(Resource.getDefault()); verify(builder, times(1)).shutdownHook(autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk()); - Assertions.assertThat(Runtime.getRuntime().removeShutdownHook(thread)).isTrue(); + assertThat(Runtime.getRuntime().removeShutdownHook(thread)).isTrue(); logCapturer.assertContains("Autoconfiguring from configuration file: " + configFilePath); } + @Test + void configFile_setComponentLoader() { + ComponentLoader componentLoader = + ComponentLoader.forClassLoader(DeclarativeConfigurationTest.class.getClassLoader()); + ConfigProperties config = + DefaultConfigProperties.createFromMap( + Collections.singletonMap("otel.experimental.config.file", configFilePath.toString())); + + AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk = + AutoConfiguredOpenTelemetrySdk.builder() + .setConfig(config) + .setComponentLoader(componentLoader) + .build(); + cleanup.addCloseable(autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk()); + + assertThat( + Optional.ofNullable(AutoConfigureUtil.getConfigProvider(autoConfiguredOpenTelemetrySdk)) + .map(ConfigProvider::getInstrumentationConfig) + .map(DeclarativeConfigProperties::getComponentLoader) + .orElse(null)) + .isSameAs(componentLoader); + } + @Test void configFile_NoShutdownHook() { ConfigProperties config = @@ -171,9 +195,7 @@ class DeclarativeConfigurationTest { OpenTelemetrySdk openTelemetrySdk = autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk(); cleanup.addCloseable(openTelemetrySdk); - Assertions.assertThat(GlobalOpenTelemetry.get()) - .extracting("delegate") - .isNotSameAs(openTelemetrySdk); + assertThat(GlobalOpenTelemetry.get()).extracting("delegate").isNotSameAs(openTelemetrySdk); assertThat(GlobalConfigProvider.get()) .isNotSameAs(autoConfiguredOpenTelemetrySdk.getConfigProvider()); } @@ -189,9 +211,7 @@ class DeclarativeConfigurationTest { OpenTelemetrySdk openTelemetrySdk = autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk(); cleanup.addCloseable(openTelemetrySdk); - Assertions.assertThat(GlobalOpenTelemetry.get()) - .extracting("delegate") - .isSameAs(openTelemetrySdk); + assertThat(GlobalOpenTelemetry.get()).extracting("delegate").isSameAs(openTelemetrySdk); assertThat(GlobalConfigProvider.get()) .isSameAs(autoConfiguredOpenTelemetrySdk.getConfigProvider()); } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfiguration.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfiguration.java index b06b36ee9b..494138bdaa 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfiguration.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfiguration.java @@ -11,8 +11,8 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.autoconfigure.internal.ComponentLoader; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; @@ -57,7 +57,7 @@ public final class DeclarativeConfiguration { private static final Pattern ENV_VARIABLE_REFERENCE = Pattern.compile("\\$\\{([a-zA-Z_][a-zA-Z0-9_]*)(:-([^\n}]*))?}"); private static final ComponentLoader DEFAULT_COMPONENT_LOADER = - SpiHelper.serviceComponentLoader(DeclarativeConfiguration.class.getClassLoader()); + ComponentLoader.forClassLoader(DeclarativeConfigProperties.class.getClassLoader()); // Visible for testing static final ObjectMapper MAPPER; diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SdkConfigProvider.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SdkConfigProvider.java index d23c379961..9bc5192a78 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SdkConfigProvider.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SdkConfigProvider.java @@ -7,6 +7,7 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; import javax.annotation.Nullable; @@ -15,9 +16,10 @@ public final class SdkConfigProvider implements ConfigProvider { @Nullable private final DeclarativeConfigProperties instrumentationConfig; - private SdkConfigProvider(OpenTelemetryConfigurationModel model) { + private SdkConfigProvider( + OpenTelemetryConfigurationModel model, ComponentLoader componentLoader) { DeclarativeConfigProperties configProperties = - DeclarativeConfiguration.toConfigProperties(model); + DeclarativeConfiguration.toConfigProperties(model, componentLoader); this.instrumentationConfig = configProperties.getStructured("instrumentation/development"); } @@ -28,7 +30,19 @@ public final class SdkConfigProvider implements ConfigProvider { * @return the {@link SdkConfigProvider} */ public static SdkConfigProvider create(OpenTelemetryConfigurationModel model) { - return new SdkConfigProvider(model); + return create(model, ComponentLoader.forClassLoader(SdkConfigProvider.class.getClassLoader())); + } + + /** + * Create a {@link SdkConfigProvider} from the {@code model}. + * + * @param model the configuration model + * @param componentLoader the component loader used to load SPIs + * @return the {@link SdkConfigProvider} + */ + public static SdkConfigProvider create( + OpenTelemetryConfigurationModel model, ComponentLoader componentLoader) { + return new SdkConfigProvider(model, componentLoader); } @Nullable diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ServiceResourceDetector.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ServiceResourceDetector.java index a8077032ec..dcaeeee271 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ServiceResourceDetector.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ServiceResourceDetector.java @@ -38,7 +38,8 @@ public class ServiceResourceDetector implements ComponentProvider { public Resource create(DeclarativeConfigProperties config) { ResourceBuilder builder = Resource.builder(); - ConfigProperties properties = DefaultConfigProperties.create(Collections.emptyMap()); + ConfigProperties properties = + DefaultConfigProperties.create(Collections.emptyMap(), config.getComponentLoader()); String serviceName = properties.getString("otel.service.name"); if (serviceName != null) { builder.put(SERVICE_NAME, serviceName).build(); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigProperties.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigProperties.java index 924d53b401..4be956af59 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigProperties.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/YamlDeclarativeConfigProperties.java @@ -10,7 +10,7 @@ import static java.util.stream.Collectors.toList; import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; -import io.opentelemetry.sdk.autoconfigure.internal.ComponentLoader; +import io.opentelemetry.common.ComponentLoader; import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashMap; @@ -303,6 +303,7 @@ public final class YamlDeclarativeConfigProperties implements DeclarativeConfigP } /** Return the {@link ComponentLoader}. */ + @Override public ComponentLoader getComponentLoader() { return componentLoader; } diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCreateTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCreateTest.java index 62ee078286..b72c0bc8eb 100644 --- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCreateTest.java +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigurationCreateTest.java @@ -13,9 +13,9 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension; import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.api.incubator.config.DeclarativeConfigException; +import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.internal.testing.CleanupExtension; import io.opentelemetry.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProviderModel; @@ -161,7 +161,7 @@ class DeclarativeConfigurationCreateTest { DeclarativeConfiguration.create( model, // customizer is TestDeclarativeConfigurationCustomizerProvider - SpiHelper.serviceComponentLoader( + ComponentLoader.forClassLoader( DeclarativeConfigurationCreateTest.class.getClassLoader())); assertThat(sdk.toString()) .contains( diff --git a/settings.gradle.kts b/settings.gradle.kts index 9dbea10ee4..eb92b193f2 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -28,6 +28,7 @@ include(":api:incubator") include(":api:testing-internal") include(":bom") include(":bom-alpha") +include(":common") include(":context") include(":custom-checks") include(":dependencyManagement")