Skip to content

Add default constructor support for OTel plugin#540

Open
zhongkechen wants to merge 29 commits into
mainfrom
codex/otel-plugin-default-constructor
Open

Add default constructor support for OTel plugin#540
zhongkechen wants to merge 29 commits into
mainfrom
codex/otel-plugin-default-constructor

Conversation

@zhongkechen

@zhongkechen zhongkechen commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add new OtelPlugin() for ADOT Java agent usage without handler-side GlobalOpenTelemetry initialization.
  • Register OtelPluginAutoConfigurationCustomizerProvider through the OpenTelemetry Java agent autoconfigure SPI so the agent-created SdkTracerProviderBuilder gets the durable deterministic IdGenerator before the provider is built.
  • Make OtelPlugin() validate that the SPI ran, then use GlobalOpenTelemetry.getTracerProvider() directly instead of creating, copying, mutating, or reflecting into a provider.
  • Move the deployed X-Ray Step/Wait examples off the old ADOT collector assumption and onto the same Java-agent extension setup as the default-constructor example.
  • Package the OTel plugin jar into the examples artifact under lib/ and generate SAM config that points OTEL_JAVAAGENT_EXTENSIONS / otel.javaagent.extensions at that jar for examples that use new OtelPlugin().

How It Works Now

  • The ADOT Lambda layer starts the Java process through /opt/otel-instrument.
  • The generated template configures the extension path as /var/task/lib/aws-durable-execution-sdk-java-plugin-otel-<version>.jar for no-arg OTel examples.
  • The Java agent loads the plugin jar as an extension and discovers META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider.
  • OtelPluginAutoConfigurationCustomizerProvider installs a shared DeterministicIdGenerator on the agent SDK builder and marks installation through dependency-free shared state.
  • OtelPlugin() checks that marker, uses the existing global tracer provider, and keeps a separate DeterministicIdGenerator instance only to publish durable execution state through system properties. The agent-installed generator reads that state when spans are started, which works across the app and agent classloader split.

Why Not Reflection

  • ADOT exposes Java agent wrapper providers such as ApplicationTracerProvider14, not a stable public SdkTracerProviderBuilder surface.
  • Reflection paths were brittle across OpenTelemetry versions: some wrappers do not expose unobfuscate(), and internal fields such as agentTracerProvider are not consistently visible or typed from the application classloader.
  • Even when an SDK provider can be reached, replacing the ID generator after the provider is already built is not a supported contract and depends on private SDK internals.
  • The SPI runs at the right lifecycle point, before the agent builds the SDK provider, and is the documented OpenTelemetry Java agent extension mechanism.

Testing

  • mvn -pl otel-plugin,examples spotless:apply
  • mvn -pl examples spotless:apply
  • python3 generate-template.py
  • mvn -pl otel-plugin -am test
  • mvn -pl examples -am -Dtest="OtelXRayStepExampleTest,OtelXRayWaitExampleTest,OtelXRayExamplesTest" -Dsurefire.failIfNoSpecifiedTests=false test
  • mvn -pl examples -am package -DskipTests
  • Verified the examples artifact contains lib/aws-durable-execution-sdk-java-plugin-otel-2.1.1-SNAPSHOT.jar and that nested jar contains the autoconfigure SPI service entry.
  • Verified the default-constructor example runs in Lambda with the ADOT layer and plugin jar extension path.

@zhongkechen zhongkechen requested a review from a team July 14, 2026 00:21

@SilanHe SilanHe left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll have to add an integration test example where we use the optimized ADOT layer so that we can ensure this is working

@zhongkechen zhongkechen requested a review from SilanHe July 14, 2026 17:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants