diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 25d3d3ed4b4..78e6a0d15c3 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -10,6 +10,7 @@ rootProject.extra["versions"] = dependencyVersions val autoValueVersion = "1.11.1" val errorProneVersion = "2.48.0" +val groovyVersion = "4.0.25" val jmhVersion = "1.37" // Mockito 5.x.x requires Java 11 https://github.com/mockito/mockito/releases/tag/v5.0.0 val mockitoVersion = "4.11.0" @@ -88,6 +89,7 @@ val DEPENDENCIES = listOf( "io.opentracing:opentracing-noop:0.33.0", "junit:junit:4.13.2", "nl.jqno.equalsverifier:equalsverifier:3.19.4", + "org.apache.groovy:groovy:${groovyVersion}", "org.awaitility:awaitility:4.3.0", "org.codehaus.mojo:animal-sniffer-annotations:1.27", "org.jctools:jctools-core:4.0.6", diff --git a/sdk/all/build.gradle.kts b/sdk/all/build.gradle.kts index 3a19758f313..7515b0b974c 100644 --- a/sdk/all/build.gradle.kts +++ b/sdk/all/build.gradle.kts @@ -23,6 +23,7 @@ dependencies { testAnnotationProcessor("com.google.auto.value:auto-value") + testImplementation("org.apache.groovy:groovy") testImplementation(project(":sdk:testing")) jmh(project(":sdk:testing")) diff --git a/sdk/all/src/main/java/io/opentelemetry/sdk/OpenTelemetrySdkBuilder.java b/sdk/all/src/main/java/io/opentelemetry/sdk/OpenTelemetrySdkBuilder.java index c7168599554..b460778b527 100644 --- a/sdk/all/src/main/java/io/opentelemetry/sdk/OpenTelemetrySdkBuilder.java +++ b/sdk/all/src/main/java/io/opentelemetry/sdk/OpenTelemetrySdkBuilder.java @@ -10,12 +10,13 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.context.propagation.ContextPropagators; import io.opentelemetry.sdk.internal.OpenTelemetrySdkBuilderUtil; -import io.opentelemetry.sdk.internal.SdkConfigProvider; import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.trace.SdkTracerProvider; import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import javax.annotation.Nullable; /** A builder for configuring an {@link OpenTelemetrySdk}. */ @@ -28,16 +29,28 @@ public final class OpenTelemetrySdkBuilder { @Nullable private Object configProvider; private static final boolean INCUBATOR_AVAILABLE; + @Nullable private static final Method CREATE_EXTENDED_OPEN_TELEMETRY_SDK_METHOD; static { boolean incubatorAvailable = false; + Method createExtendedOpenTelemetrySdk = null; try { Class.forName("io.opentelemetry.api.incubator.ExtendedOpenTelemetry"); + createExtendedOpenTelemetrySdk = + Class.forName("io.opentelemetry.sdk.IncubatingUtil") + .getDeclaredMethod( + "createExtendedOpenTelemetrySdk", OpenTelemetrySdk.class, Object.class); incubatorAvailable = true; } catch (ClassNotFoundException e) { // Not available + } catch (NoSuchMethodException e) { + throw new IllegalStateException( + "IncubatingUtil.createExtendedOpenTelemetrySdk could not be found." + + " This is a bug in OpenTelemetry.", + e); } INCUBATOR_AVAILABLE = incubatorAvailable; + CREATE_EXTENDED_OPEN_TELEMETRY_SDK_METHOD = createExtendedOpenTelemetrySdk; } /** @@ -89,12 +102,13 @@ public OpenTelemetrySdkBuilder setPropagators(ContextPropagators propagators) { } /** - * Sets the {@link SdkConfigProvider} to use. + * Sets the SDK config provider to use. * *

This method is experimental so not public. You may reflectively call it using {@link - * OpenTelemetrySdkBuilderUtil#setConfigProvider(OpenTelemetrySdkBuilder, SdkConfigProvider)}. + * OpenTelemetrySdkBuilderUtil#setConfigProvider(OpenTelemetrySdkBuilder, + * io.opentelemetry.sdk.internal.SdkConfigProvider)}. */ - OpenTelemetrySdkBuilder setConfigProvider(SdkConfigProvider configProvider) { + OpenTelemetrySdkBuilder setConfigProvider(Object configProvider) { this.configProvider = requireNonNull(configProvider); return this; } @@ -143,7 +157,33 @@ public OpenTelemetrySdk build() { OpenTelemetrySdk openTelemetrySdk = new OpenTelemetrySdk(tracerProvider, meterProvider, loggerProvider, propagators); return INCUBATOR_AVAILABLE - ? IncubatingUtil.createExtendedOpenTelemetrySdk(openTelemetrySdk, configProvider) + ? createExtendedOpenTelemetrySdk(openTelemetrySdk, configProvider) : openTelemetrySdk; } + + private static OpenTelemetrySdk createExtendedOpenTelemetrySdk( + OpenTelemetrySdk openTelemetrySdk, @Nullable Object configProvider) { + try { + return (OpenTelemetrySdk) + requireNonNull(CREATE_EXTENDED_OPEN_TELEMETRY_SDK_METHOD) + .invoke(null, openTelemetrySdk, configProvider); + } catch (IllegalAccessException e) { + throw new IllegalStateException( + "IncubatingUtil.createExtendedOpenTelemetrySdk could not be invoked." + + " This is a bug in OpenTelemetry.", + e); + } catch (InvocationTargetException e) { + Throwable cause = e.getTargetException(); + if (cause instanceof RuntimeException) { + throw (RuntimeException) cause; + } + if (cause instanceof Error) { + throw (Error) cause; + } + throw new IllegalStateException( + "IncubatingUtil.createExtendedOpenTelemetrySdk failed." + + " This is a bug in OpenTelemetry.", + cause); + } + } } diff --git a/sdk/all/src/main/java/io/opentelemetry/sdk/internal/OpenTelemetrySdkBuilderUtil.java b/sdk/all/src/main/java/io/opentelemetry/sdk/internal/OpenTelemetrySdkBuilderUtil.java index ff017d64fc0..f34b645eea7 100644 --- a/sdk/all/src/main/java/io/opentelemetry/sdk/internal/OpenTelemetrySdkBuilderUtil.java +++ b/sdk/all/src/main/java/io/opentelemetry/sdk/internal/OpenTelemetrySdkBuilderUtil.java @@ -27,8 +27,7 @@ public static OpenTelemetrySdkBuilder setConfigProvider( OpenTelemetrySdkBuilder builder, SdkConfigProvider configProvider) { try { Method method = - OpenTelemetrySdkBuilder.class.getDeclaredMethod( - "setConfigProvider", SdkConfigProvider.class); + OpenTelemetrySdkBuilder.class.getDeclaredMethod("setConfigProvider", Object.class); method.setAccessible(true); method.invoke(builder, configProvider); } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { diff --git a/sdk/all/src/test/java/io/opentelemetry/sdk/OpenTelemetrySdkTest.java b/sdk/all/src/test/java/io/opentelemetry/sdk/OpenTelemetrySdkTest.java index c6a48a0dbad..bc416a7a74f 100644 --- a/sdk/all/src/test/java/io/opentelemetry/sdk/OpenTelemetrySdkTest.java +++ b/sdk/all/src/test/java/io/opentelemetry/sdk/OpenTelemetrySdkTest.java @@ -14,6 +14,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import groovy.lang.GroovyClassLoader; import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; @@ -138,6 +139,23 @@ void builder() { assertThat(openTelemetry.getPropagators()).isEqualTo(propagators); } + @Test + void builder_fromGroovyWithoutIncubator() throws Exception { + try (GroovyClassLoader groovyClassLoader = new GroovyClassLoader(getClass().getClassLoader())) { + Class groovyClass = + groovyClassLoader.parseClass( + "import io.opentelemetry.sdk.OpenTelemetrySdk\n" + + "class GroovyBuilderCaller {\n" + + " static Object buildSdk() {\n" + + " OpenTelemetrySdk.builder().build()\n" + + " }\n" + + "}\n"); + + assertThat(groovyClass.getMethod("buildSdk").invoke(null)) + .isInstanceOf(OpenTelemetrySdk.class); + } + } + @Test void getTracer() { assertThat(GlobalOpenTelemetry.getTracer("testTracer1"))