You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Make the OpenTelemetry plugin support two explicit runtime contracts without requiring the ADOT/global path to package an application-side OpenTelemetry SDK:
ADOT/global mode: the plugin layer and Java agent own provider integration. Function code must not need opentelemetry-sdk or initialize another provider.
Standalone/explicit mode: the application deliberately supplies the OpenTelemetry SDK, processors, and exporter.
This should align with the Python OTel package model introduced by aws/aws-durable-execution-sdk-python#646 while using a Java/Maven-appropriate artifact design.
Current state
The proposed plugin layer in #621 contains only the thin OTel plugin JAR. However, application-loaded plugin classes still reference SDK types:
InvocationOtelPlugin and ExecutionOtelPlugin expose SdkTracerProviderBuilder, store SdkTracerProvider, and call forceFlush().
Their global constructors create DeterministicIdGenerator, which implements the SDK IdGenerator interface.
The current Java conformance example explicitly packages opentelemetry-sdk, so it does not validate the thin plugin layer without an application SDK.
Consequently, packaging the layer without SDK dependencies relies on SDK classes being visible through agent/runtime classloader behavior that is not covered by an end-to-end test. Packaging another SDK in function code creates separate application-side and agent-side OTel classloader worlds and introduces version-skew and provider-ownership risks.
Option 1: Add a standalone SDK module (recommended)
Keep aws-durable-execution-sdk-java-plugin-otel as the layer/global artifact and add a second module, for example aws-durable-execution-sdk-java-plugin-otel-sdk.
The core/layer module would:
keep application-loaded plugin classes free of io.opentelemetry.sdk.* references;
use an SDK-free scoped-ID bridge around plugin-owned SpanBuilder.startSpan() calls;
retain the Java-agent AutoConfigurationCustomizerProvider and deterministic SDK IdGenerator as agent-loaded classes with SDK/SPI dependencies in provided scope;
use only the global API Tracer in ADOT mode and leave flushing/lifecycle ownership to the agent.
The standalone module would:
depend on the core plugin and opentelemetry-sdk;
expose typed factories or builders for explicit providers;
install the deterministic ID generator on SdkTracerProviderBuilder;
own explicit-provider flushing and shutdown behavior.
Reflection or broad classpath scanning may load SDK-linked classes unexpectedly.
Accidental SDK imports into core classes can silently regress the layer contract.
Requires architectural or jdeps enforcement to preserve the boundary.
Shared implementation requirements
Regardless of the selected option:
Extract scoped deterministic-ID state into an application-side class with no SDK dependency.
Keep the agent-side IdGenerator bridge compatible across the application and agent classloaders.
Remove SDK-specific provider checks and forceFlush() from global mode.
Decide and document how opentelemetry-api becomes application-visible for layer-only discovery; do not shade duplicate OTel API packages into the plugin JAR.
What would you like?
Make the OpenTelemetry plugin support two explicit runtime contracts without requiring the ADOT/global path to package an application-side OpenTelemetry SDK:
opentelemetry-sdkor initialize another provider.This should align with the Python OTel package model introduced by aws/aws-durable-execution-sdk-python#646 while using a Java/Maven-appropriate artifact design.
Current state
The proposed plugin layer in #621 contains only the thin OTel plugin JAR. However, application-loaded plugin classes still reference SDK types:
InvocationOtelPluginandExecutionOtelPluginexposeSdkTracerProviderBuilder, storeSdkTracerProvider, and callforceFlush().DeterministicIdGenerator, which implements the SDKIdGeneratorinterface.OtelPluginSupportperforms SDK-specific provider checks.opentelemetry-sdk, so it does not validate the thin plugin layer without an application SDK.Consequently, packaging the layer without SDK dependencies relies on SDK classes being visible through agent/runtime classloader behavior that is not covered by an end-to-end test. Packaging another SDK in function code creates separate application-side and agent-side OTel classloader worlds and introduces version-skew and provider-ownership risks.
Option 1: Add a standalone SDK module (recommended)
Keep
aws-durable-execution-sdk-java-plugin-otelas the layer/global artifact and add a second module, for exampleaws-durable-execution-sdk-java-plugin-otel-sdk.The core/layer module would:
io.opentelemetry.sdk.*references;SpanBuilder.startSpan()calls;AutoConfigurationCustomizerProviderand deterministic SDKIdGeneratoras agent-loaded classes with SDK/SPI dependencies inprovidedscope;Tracerin ADOT mode and leave flushing/lifecycle ownership to the agent.The standalone module would:
opentelemetry-sdk;SdkTracerProviderBuilder;Example standalone API:
Advantages
Disadvantages
Option 2: Keep one artifact with strict class isolation
Keep a single
aws-durable-execution-sdk-java-plugin-otelartifact, but isolate its classes by responsibility:agentpackage contains the SDKIdGeneratorand auto-configuration SPI implementation;sdkpackage contains standalone factories that referenceSdkTracerProviderBuilder;opentelemetry-sdkand auto-configuration SPI dependencies are non-transitive (providedor optional as appropriate);opentelemetry-sdk; global users never load the SDK-linked packages.Advantages
Disadvantages
jdepsenforcement to preserve the boundary.Shared implementation requirements
Regardless of the selected option:
IdGeneratorbridge compatible across the application and agent classloaders.forceFlush()from global mode.opentelemetry-apibecomes application-visible for layer-only discovery; do not shade duplicate OTel API packages into the plugin JAR.Acceptance criteria
opentelemetry-sdk.jdepstest prevents SDK references from application-loaded core plugin classes.Is this a breaking change?
No. The OTel plugin has not been officially released.
Does this require an RFC?
Yes. This changes artifact boundaries, provider ownership, and the plugin-layer runtime contract.
Additional context
Related work:
AUTO_OTLP, and makes provider ownership explicit.