From d7d21d889a8c9bc670d044c48daefb2b93096bf5 Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Thu, 15 Oct 2020 16:48:52 -0700 Subject: [PATCH] Revert "Remove getCurrentContext and withSpan from Tracer (#1809)" This reverts commit b73a063901d92f0d9207dc7246afb1347565739f. --- QUICKSTART.md | 10 +-- .../trace/DefaultTracerBenchmarks.java | 6 +- .../io/opentelemetry/trace/DefaultTracer.java | 11 +++ .../java/io/opentelemetry/trace/Span.java | 8 +- .../java/io/opentelemetry/trace/Tracer.java | 74 ++++++++++++++++++- .../trace/TracingContextUtils.java | 17 ----- .../io/opentelemetry/OpenTelemetryTest.java | 12 +++ .../trace/DefaultTracerTest.java | 51 ++++++++++++- .../trace/TracingContextUtilsTest.java | 16 +--- .../java/io/opentelemetry/context/Scope.java | 2 +- .../propagation/ContextPropagators.java | 4 +- docs/rationale.md | 2 +- .../example/HelloWorldClient.java | 2 +- .../example/HelloWorldClientStream.java | 6 +- .../example/http/HttpClient.java | 2 +- .../example/http/HttpServer.java | 2 +- .../example/metrics/DoubleCounterExample.java | 2 +- .../example/metrics/LongCounterExample.java | 2 +- .../example/OtlpExporterExample.java | 2 +- .../opentracingshim/ScopeManagerShim.java | 5 +- .../OpenTelemetryInteroperabilityTest.java | 7 +- .../perf/OtlpPipelineDriver.java | 3 +- .../io/opentelemetry/sdk/trace/TracerSdk.java | 12 +++ .../sdk/trace/SpanBuilderSdkTest.java | 8 +- .../sdk/trace/TracerSdkTest.java | 35 ++++++++- .../ActiveSpanReplacementTest.java | 11 ++- .../trace/testbed/actorpropagation/Actor.java | 3 +- .../ActorPropagationTest.java | 9 +-- .../trace/testbed/clientserver/Client.java | 3 +- .../trace/testbed/clientserver/Server.java | 5 +- .../clientserver/TestClientServerTest.java | 3 +- .../HandlerTest.java | 6 +- .../errorreporting/ErrorReportingTest.java | 21 +++--- .../latespanfinish/LateSpanFinishTest.java | 11 ++- .../listenerperrequest/ListenerTest.java | 3 +- .../testbed/multiplecallbacks/Client.java | 3 +- .../MultipleCallbacksTest.java | 5 +- .../nestedcallbacks/NestedCallbacksTest.java | 9 +-- .../testbed/promisepropagation/Promise.java | 5 +- .../PromisePropagationTest.java | 7 +- .../RequestHandler.java | 5 +- .../SuspendResume.java | 9 ++- 42 files changed, 279 insertions(+), 140 deletions(-) diff --git a/QUICKSTART.md b/QUICKSTART.md index 3327435fc8a..d352c85e33f 100644 --- a/QUICKSTART.md +++ b/QUICKSTART.md @@ -51,7 +51,7 @@ To create a basic span, you only need to specify the name of the span. The start and end time of the span is automatically set by the OpenTelemetry SDK. ```java Span span = tracer.spanBuilder("my span").startSpan(); -try (Scope scope = TracingContextUtils.currentContextWith(span)) { +try (Scope scope = tracer.withSpan(span)) { // your use case ... } catch (Throwable t) { @@ -87,7 +87,7 @@ The OpenTelemetry API offers also an automated way to propagate the `parentSpan` ```java void a() { Span parentSpan = tracer.spanBuilder("a").startSpan(); - try(Scope scope = TracingContextUtils.currentContextWith(parentSpan)) { + try(Scope scope = tracer.withSpan(parentSpan)) { b(); } finally { parentSpan.end(); @@ -96,9 +96,9 @@ void a() { void b() { Span childSpan = tracer.spanBuilder("b") // NOTE: setParent(parentSpan) is not required; - // `TracingContextUtils.getCurrentSpan()` is automatically added as parent + // `tracer.getCurrentSpan()` is automatically added as parent .startSpan(); - try(Scope scope = TracingContextUtils.currentContextWith(childSpan)) { + try(Scope scope = tracer.withSpan(childSpan)) { // do stuff } finally { childSpan.end(); @@ -185,7 +185,7 @@ TextMapPropagator.Setter setter = URL url = new URL("http://127.0.0.1:8080/resource"); Span outGoing = tracer.spanBuilder("/resource").setSpanKind(Span.Kind.CLIENT).startSpan(); -try (Scope scope = TracingContextUtils.currentContextWith(outGoing)) { +try (Scope scope = tracer.withSpan(outGoing)) { // Semantic Convention. // (Observe that to set these, Span does not *need* to be the current instance.) outGoing.setAttribute("http.method", "GET"); diff --git a/api/src/jmh/java/io/opentelemetry/trace/DefaultTracerBenchmarks.java b/api/src/jmh/java/io/opentelemetry/trace/DefaultTracerBenchmarks.java index 54b47ba8814..05b065e6806 100644 --- a/api/src/jmh/java/io/opentelemetry/trace/DefaultTracerBenchmarks.java +++ b/api/src/jmh/java/io/opentelemetry/trace/DefaultTracerBenchmarks.java @@ -34,7 +34,7 @@ public class DefaultTracerBenchmarks { @Warmup(iterations = 5, time = 1) public void measureFullSpanLifecycle() { span = tracer.spanBuilder("span").startSpan(); - try (io.opentelemetry.context.Scope ignored = TracingContextUtils.currentContextWith(span)) { + try (io.opentelemetry.context.Scope ignored = tracer.withSpan(span)) { // no-op } finally { span.end(); @@ -59,7 +59,7 @@ public void measureSpanBuilding() { @OutputTimeUnit(TimeUnit.NANOSECONDS) @Warmup(iterations = 5, time = 1) public void measureScopeLifecycle() { - try (io.opentelemetry.context.Scope ignored = TracingContextUtils.currentContextWith(span)) { + try (io.opentelemetry.context.Scope ignored = tracer.withSpan(span)) { // no-op } } @@ -71,7 +71,7 @@ public void measureScopeLifecycle() { @OutputTimeUnit(TimeUnit.NANOSECONDS) @Warmup(iterations = 5, time = 1) public void measureGetCurrentSpan() { - TracingContextUtils.getCurrentSpan(); + tracer.getCurrentSpan(); } @TearDown(Level.Iteration) diff --git a/api/src/main/java/io/opentelemetry/trace/DefaultTracer.java b/api/src/main/java/io/opentelemetry/trace/DefaultTracer.java index 9fb55f361c3..04e6b7a5f5a 100644 --- a/api/src/main/java/io/opentelemetry/trace/DefaultTracer.java +++ b/api/src/main/java/io/opentelemetry/trace/DefaultTracer.java @@ -8,6 +8,7 @@ import io.opentelemetry.common.AttributeKey; import io.opentelemetry.common.Attributes; import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; import io.opentelemetry.internal.Utils; import java.util.Objects; import javax.annotation.Nullable; @@ -27,6 +28,16 @@ public static Tracer getInstance() { return INSTANCE; } + @Override + public Span getCurrentSpan() { + return TracingContextUtils.getCurrentSpan(); + } + + @Override + public Scope withSpan(Span span) { + return TracingContextUtils.currentContextWith(span); + } + @Override public Span.Builder spanBuilder(String spanName) { return NoopSpanBuilder.create(spanName); diff --git a/api/src/main/java/io/opentelemetry/trace/Span.java b/api/src/main/java/io/opentelemetry/trace/Span.java index 6104f45827f..fa3540f9cf1 100644 --- a/api/src/main/java/io/opentelemetry/trace/Span.java +++ b/api/src/main/java/io/opentelemetry/trace/Span.java @@ -299,8 +299,8 @@ default void setAttribute(AttributeKey key, int value) { * void doWork { * // Create a Span as a child of the current Span. * Span span = tracer.spanBuilder("MyChildSpan").startSpan(); - * try (Scope ss = TracingContextUtils.currentContextWith(span)) { - * TracingContextUtils.getCurrentSpan().addEvent("my event"); + * try (Scope ss = tracer.withSpan(span)) { + * tracer.getCurrentSpan().addEvent("my event"); * doSomeWork(); // Here the new span is in the current Context, so it can be used * // implicitly anywhere down the stack. * } finally { @@ -327,8 +327,8 @@ default void setAttribute(AttributeKey key, int value) { * } * * public void onExecuteHandler(ServerCallHandler serverCallHandler) { - * try (Scope ws = TracingContextUtils.currentContextWith(mySpan)) { - * TracingContextUtils.getCurrentSpan().addEvent("Start rpc execution."); + * try (Scope ws = tracer.withSpan(mySpan)) { + * tracer.getCurrentSpan().addEvent("Start rpc execution."); * serverCallHandler.run(); // Here the new span is in the current Context, so it can be * // used implicitly anywhere down the stack. * } diff --git a/api/src/main/java/io/opentelemetry/trace/Tracer.java b/api/src/main/java/io/opentelemetry/trace/Tracer.java index a9ab6468376..71ad062a15f 100644 --- a/api/src/main/java/io/opentelemetry/trace/Tracer.java +++ b/api/src/main/java/io/opentelemetry/trace/Tracer.java @@ -5,6 +5,8 @@ package io.opentelemetry.trace; +import com.google.errorprone.annotations.MustBeClosed; +import io.opentelemetry.context.Scope; import javax.annotation.concurrent.ThreadSafe; /** @@ -25,10 +27,10 @@ * private static final Tracer tracer = OpenTelemetry.getTracer(); * void doWork() { * Span span = tracer.spanBuilder("MyClass.DoWork").startSpan(); - * try(Scope ss = TracingContextUtils.currentContextWith(span)) { - * TracingContextUtils.getCurrentSpan().addEvent("Starting the work."); + * try(Scope ss = tracer.withSpan(span)) { + * tracer.getCurrentSpan().addEvent("Starting the work."); * doWorkInternal(); - * TracingContextUtils.getCurrentSpan().addEvent("Finished working."); + * tracer.getCurrentSpan().addEvent("Finished working."); * } finally { * span.end(); * } @@ -57,6 +59,72 @@ */ @ThreadSafe public interface Tracer { + /** + * Gets the current Span from the current Context. + * + *

To install a {@link Span} to the current Context use {@link #withSpan(Span)}. + * + *

startSpan methods do NOT modify the current Context {@code Span}. + * + * @return a default {@code Span} that does nothing and has an invalid {@link SpanContext} if no + * {@code Span} is associated with the current Context, otherwise the current {@code Span} + * from the Context. + */ + Span getCurrentSpan(); + + /** + * Enters the scope of code where the given {@link Span} is in the current Context, and returns an + * object that represents that scope. The scope is exited when the returned object is closed. + * + *

Supports try-with-resource idiom. + * + *

Can be called with {@code Span.getPropagated(span.getContext())} to enter a scope of code + * where tracing is stopped. + * + *

Example of usage: + * + *

{@code
+   * private static Tracer tracer = OpenTelemetry.getTracer();
+   * void doWork() {
+   *   // Create a Span as a child of the current Span.
+   *   Span span = tracer.spanBuilder("my span").startSpan();
+   *   try (Scope ws = tracer.withSpan(span)) {
+   *     tracer.getCurrentSpan().addEvent("my event");
+   *     doSomeOtherWork();  // Here "span" is the current Span.
+   *   }
+   *   span.end();
+   * }
+   * }
+ * + *

Prior to Java SE 7, you can use a finally block to ensure that a resource is closed + * regardless of whether the try statement completes normally or abruptly. + * + *

Example of usage prior to Java SE7: + * + *

{@code
+   * private static Tracer tracer = OpenTelemetry.getTracer();
+   * void doWork() {
+   *   // Create a Span as a child of the current Span.
+   *   Span span = tracer.spanBuilder("my span").startSpan();
+   *   Scope ws = tracer.withSpan(span);
+   *   try {
+   *     tracer.getCurrentSpan().addEvent("my event");
+   *     doSomeOtherWork();  // Here "span" is the current Span.
+   *   } finally {
+   *     ws.close();
+   *   }
+   *   span.end();
+   * }
+   * }
+ * + * @param span The {@link Span} to be set to the current Context. + * @return an object that defines a scope where the given {@link Span} will be set to the current + * Context. + * @throws NullPointerException if {@code span} is {@code null}. + */ + @MustBeClosed + Scope withSpan(Span span); + /** * Returns a {@link Span.Builder} to create and start a new {@link Span}. * diff --git a/api/src/main/java/io/opentelemetry/trace/TracingContextUtils.java b/api/src/main/java/io/opentelemetry/trace/TracingContextUtils.java index 6c65e19636f..5e0af1161c5 100644 --- a/api/src/main/java/io/opentelemetry/trace/TracingContextUtils.java +++ b/api/src/main/java/io/opentelemetry/trace/TracingContextUtils.java @@ -5,7 +5,6 @@ package io.opentelemetry.trace; -import com.google.errorprone.annotations.MustBeClosed; import io.opentelemetry.context.Context; import io.opentelemetry.context.ContextKey; import io.opentelemetry.context.Scope; @@ -67,25 +66,9 @@ public static Span getSpanWithoutDefault(Context context) { * Returns a new {@link Scope} encapsulating the provided {@link Span} added to the current {@code * Context}. * - *

Example of usage: - * - *

{@code
-   * private static Tracer tracer = OpenTelemetry.getTracer();
-   * void doWork() {
-   *   // Create a Span as a child of the current Span.
-   *   Span span = tracer.spanBuilder("my span").startSpan();
-   *   try (Scope ws = TracingContextUtils.currentContextWith(span)) {
-   *     TracingContextUtils.getCurrentSpan().addEvent("my event");
-   *     doSomeOtherWork();  // Here "span" is the current Span.
-   *   }
-   *   span.end();
-   * }
-   * }
- * * @param span the {@link Span} to be added to the current {@code Context}. * @return the {@link Scope} for the updated {@code Context}. */ - @MustBeClosed public static Scope currentContextWith(Span span) { return withSpan(span, io.opentelemetry.context.Context.current()).makeCurrent(); } diff --git a/api/src/test/java/io/opentelemetry/OpenTelemetryTest.java b/api/src/test/java/io/opentelemetry/OpenTelemetryTest.java index c76f4902e9c..ecd63cc9342 100644 --- a/api/src/test/java/io/opentelemetry/OpenTelemetryTest.java +++ b/api/src/test/java/io/opentelemetry/OpenTelemetryTest.java @@ -246,6 +246,18 @@ public Tracer get(String instrumentationName, String instrumentationVersion) { return get(instrumentationName); } + @Nullable + @Override + public Span getCurrentSpan() { + return null; + } + + @Nullable + @Override + public Scope withSpan(Span span) { + return null; + } + @Nullable @Override public Span.Builder spanBuilder(String spanName) { diff --git a/api/src/test/java/io/opentelemetry/trace/DefaultTracerTest.java b/api/src/test/java/io/opentelemetry/trace/DefaultTracerTest.java index ddab8c98134..52a74c8a3d9 100644 --- a/api/src/test/java/io/opentelemetry/trace/DefaultTracerTest.java +++ b/api/src/test/java/io/opentelemetry/trace/DefaultTracerTest.java @@ -9,6 +9,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; import org.junit.jupiter.api.Test; /** Unit tests for {@link DefaultTracer}. */ @@ -28,6 +29,20 @@ class DefaultTracerTest { TraceFlags.getDefault(), TraceState.getDefault()); + @Test + void defaultGetCurrentSpan() { + assertThat(defaultTracer.getCurrentSpan().getContext().isValid()).isFalse(); + } + + @Test + void getCurrentSpan_WithSpan() { + assertThat(defaultTracer.getCurrentSpan().getContext().isValid()).isFalse(); + try (Scope ws = defaultTracer.withSpan(Span.getInvalid())) { + assertThat(defaultTracer.getCurrentSpan().getContext().isValid()).isFalse(); + } + assertThat(defaultTracer.getCurrentSpan().getContext().isValid()).isFalse(); + } + @Test void spanBuilderWithName_NullName() { assertThrows(NullPointerException.class, () -> defaultTracer.spanBuilder(null)); @@ -38,6 +53,21 @@ void defaultSpanBuilderWithName() { assertThat(defaultTracer.spanBuilder(SPAN_NAME).startSpan().getContext().isValid()).isFalse(); } + @Test + void testInProcessContext() { + Span span = defaultTracer.spanBuilder(SPAN_NAME).startSpan(); + try (Scope scope = defaultTracer.withSpan(span)) { + assertThat(defaultTracer.getCurrentSpan()).isEqualTo(span); + Span secondSpan = defaultTracer.spanBuilder(SPAN_NAME).startSpan(); + try (Scope secondScope = defaultTracer.withSpan(secondSpan)) { + assertThat(defaultTracer.getCurrentSpan()).isEqualTo(secondSpan); + } finally { + assertThat(defaultTracer.getCurrentSpan()).isEqualTo(span); + } + } + assertThat(defaultTracer.getCurrentSpan().getContext().isValid()).isFalse(); + } + @Test void testSpanContextPropagationExplicitParent() { Span span = @@ -69,7 +99,8 @@ void noSpanContextMakesInvalidSpans() { @Test void testSpanContextPropagation_nullContext() { assertThrows( - NullPointerException.class, () -> defaultTracer.spanBuilder(SPAN_NAME).setParent(null)); + NullPointerException.class, + () -> defaultTracer.spanBuilder(SPAN_NAME).setParent((Context) null)); } @Test @@ -95,4 +126,22 @@ void testSpanContextPropagation_fromContextThenNoParent() { Span span = defaultTracer.spanBuilder(SPAN_NAME).setParent(context).setNoParent().startSpan(); assertThat(span.getContext()).isEqualTo(SpanContext.getInvalid()); } + + @Test + void testSpanContextPropagationCurrentSpan() { + Span parent = Span.wrap(spanContext); + try (Scope scope = defaultTracer.withSpan(parent)) { + Span span = defaultTracer.spanBuilder(SPAN_NAME).startSpan(); + assertThat(span.getContext()).isSameAs(spanContext); + } + } + + @Test + void testSpanContextPropagationCurrentSpanContext() { + Context context = TracingContextUtils.withSpan(Span.wrap(spanContext), Context.current()); + try (Scope scope = context.makeCurrent()) { + Span span = defaultTracer.spanBuilder(SPAN_NAME).startSpan(); + assertThat(span.getContext()).isSameAs(spanContext); + } + } } diff --git a/api/src/test/java/io/opentelemetry/trace/TracingContextUtilsTest.java b/api/src/test/java/io/opentelemetry/trace/TracingContextUtilsTest.java index 107f17d836c..b67f295bfa3 100644 --- a/api/src/test/java/io/opentelemetry/trace/TracingContextUtilsTest.java +++ b/api/src/test/java/io/opentelemetry/trace/TracingContextUtilsTest.java @@ -12,6 +12,7 @@ import org.junit.jupiter.api.Test; class TracingContextUtilsTest { + @Test void testGetCurrentSpan_Default() { Span span = TracingContextUtils.getCurrentSpan(); @@ -51,19 +52,4 @@ void testGetSpanWithoutDefault_ExplicitContext() { Context context = TracingContextUtils.withSpan(span, Context.current()); assertThat(TracingContextUtils.getSpanWithoutDefault(context)).isSameAs(span); } - - @Test - void testInProcessContext() { - Span span = Span.wrap(SpanContext.getInvalid()); - try (Scope scope = TracingContextUtils.currentContextWith(span)) { - assertThat(TracingContextUtils.getCurrentSpan()).isSameAs(span); - Span secondSpan = Span.wrap(SpanContext.getInvalid()); - try (Scope secondScope = TracingContextUtils.currentContextWith(secondSpan)) { - assertThat(TracingContextUtils.getCurrentSpan()).isSameAs(secondSpan); - } finally { - assertThat(TracingContextUtils.getCurrentSpan()).isSameAs(span); - } - } - assertThat(TracingContextUtils.getCurrentSpan().getContext().isValid()).isFalse(); - } } diff --git a/context/src/main/java/io/opentelemetry/context/Scope.java b/context/src/main/java/io/opentelemetry/context/Scope.java index 805b72d4bc7..5c79f8494da 100644 --- a/context/src/main/java/io/opentelemetry/context/Scope.java +++ b/context/src/main/java/io/opentelemetry/context/Scope.java @@ -13,7 +13,7 @@ * you use this class with a {@code try-with-resources} block: * *
{@code
- * try (Scope ignored = TracingContextUtils.currentContextWith(span)) {
+ * try (Scope ignored = tracer.withSpan(span)) {
  *   ...
  * }
  * }
diff --git a/context_prop/src/main/java/io/opentelemetry/context/propagation/ContextPropagators.java b/context_prop/src/main/java/io/opentelemetry/context/propagation/ContextPropagators.java index 4a9ed894b16..5d21a704dc0 100644 --- a/context_prop/src/main/java/io/opentelemetry/context/propagation/ContextPropagators.java +++ b/context_prop/src/main/java/io/opentelemetry/context/propagation/ContextPropagators.java @@ -22,7 +22,7 @@ *
{@code
  * private static final Tracer tracer = OpenTelemetry.getTracer();
  * void onSendRequest() {
- *   try (Scope scope = TracingContextUtils.currentContextWith(span)) {
+ *   try (Scope scope = tracer.withSpan(span)) {
  *     ContextPropagators propagators = OpenTelemetry.getPropagators();
  *     TextMapPropagator textMapPropagator = propagators.getTextMapPropagator();
  *
@@ -59,7 +59,7 @@
  *   Span span = tracer.spanBuilder("MyRequest")
  *       .setParent(context)
  *       .setSpanKind(Span.Kind.SERVER).startSpan();
- *   try (Scope ss = TracingContextUtils.currentContextWith(span)) {
+ *   try (Scope ss = tracer.withSpan(span)) {
  *     // Handle request and send response back.
  *   } finally {
  *     span.end();
diff --git a/docs/rationale.md b/docs/rationale.md
index da98af75922..e8514f92167 100644
--- a/docs/rationale.md
+++ b/docs/rationale.md
@@ -13,7 +13,7 @@ which try-with-resources does not allow. Take this example:
 
 ```java
 Span span = tracer.spanBuilder("someWork").startSpan();
-try (Scope scope = TracingContextUtils.currentContextWith(span)) {
+try (Scope scope = tracer.withSpan(span)) {
     // Do things.
 } catch (Exception ex) {
     span.recordException(ex);
diff --git a/examples/grpc/src/main/java/io/opentelemetry/example/HelloWorldClient.java b/examples/grpc/src/main/java/io/opentelemetry/example/HelloWorldClient.java
index 44ff6c86166..0a072923d8a 100644
--- a/examples/grpc/src/main/java/io/opentelemetry/example/HelloWorldClient.java
+++ b/examples/grpc/src/main/java/io/opentelemetry/example/HelloWorldClient.java
@@ -90,7 +90,7 @@ public void greet(String name) {
     span.setAttribute("net.peer.port", this.serverPort);
 
     // Set the context with the current span
-    try (Scope scope = TracingContextUtils.currentContextWith(span)) {
+    try (Scope scope = tracer.withSpan(span)) {
       HelloRequest request = HelloRequest.newBuilder().setName(name).build();
       try {
         HelloReply response = blockingStub.sayHello(request);
diff --git a/examples/grpc/src/main/java/io/opentelemetry/example/HelloWorldClientStream.java b/examples/grpc/src/main/java/io/opentelemetry/example/HelloWorldClientStream.java
index 3cc8336ec17..4d9d9530fe1 100644
--- a/examples/grpc/src/main/java/io/opentelemetry/example/HelloWorldClientStream.java
+++ b/examples/grpc/src/main/java/io/opentelemetry/example/HelloWorldClientStream.java
@@ -95,7 +95,7 @@ public void greet(List names) {
     StreamObserver requestObserver;
 
     // Set the context with the current span
-    try (Scope scope = TracingContextUtils.currentContextWith(span)) {
+    try (Scope scope = tracer.withSpan(span)) {
       HelloReplyStreamObserver replyObserver = new HelloReplyStreamObserver();
       requestObserver = asyncStub.sayHelloStream(replyObserver);
       for (String name : names) {
@@ -126,14 +126,14 @@ public HelloReplyStreamObserver() {
 
     @Override
     public void onNext(HelloReply value) {
-      Span span = TracingContextUtils.getCurrentSpan();
+      Span span = tracer.getCurrentSpan();
       span.addEvent("Data received: " + value.getMessage());
       logger.info(value.getMessage());
     }
 
     @Override
     public void onError(Throwable t) {
-      Span span = TracingContextUtils.getCurrentSpan();
+      Span span = tracer.getCurrentSpan();
       logger.log(Level.WARNING, "RPC failed: {0}", t.getMessage());
       span.setStatus(StatusCanonicalCode.ERROR, "gRPC status: " + t.getMessage());
     }
diff --git a/examples/http/src/main/java/io/opentelemetry/example/http/HttpClient.java b/examples/http/src/main/java/io/opentelemetry/example/http/HttpClient.java
index eec26421669..5c7f2019eda 100644
--- a/examples/http/src/main/java/io/opentelemetry/example/http/HttpClient.java
+++ b/examples/http/src/main/java/io/opentelemetry/example/http/HttpClient.java
@@ -55,7 +55,7 @@ private HttpClient() throws Exception {
     // Name convention for the Span is not yet defined.
     // See: https://github.com/open-telemetry/opentelemetry-specification/issues/270
     Span span = tracer.spanBuilder("/").setSpanKind(Span.Kind.CLIENT).startSpan();
-    try (Scope scope = TracingContextUtils.currentContextWith(span)) {
+    try (Scope scope = tracer.withSpan(span)) {
       // TODO provide semantic convention attributes to Span.Builder
       span.setAttribute("component", "http");
       span.setAttribute("http.method", "GET");
diff --git a/examples/http/src/main/java/io/opentelemetry/example/http/HttpServer.java b/examples/http/src/main/java/io/opentelemetry/example/http/HttpServer.java
index f53f4529948..8c5c7086236 100644
--- a/examples/http/src/main/java/io/opentelemetry/example/http/HttpServer.java
+++ b/examples/http/src/main/java/io/opentelemetry/example/http/HttpServer.java
@@ -43,7 +43,7 @@ public void handle(HttpExchange exchange) throws IOException {
       Span span =
           tracer.spanBuilder("/").setParent(context).setSpanKind(Span.Kind.SERVER).startSpan();
 
-      try (Scope scope = TracingContextUtils.currentContextWith(span)) {
+      try (Scope scope = tracer.withSpan(span)) {
         // Set the Semantic Convention
         span.setAttribute("component", "http");
         span.setAttribute("http.method", "GET");
diff --git a/examples/metrics/src/main/java/io/opentelemetry/example/metrics/DoubleCounterExample.java b/examples/metrics/src/main/java/io/opentelemetry/example/metrics/DoubleCounterExample.java
index 30555c2c0da..ed918a4a808 100644
--- a/examples/metrics/src/main/java/io/opentelemetry/example/metrics/DoubleCounterExample.java
+++ b/examples/metrics/src/main/java/io/opentelemetry/example/metrics/DoubleCounterExample.java
@@ -36,7 +36,7 @@ public class DoubleCounterExample {
   public static void main(String[] args) {
     Span span = tracer.spanBuilder("calculate space").setSpanKind(Kind.INTERNAL).startSpan();
     DoubleCounterExample example = new DoubleCounterExample();
-    try (Scope scope = TracingContextUtils.currentContextWith(span)) {
+    try (Scope scope = tracer.withSpan(span)) {
       List extensionsToFind = new ArrayList<>();
       extensionsToFind.add("dll");
       extensionsToFind.add("png");
diff --git a/examples/metrics/src/main/java/io/opentelemetry/example/metrics/LongCounterExample.java b/examples/metrics/src/main/java/io/opentelemetry/example/metrics/LongCounterExample.java
index f2a056187c5..c050d884d98 100644
--- a/examples/metrics/src/main/java/io/opentelemetry/example/metrics/LongCounterExample.java
+++ b/examples/metrics/src/main/java/io/opentelemetry/example/metrics/LongCounterExample.java
@@ -37,7 +37,7 @@ public class LongCounterExample {
   public static void main(String[] args) {
     Span span = tracer.spanBuilder("workflow").setSpanKind(Kind.INTERNAL).startSpan();
     LongCounterExample example = new LongCounterExample();
-    try (Scope scope = TracingContextUtils.currentContextWith(span)) {
+    try (Scope scope = tracer.withSpan(span)) {
       homeDirectoryCounter.add(1); // count root directory
       example.findFile("file_to_find.txt", homeDirectory);
     } catch (Exception e) {
diff --git a/examples/otlp/src/main/java/io/opentelemetry/example/OtlpExporterExample.java b/examples/otlp/src/main/java/io/opentelemetry/example/OtlpExporterExample.java
index bafe0eed7e8..d76b5962d66 100644
--- a/examples/otlp/src/main/java/io/opentelemetry/example/OtlpExporterExample.java
+++ b/examples/otlp/src/main/java/io/opentelemetry/example/OtlpExporterExample.java
@@ -55,7 +55,7 @@ public static void main(String[] args) throws InterruptedException {
 
     for (int i = 0; i < 10; i++) {
       Span exampleSpan = tracer.spanBuilder("exampleSpan").startSpan();
-      try (Scope scope = TracingContextUtils.currentContextWith(exampleSpan)) {
+      try (Scope scope = tracer.withSpan(exampleSpan)) {
         counter.add(1);
         exampleSpan.setAttribute("good", "true");
         exampleSpan.setAttribute("exampleNumber", i);
diff --git a/opentracing_shim/src/main/java/io/opentelemetry/opentracingshim/ScopeManagerShim.java b/opentracing_shim/src/main/java/io/opentelemetry/opentracingshim/ScopeManagerShim.java
index d96fda33d24..c4b976d3070 100644
--- a/opentracing_shim/src/main/java/io/opentelemetry/opentracingshim/ScopeManagerShim.java
+++ b/opentracing_shim/src/main/java/io/opentelemetry/opentracingshim/ScopeManagerShim.java
@@ -5,7 +5,6 @@
 
 package io.opentelemetry.opentracingshim;
 
-import io.opentelemetry.trace.TracingContextUtils;
 import io.opentracing.Scope;
 import io.opentracing.ScopeManager;
 import io.opentracing.Span;
@@ -21,7 +20,7 @@ public ScopeManagerShim(TelemetryInfo telemetryInfo) {
   public Span activeSpan() {
     // As OpenTracing simply returns null when no active instance is available,
     // we need to do map an invalid OpenTelemetry span to null here.
-    io.opentelemetry.trace.Span span = TracingContextUtils.getCurrentSpan();
+    io.opentelemetry.trace.Span span = tracer().getCurrentSpan();
     if (!span.getContext().isValid()) {
       return null;
     }
@@ -34,7 +33,7 @@ public Span activeSpan() {
   @SuppressWarnings("MustBeClosedChecker")
   public Scope activate(Span span) {
     io.opentelemetry.trace.Span actualSpan = getActualSpan(span);
-    return new ScopeShim(TracingContextUtils.currentContextWith(actualSpan));
+    return new ScopeShim(tracer().withSpan(actualSpan));
   }
 
   static io.opentelemetry.trace.Span getActualSpan(Span span) {
diff --git a/opentracing_shim/src/test/java/io/opentelemetry/opentracingshim/testbed/OpenTelemetryInteroperabilityTest.java b/opentracing_shim/src/test/java/io/opentelemetry/opentracingshim/testbed/OpenTelemetryInteroperabilityTest.java
index c409eb659a8..9a66728f162 100644
--- a/opentracing_shim/src/test/java/io/opentelemetry/opentracingshim/testbed/OpenTelemetryInteroperabilityTest.java
+++ b/opentracing_shim/src/test/java/io/opentelemetry/opentracingshim/testbed/OpenTelemetryInteroperabilityTest.java
@@ -15,7 +15,6 @@
 import io.opentelemetry.opentracingshim.TraceShim;
 import io.opentelemetry.sdk.OpenTelemetrySdk;
 import io.opentelemetry.sdk.trace.data.SpanData;
-import io.opentelemetry.trace.TracingContextUtils;
 import io.opentracing.Scope;
 import io.opentracing.Span;
 import io.opentracing.Tracer;
@@ -46,7 +45,7 @@ void sdkContinuesOpenTracingTrace() {
     } finally {
       otSpan.finish();
     }
-    assertThat(TracingContextUtils.getCurrentSpan().getContext().isValid()).isFalse();
+    assertThat(tracer.getCurrentSpan().getContext().isValid()).isFalse();
     assertNull(otTracer.activeSpan());
 
     List finishedSpans = inMemoryTracing.getSpanExporter().getFinishedSpanItems();
@@ -57,13 +56,13 @@ void sdkContinuesOpenTracingTrace() {
   @Test
   void openTracingContinuesSdkTrace() {
     io.opentelemetry.trace.Span otelSpan = tracer.spanBuilder("otel_span").startSpan();
-    try (io.opentelemetry.context.Scope scope = TracingContextUtils.currentContextWith(otelSpan)) {
+    try (io.opentelemetry.context.Scope scope = tracer.withSpan(otelSpan)) {
       otTracer.buildSpan("ot_span").start().finish();
     } finally {
       otelSpan.end();
     }
 
-    assertThat(TracingContextUtils.getCurrentSpan().getContext().isValid()).isFalse();
+    assertThat(tracer.getCurrentSpan().getContext().isValid()).isFalse();
     assertNull(otTracer.activeSpan());
 
     List finishedSpans = inMemoryTracing.getSpanExporter().getFinishedSpanItems();
diff --git a/perf_harness/src/main/java/io/opentelemetry/perf/OtlpPipelineDriver.java b/perf_harness/src/main/java/io/opentelemetry/perf/OtlpPipelineDriver.java
index c6b3cead126..0b786dcec29 100644
--- a/perf_harness/src/main/java/io/opentelemetry/perf/OtlpPipelineDriver.java
+++ b/perf_harness/src/main/java/io/opentelemetry/perf/OtlpPipelineDriver.java
@@ -22,7 +22,6 @@
 import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
 import io.opentelemetry.trace.Span;
 import io.opentelemetry.trace.Tracer;
-import io.opentelemetry.trace.TracingContextUtils;
 import java.io.IOException;
 import java.util.Collection;
 import java.util.Collections;
@@ -105,7 +104,7 @@ private static void runOnce(Integer numberOfSpans, int numberOfMillisToRunFor)
         : i < numberOfSpans) {
       //    for (int i = 0; i < 10000; i++) {
       Span exampleSpan = tracer.spanBuilder("exampleSpan").startSpan();
-      try (Scope scope = TracingContextUtils.currentContextWith(exampleSpan)) {
+      try (Scope scope = tracer.withSpan(exampleSpan)) {
         exampleSpan.setAttribute("exampleNumber", i++);
         exampleSpan.setAttribute("attribute0", "attvalue-0");
         exampleSpan.setAttribute("attribute1", "attvalue-1");
diff --git a/sdk/tracing/src/main/java/io/opentelemetry/sdk/trace/TracerSdk.java b/sdk/tracing/src/main/java/io/opentelemetry/sdk/trace/TracerSdk.java
index 6bb5c7af51b..deb7b25bc5f 100644
--- a/sdk/tracing/src/main/java/io/opentelemetry/sdk/trace/TracerSdk.java
+++ b/sdk/tracing/src/main/java/io/opentelemetry/sdk/trace/TracerSdk.java
@@ -5,10 +5,12 @@
 
 package io.opentelemetry.sdk.trace;
 
+import io.opentelemetry.context.Scope;
 import io.opentelemetry.sdk.common.InstrumentationLibraryInfo;
 import io.opentelemetry.trace.DefaultTracer;
 import io.opentelemetry.trace.Span;
 import io.opentelemetry.trace.Tracer;
+import io.opentelemetry.trace.TracingContextUtils;
 
 /** {@link TracerSdk} is SDK implementation of {@link Tracer}. */
 final class TracerSdk implements Tracer {
@@ -20,6 +22,16 @@ final class TracerSdk implements Tracer {
     this.instrumentationLibraryInfo = instrumentationLibraryInfo;
   }
 
+  @Override
+  public Span getCurrentSpan() {
+    return TracingContextUtils.getCurrentSpan();
+  }
+
+  @Override
+  public Scope withSpan(Span span) {
+    return TracingContextUtils.currentContextWith(span);
+  }
+
   @Override
   public Span.Builder spanBuilder(String spanName) {
     if (sharedState.isStopped()) {
diff --git a/sdk/tracing/src/test/java/io/opentelemetry/sdk/trace/SpanBuilderSdkTest.java b/sdk/tracing/src/test/java/io/opentelemetry/sdk/trace/SpanBuilderSdkTest.java
index 603fc37d133..50e52781b84 100644
--- a/sdk/tracing/src/test/java/io/opentelemetry/sdk/trace/SpanBuilderSdkTest.java
+++ b/sdk/tracing/src/test/java/io/opentelemetry/sdk/trace/SpanBuilderSdkTest.java
@@ -613,7 +613,7 @@ void sampledViaParentLinks() {
   @Test
   void noParent() {
     Span parent = tracerSdk.spanBuilder(SPAN_NAME).startSpan();
-    try (Scope ignored = TracingContextUtils.currentContextWith(parent)) {
+    try (Scope ignored = tracerSdk.withSpan(parent)) {
       Span span = tracerSdk.spanBuilder(SPAN_NAME).setNoParent().startSpan();
       try {
         assertThat(span.getContext().getTraceIdAsHexString())
@@ -760,7 +760,7 @@ void parent_fromEmptyContext() {
   @Test
   void parentCurrentSpan() {
     Span parent = tracerSdk.spanBuilder(SPAN_NAME).startSpan();
-    try (Scope ignored = TracingContextUtils.currentContextWith(parent)) {
+    try (Scope ignored = tracerSdk.withSpan(parent)) {
       final Context implicitParent = Context.current();
       RecordEventsReadableSpan span =
           (RecordEventsReadableSpan) tracerSdk.spanBuilder(SPAN_NAME).startSpan();
@@ -809,7 +809,7 @@ void startTimestamp_null() {
   @Test
   void parent_clockIsSame() {
     Span parent = tracerSdk.spanBuilder(SPAN_NAME).startSpan();
-    try (Scope scope = TracingContextUtils.currentContextWith(parent)) {
+    try (Scope scope = tracerSdk.withSpan(parent)) {
       RecordEventsReadableSpan span =
           (RecordEventsReadableSpan) tracerSdk.spanBuilder(SPAN_NAME).startSpan();
 
@@ -822,7 +822,7 @@ void parent_clockIsSame() {
   @Test
   void parentCurrentSpan_clockIsSame() {
     Span parent = tracerSdk.spanBuilder(SPAN_NAME).startSpan();
-    try (Scope ignored = TracingContextUtils.currentContextWith(parent)) {
+    try (Scope ignored = tracerSdk.withSpan(parent)) {
       RecordEventsReadableSpan span =
           (RecordEventsReadableSpan) tracerSdk.spanBuilder(SPAN_NAME).startSpan();
 
diff --git a/sdk/tracing/src/test/java/io/opentelemetry/sdk/trace/TracerSdkTest.java b/sdk/tracing/src/test/java/io/opentelemetry/sdk/trace/TracerSdkTest.java
index b31ee48d618..4662a87d685 100644
--- a/sdk/tracing/src/test/java/io/opentelemetry/sdk/trace/TracerSdkTest.java
+++ b/sdk/tracing/src/test/java/io/opentelemetry/sdk/trace/TracerSdkTest.java
@@ -49,11 +49,44 @@ void setUp() {
     MockitoAnnotations.initMocks(this);
   }
 
+  @Test
+  void defaultGetCurrentSpan() {
+    assertThat(tracer.getCurrentSpan().getContext().isValid()).isFalse();
+  }
+
   @Test
   void defaultSpanBuilder() {
     assertThat(tracer.spanBuilder(SPAN_NAME)).isInstanceOf(SpanBuilderSdk.class);
   }
 
+  @Test
+  void getCurrentSpan() {
+    assertThat(tracer.getCurrentSpan().getContext().isValid()).isFalse();
+    // Make sure context is detached even if test fails.
+    try (Scope ignored = TracingContextUtils.withSpan(span, Context.current()).makeCurrent()) {
+      assertThat(tracer.getCurrentSpan()).isSameAs(span);
+    }
+    assertThat(tracer.getCurrentSpan().getContext().isValid()).isFalse();
+  }
+
+  @Test
+  void withSpan_NullSpan() {
+    assertThat(tracer.getCurrentSpan().getContext().isValid()).isFalse();
+    try (Scope ignored = tracer.withSpan(null)) {
+      assertThat(tracer.getCurrentSpan().getContext().isValid()).isFalse();
+    }
+    assertThat(tracer.getCurrentSpan().getContext().isValid()).isFalse();
+  }
+
+  @Test
+  void getCurrentSpan_WithSpan() {
+    assertThat(tracer.getCurrentSpan().getContext().isValid()).isFalse();
+    try (Scope ignored = tracer.withSpan(span)) {
+      assertThat(tracer.getCurrentSpan()).isSameAs(span);
+    }
+    assertThat(tracer.getCurrentSpan().getContext().isValid()).isFalse();
+  }
+
   @Test
   void getInstrumentationLibraryInfo() {
     assertThat(tracer.getInstrumentationLibraryInfo()).isEqualTo(instrumentationLibraryInfo);
@@ -161,7 +194,7 @@ public SimpleSpanOperation(TracerSdk tracer) {
     @Override
     public void update() {
       Span span = tracer.spanBuilder("testSpan").startSpan();
-      try (Scope ignored = TracingContextUtils.currentContextWith(span)) {
+      try (Scope ignored = tracer.withSpan(span)) {
         span.setAttribute("testAttribute", "testValue");
       } finally {
         span.end();
diff --git a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/activespanreplacement/ActiveSpanReplacementTest.java b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/activespanreplacement/ActiveSpanReplacementTest.java
index 01d8f460b99..8d8a85151a9 100644
--- a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/activespanreplacement/ActiveSpanReplacementTest.java
+++ b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/activespanreplacement/ActiveSpanReplacementTest.java
@@ -18,7 +18,6 @@
 import io.opentelemetry.trace.Span;
 import io.opentelemetry.trace.SpanId;
 import io.opentelemetry.trace.Tracer;
-import io.opentelemetry.trace.TracingContextUtils;
 import java.util.List;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -38,7 +37,7 @@ class ActiveSpanReplacementTest {
   void test() {
     // Start an isolated task and query for its result in another task/thread
     Span span = tracer.spanBuilder("initial").startSpan();
-    try (Scope scope = TracingContextUtils.currentContextWith(span)) {
+    try (Scope scope = tracer.withSpan(span)) {
       // Explicitly pass a Span to be finished once a late calculation is done.
       submitAnotherTask(span);
     }
@@ -61,7 +60,7 @@ void test() {
     assertThat(spans.get(0).getTraceId()).isNotEqualTo(spans.get(1).getTraceId());
     assertThat(spans.get(0).getParentSpanId()).isEqualTo(SpanId.getInvalid());
 
-    assertThat(TracingContextUtils.getCurrentSpan()).isSameAs(Span.getInvalid());
+    assertThat(tracer.getCurrentSpan()).isSameAs(Span.getInvalid());
   }
 
   private void submitAnotherTask(final Span initialSpan) {
@@ -70,11 +69,11 @@ private void submitAnotherTask(final Span initialSpan) {
         () -> {
           // Create a new Span for this task
           Span taskSpan = tracer.spanBuilder("task").startSpan();
-          try (Scope scope = TracingContextUtils.currentContextWith(taskSpan)) {
+          try (Scope scope = tracer.withSpan(taskSpan)) {
 
             // Simulate work strictly related to the initial Span
             // and finish it.
-            try (Scope initialScope = TracingContextUtils.currentContextWith(initialSpan)) {
+            try (Scope initialScope = tracer.withSpan(initialSpan)) {
               sleep(50);
             } finally {
               initialSpan.end();
@@ -82,7 +81,7 @@ private void submitAnotherTask(final Span initialSpan) {
 
             // Restore the span for this task and create a subspan
             Span subTaskSpan = tracer.spanBuilder("subtask").startSpan();
-            try (Scope subTaskScope = TracingContextUtils.currentContextWith(subTaskSpan)) {
+            try (Scope subTaskScope = tracer.withSpan(subTaskSpan)) {
               sleep(50);
             } finally {
               subTaskSpan.end();
diff --git a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/actorpropagation/Actor.java b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/actorpropagation/Actor.java
index 9ff92e8d8f7..9ed196776c0 100644
--- a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/actorpropagation/Actor.java
+++ b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/actorpropagation/Actor.java
@@ -10,7 +10,6 @@
 import io.opentelemetry.trace.Span;
 import io.opentelemetry.trace.Span.Kind;
 import io.opentelemetry.trace.Tracer;
-import io.opentelemetry.trace.TracingContextUtils;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
@@ -45,7 +44,7 @@ Future tell(final String message) {
                   .setParent(parent)
                   .setSpanKind(Kind.CONSUMER)
                   .startSpan();
-          try (Scope ignored = TracingContextUtils.currentContextWith(child)) {
+          try (Scope ignored = tracer.withSpan(child)) {
             phaser.arriveAndAwaitAdvance(); // child tracer started
             child.addEvent("received " + message);
             phaser.arriveAndAwaitAdvance(); // assert size
diff --git a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/actorpropagation/ActorPropagationTest.java b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/actorpropagation/ActorPropagationTest.java
index dd36eadc0a2..d3169276409 100644
--- a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/actorpropagation/ActorPropagationTest.java
+++ b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/actorpropagation/ActorPropagationTest.java
@@ -15,7 +15,6 @@
 import io.opentelemetry.trace.Span;
 import io.opentelemetry.trace.Span.Kind;
 import io.opentelemetry.trace.Tracer;
-import io.opentelemetry.trace.TracingContextUtils;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
@@ -49,7 +48,7 @@ void testActorTell() {
       phaser.register();
       Span parent = tracer.spanBuilder("actorTell").setSpanKind(Kind.PRODUCER).startSpan();
       parent.setAttribute("component", "example-actor");
-      try (Scope ignored = TracingContextUtils.currentContextWith(parent)) {
+      try (Scope ignored = tracer.withSpan(parent)) {
         actor.tell("my message 1");
         actor.tell("my message 2");
       } finally {
@@ -73,7 +72,7 @@ void testActorTell() {
       assertThat(TestUtils.getByKind(finished, Span.Kind.CONSUMER)).hasSize(2);
       assertThat(TestUtils.getOneByKind(finished, Span.Kind.PRODUCER)).isNotNull();
 
-      assertThat(TracingContextUtils.getCurrentSpan()).isSameAs(Span.getInvalid());
+      assertThat(tracer.getCurrentSpan()).isSameAs(Span.getInvalid());
     }
   }
 
@@ -86,7 +85,7 @@ void testActorAsk() throws ExecutionException, InterruptedException {
       Span span = tracer.spanBuilder("actorAsk").setSpanKind(Kind.PRODUCER).startSpan();
       span.setAttribute("component", "example-actor");
 
-      try (Scope ignored = TracingContextUtils.currentContextWith(span)) {
+      try (Scope ignored = tracer.withSpan(span)) {
         future1 = actor.ask("my message 1");
         future2 = actor.ask("my message 2");
       } finally {
@@ -114,7 +113,7 @@ void testActorAsk() throws ExecutionException, InterruptedException {
       assertThat(TestUtils.getByKind(finished, Span.Kind.CONSUMER)).hasSize(2);
       assertThat(TestUtils.getOneByKind(finished, Span.Kind.PRODUCER)).isNotNull();
 
-      assertThat(TracingContextUtils.getCurrentSpan()).isSameAs(Span.getInvalid());
+      assertThat(tracer.getCurrentSpan()).isSameAs(Span.getInvalid());
     }
   }
 }
diff --git a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/clientserver/Client.java b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/clientserver/Client.java
index 73926afd66f..f13427f26e7 100644
--- a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/clientserver/Client.java
+++ b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/clientserver/Client.java
@@ -11,7 +11,6 @@
 import io.opentelemetry.trace.Span;
 import io.opentelemetry.trace.Span.Kind;
 import io.opentelemetry.trace.Tracer;
-import io.opentelemetry.trace.TracingContextUtils;
 import java.util.concurrent.ArrayBlockingQueue;
 
 final class Client {
@@ -30,7 +29,7 @@ public void send() throws InterruptedException {
     Span span = tracer.spanBuilder("send").setSpanKind(Kind.CLIENT).startSpan();
     span.setAttribute("component", "example-client");
 
-    try (Scope ignored = TracingContextUtils.currentContextWith(span)) {
+    try (Scope ignored = tracer.withSpan(span)) {
       OpenTelemetry.getPropagators()
           .getTextMapPropagator()
           .inject(Context.current(), message, Message::put);
diff --git a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/clientserver/Server.java b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/clientserver/Server.java
index 31ec848cfec..1df470861c2 100644
--- a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/clientserver/Server.java
+++ b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/clientserver/Server.java
@@ -12,7 +12,6 @@
 import io.opentelemetry.trace.Span;
 import io.opentelemetry.trace.Span.Kind;
 import io.opentelemetry.trace.Tracer;
-import io.opentelemetry.trace.TracingContextUtils;
 import java.util.concurrent.ArrayBlockingQueue;
 import javax.annotation.Nullable;
 
@@ -44,9 +43,9 @@ public String get(Message carrier, String key) {
         tracer.spanBuilder("receive").setSpanKind(Kind.SERVER).setParent(context).startSpan();
     span.setAttribute("component", "example-server");
 
-    try (Scope ignored = TracingContextUtils.currentContextWith(span)) {
+    try (Scope ignored = tracer.withSpan(span)) {
       // Simulate work.
-      TracingContextUtils.getCurrentSpan().addEvent("DoWork");
+      tracer.getCurrentSpan().addEvent("DoWork");
     } finally {
       span.end();
     }
diff --git a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/clientserver/TestClientServerTest.java b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/clientserver/TestClientServerTest.java
index 9d899469f5d..244035856c0 100644
--- a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/clientserver/TestClientServerTest.java
+++ b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/clientserver/TestClientServerTest.java
@@ -17,7 +17,6 @@
 import io.opentelemetry.trace.Span;
 import io.opentelemetry.trace.Span.Kind;
 import io.opentelemetry.trace.Tracer;
-import io.opentelemetry.trace.TracingContextUtils;
 import java.util.List;
 import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.TimeUnit;
@@ -63,6 +62,6 @@ void test() throws Exception {
     assertThat(finished.get(0).getKind()).isEqualTo(Kind.CLIENT);
     assertThat(finished.get(1).getKind()).isEqualTo(Kind.SERVER);
 
-    assertThat(TracingContextUtils.getCurrentSpan()).isSameAs(Span.getInvalid());
+    assertThat(tracer.getCurrentSpan()).isSameAs(Span.getInvalid());
   }
 }
diff --git a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/concurrentcommonrequesthandler/HandlerTest.java b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/concurrentcommonrequesthandler/HandlerTest.java
index 4fc4ffad5b0..9a14470c2f6 100644
--- a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/concurrentcommonrequesthandler/HandlerTest.java
+++ b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/concurrentcommonrequesthandler/HandlerTest.java
@@ -60,14 +60,14 @@ void two_requests() throws Exception {
     assertThat(finished.get(0).getParentSpanId()).isEqualTo(SpanId.getInvalid());
     assertThat(finished.get(1).getParentSpanId()).isEqualTo(SpanId.getInvalid());
 
-    assertThat(TracingContextUtils.getCurrentSpan()).isSameAs(Span.getInvalid());
+    assertThat(tracer.getCurrentSpan()).isSameAs(Span.getInvalid());
   }
 
   /** Active parent is not picked up by child. */
   @Test
   void parent_not_picked_up() throws Exception {
     Span parentSpan = tracer.spanBuilder("parent").startSpan();
-    try (Scope ignored = TracingContextUtils.currentContextWith(parentSpan)) {
+    try (Scope ignored = tracer.withSpan(parentSpan)) {
       String response = client.send("no_parent").get(15, TimeUnit.SECONDS);
       assertThat(response).isEqualTo("no_parent:response");
     } finally {
@@ -97,7 +97,7 @@ void parent_not_picked_up() throws Exception {
   void bad_solution_to_set_parent() throws Exception {
     Client client;
     Span parentSpan = tracer.spanBuilder("parent").startSpan();
-    try (Scope ignored = TracingContextUtils.currentContextWith(parentSpan)) {
+    try (Scope ignored = tracer.withSpan(parentSpan)) {
       client =
           new Client(
               new RequestHandler(
diff --git a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/errorreporting/ErrorReportingTest.java b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/errorreporting/ErrorReportingTest.java
index 8e10923fe8a..141155a038f 100644
--- a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/errorreporting/ErrorReportingTest.java
+++ b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/errorreporting/ErrorReportingTest.java
@@ -19,7 +19,6 @@
 import io.opentelemetry.trace.Span;
 import io.opentelemetry.trace.StatusCanonicalCode;
 import io.opentelemetry.trace.Tracer;
-import io.opentelemetry.trace.TracingContextUtils;
 import java.util.List;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -39,7 +38,7 @@ public final class ErrorReportingTest {
   @Test
   void testSimpleError() {
     Span span = tracer.spanBuilder("one").startSpan();
-    try (Scope ignored = TracingContextUtils.currentContextWith(span)) {
+    try (Scope ignored = tracer.withSpan(span)) {
       throw new RuntimeException("Invalid state");
     } catch (Exception e) {
       span.setStatus(StatusCanonicalCode.ERROR);
@@ -47,7 +46,7 @@ void testSimpleError() {
       span.end();
     }
 
-    assertThat(TracingContextUtils.getCurrentSpan()).isSameAs(Span.getInvalid());
+    assertThat(tracer.getCurrentSpan()).isSameAs(Span.getInvalid());
 
     List spans = inMemoryTracing.getSpanExporter().getFinishedSpanItems();
     assertThat(spans).hasSize(1);
@@ -60,7 +59,7 @@ void testCallbackError() {
     final Span span = tracer.spanBuilder("one").startSpan();
     executor.submit(
         () -> {
-          try (Scope ignored = TracingContextUtils.currentContextWith(span)) {
+          try (Scope ignored = tracer.withSpan(span)) {
             throw new RuntimeException("Invalid state");
           } catch (Exception exc) {
             span.setStatus(StatusCanonicalCode.ERROR);
@@ -85,7 +84,7 @@ void testErrorRecovery() {
     final int maxRetries = 1;
     int retries = 0;
     Span span = tracer.spanBuilder("one").startSpan();
-    try (Scope ignored = TracingContextUtils.currentContextWith(span)) {
+    try (Scope ignored = tracer.withSpan(span)) {
       while (retries++ < maxRetries) {
         try {
           throw new RuntimeException("No url could be fetched");
@@ -98,7 +97,7 @@ void testErrorRecovery() {
     span.setStatus(StatusCanonicalCode.ERROR); // Could not fetch anything.
     span.end();
 
-    assertThat(TracingContextUtils.getCurrentSpan()).isSameAs(Span.getInvalid());
+    assertThat(tracer.getCurrentSpan()).isSameAs(Span.getInvalid());
 
     List spans = inMemoryTracing.getSpanExporter().getFinishedSpanItems();
     assertThat(spans).hasSize(1);
@@ -114,7 +113,7 @@ void testErrorRecovery() {
   @Test
   void testInstrumentationLayer() {
     Span span = tracer.spanBuilder("one").startSpan();
-    try (Scope ignored = TracingContextUtils.currentContextWith(span)) {
+    try (Scope ignored = tracer.withSpan(span)) {
       // ScopedRunnable captures the active Span at this time.
       executor.submit(
           new ScopedRunnable(
@@ -122,9 +121,9 @@ void testInstrumentationLayer() {
                 try {
                   throw new RuntimeException("Invalid state");
                 } catch (Exception exc) {
-                  TracingContextUtils.getCurrentSpan().setStatus(StatusCanonicalCode.ERROR);
+                  tracer.getCurrentSpan().setStatus(StatusCanonicalCode.ERROR);
                 } finally {
-                  TracingContextUtils.getCurrentSpan().end();
+                  tracer.getCurrentSpan().end();
                 }
               },
               tracer));
@@ -147,13 +146,13 @@ private static class ScopedRunnable implements Runnable {
     private ScopedRunnable(Runnable runnable, Tracer tracer) {
       this.runnable = runnable;
       this.tracer = tracer;
-      this.span = TracingContextUtils.getCurrentSpan();
+      this.span = tracer.getCurrentSpan();
     }
 
     @Override
     public void run() {
       // No error reporting is done, as we are a simple wrapper.
-      try (Scope ignored = TracingContextUtils.currentContextWith(span)) {
+      try (Scope ignored = tracer.withSpan(span)) {
         runnable.run();
       }
     }
diff --git a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/latespanfinish/LateSpanFinishTest.java b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/latespanfinish/LateSpanFinishTest.java
index 7dd6d9eccb4..d1c97111314 100644
--- a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/latespanfinish/LateSpanFinishTest.java
+++ b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/latespanfinish/LateSpanFinishTest.java
@@ -14,7 +14,6 @@
 import io.opentelemetry.sdk.trace.data.SpanData;
 import io.opentelemetry.trace.Span;
 import io.opentelemetry.trace.Tracer;
-import io.opentelemetry.trace.TracingContextUtils;
 import java.util.List;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -51,7 +50,7 @@ void test() throws Exception {
 
     TestUtils.assertSameTrace(spans);
 
-    assertThat(TracingContextUtils.getCurrentSpan()).isSameAs(Span.getInvalid());
+    assertThat(tracer.getCurrentSpan()).isSameAs(Span.getInvalid());
   }
 
   /*
@@ -64,9 +63,9 @@ private void submitTasks(final Span parentSpan) {
         () -> {
           /* Alternative to calling activate() is to pass it manually to asChildOf() for each
            * created Span. */
-          try (Scope scope = TracingContextUtils.currentContextWith(parentSpan)) {
+          try (Scope scope = tracer.withSpan(parentSpan)) {
             Span childSpan = tracer.spanBuilder("task1").startSpan();
-            try (Scope childScope = TracingContextUtils.currentContextWith(childSpan)) {
+            try (Scope childScope = tracer.withSpan(childSpan)) {
               TestUtils.sleep(55);
             } finally {
               childSpan.end();
@@ -76,9 +75,9 @@ private void submitTasks(final Span parentSpan) {
 
     executor.submit(
         () -> {
-          try (Scope scope = TracingContextUtils.currentContextWith(parentSpan)) {
+          try (Scope scope = tracer.withSpan(parentSpan)) {
             Span childSpan = tracer.spanBuilder("task2").startSpan();
-            try (Scope childScope = TracingContextUtils.currentContextWith(childSpan)) {
+            try (Scope childScope = tracer.withSpan(childSpan)) {
               TestUtils.sleep(85);
             } finally {
               childSpan.end();
diff --git a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/listenerperrequest/ListenerTest.java b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/listenerperrequest/ListenerTest.java
index 00d0fc0f0d5..1362a6f797d 100644
--- a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/listenerperrequest/ListenerTest.java
+++ b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/listenerperrequest/ListenerTest.java
@@ -13,7 +13,6 @@
 import io.opentelemetry.trace.Span;
 import io.opentelemetry.trace.Span.Kind;
 import io.opentelemetry.trace.Tracer;
-import io.opentelemetry.trace.TracingContextUtils;
 import java.util.List;
 import org.junit.jupiter.api.Test;
 
@@ -34,6 +33,6 @@ void test() throws Exception {
     assertThat(finished).hasSize(1);
     assertThat(finished.get(0).getKind()).isEqualTo(Kind.CLIENT);
 
-    assertThat(TracingContextUtils.getCurrentSpan()).isSameAs(Span.getInvalid());
+    assertThat(tracer.getCurrentSpan()).isSameAs(Span.getInvalid());
   }
 }
diff --git a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/multiplecallbacks/Client.java b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/multiplecallbacks/Client.java
index a7453db9100..e7ef30738ee 100644
--- a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/multiplecallbacks/Client.java
+++ b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/multiplecallbacks/Client.java
@@ -9,7 +9,6 @@
 import io.opentelemetry.context.Scope;
 import io.opentelemetry.trace.Span;
 import io.opentelemetry.trace.Tracer;
-import io.opentelemetry.trace.TracingContextUtils;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -31,7 +30,7 @@ public Future send(final Object message) {
     return executor.submit(
         () -> {
           Span span = tracer.spanBuilder("subtask").setParent(parent).startSpan();
-          try (Scope subtaskScope = TracingContextUtils.currentContextWith(span)) {
+          try (Scope subtaskScope = tracer.withSpan(span)) {
             // Simulate work - make sure we finish *after* the parent Span.
             parentDoneLatch.await();
           } finally {
diff --git a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/multiplecallbacks/MultipleCallbacksTest.java b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/multiplecallbacks/MultipleCallbacksTest.java
index 9844c141808..519ac19cd09 100644
--- a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/multiplecallbacks/MultipleCallbacksTest.java
+++ b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/multiplecallbacks/MultipleCallbacksTest.java
@@ -16,7 +16,6 @@
 import io.opentelemetry.sdk.trace.data.SpanData;
 import io.opentelemetry.trace.Span;
 import io.opentelemetry.trace.Tracer;
-import io.opentelemetry.trace.TracingContextUtils;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -41,7 +40,7 @@ void test() {
     Client client = new Client(tracer, parentDoneLatch);
 
     Span span = tracer.spanBuilder("parent").startSpan();
-    try (Scope scope = TracingContextUtils.currentContextWith(span)) {
+    try (Scope scope = tracer.withSpan(span)) {
       client.send("task1");
       client.send("task2");
       client.send("task3");
@@ -64,6 +63,6 @@ void test() {
       assertThat(spans.get(i).getParentSpanId()).isEqualTo(parentSpan.getSpanId());
     }
 
-    assertThat(TracingContextUtils.getCurrentSpan()).isSameAs(Span.getInvalid());
+    assertThat(tracer.getCurrentSpan()).isSameAs(Span.getInvalid());
   }
 }
diff --git a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/nestedcallbacks/NestedCallbacksTest.java b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/nestedcallbacks/NestedCallbacksTest.java
index aaa40742438..8303e4a07be 100644
--- a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/nestedcallbacks/NestedCallbacksTest.java
+++ b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/nestedcallbacks/NestedCallbacksTest.java
@@ -18,7 +18,6 @@
 import io.opentelemetry.sdk.trace.data.SpanData;
 import io.opentelemetry.trace.Span;
 import io.opentelemetry.trace.Tracer;
-import io.opentelemetry.trace.TracingContextUtils;
 import java.util.List;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -54,24 +53,24 @@ void test() {
       assertThat(attrs.get(stringKey("key" + i))).isEqualTo(Integer.toString(i));
     }
 
-    assertThat(TracingContextUtils.getCurrentSpan()).isSameAs(Span.getInvalid());
+    assertThat(tracer.getCurrentSpan()).isSameAs(Span.getInvalid());
   }
 
   private void submitCallbacks(final Span span) {
 
     executor.submit(
         () -> {
-          try (Scope ignored = TracingContextUtils.currentContextWith(span)) {
+          try (Scope ignored = tracer.withSpan(span)) {
             span.setAttribute("key1", "1");
 
             executor.submit(
                 () -> {
-                  try (Scope ignored12 = TracingContextUtils.currentContextWith(span)) {
+                  try (Scope ignored12 = tracer.withSpan(span)) {
                     span.setAttribute("key2", "2");
 
                     executor.submit(
                         () -> {
-                          try (Scope ignored1 = TracingContextUtils.currentContextWith(span)) {
+                          try (Scope ignored1 = tracer.withSpan(span)) {
                             span.setAttribute("key3", "3");
                           } finally {
                             span.end();
diff --git a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/promisepropagation/Promise.java b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/promisepropagation/Promise.java
index e1956b6a173..a907732d14a 100644
--- a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/promisepropagation/Promise.java
+++ b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/promisepropagation/Promise.java
@@ -9,7 +9,6 @@
 import io.opentelemetry.context.Scope;
 import io.opentelemetry.trace.Span;
 import io.opentelemetry.trace.Tracer;
-import io.opentelemetry.trace.TracingContextUtils;
 import java.util.ArrayList;
 import java.util.Collection;
 
@@ -44,7 +43,7 @@ void success(final T result) {
           () -> {
             Span childSpan = tracer.spanBuilder("success").setParent(parent).startSpan();
             childSpan.setAttribute("component", "success");
-            try (Scope ignored = TracingContextUtils.currentContextWith(childSpan)) {
+            try (Scope ignored = tracer.withSpan(childSpan)) {
               callback.accept(result);
             } finally {
               childSpan.end();
@@ -61,7 +60,7 @@ void error(final Throwable error) {
           () -> {
             Span childSpan = tracer.spanBuilder("error").setParent(parent).startSpan();
             childSpan.setAttribute("component", "error");
-            try (Scope ignored = TracingContextUtils.currentContextWith(childSpan)) {
+            try (Scope ignored = tracer.withSpan(childSpan)) {
               callback.accept(error);
             } finally {
               childSpan.end();
diff --git a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/promisepropagation/PromisePropagationTest.java b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/promisepropagation/PromisePropagationTest.java
index 7c6c83ebdc0..788194f5293 100644
--- a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/promisepropagation/PromisePropagationTest.java
+++ b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/promisepropagation/PromisePropagationTest.java
@@ -17,7 +17,6 @@
 import io.opentelemetry.trace.Span;
 import io.opentelemetry.trace.SpanId;
 import io.opentelemetry.trace.Tracer;
-import io.opentelemetry.trace.TracingContextUtils;
 import java.util.List;
 import java.util.concurrent.Phaser;
 import java.util.concurrent.atomic.AtomicReference;
@@ -54,18 +53,18 @@ void testPromiseCallback() {
       Span parentSpan = tracer.spanBuilder("promises").startSpan();
       parentSpan.setAttribute("component", "example-promises");
 
-      try (Scope ignored = TracingContextUtils.currentContextWith(parentSpan)) {
+      try (Scope ignored = tracer.withSpan(parentSpan)) {
         Promise successPromise = new Promise<>(context, tracer);
 
         successPromise.onSuccess(
             s -> {
-              TracingContextUtils.getCurrentSpan().addEvent("Promised 1 " + s);
+              tracer.getCurrentSpan().addEvent("Promised 1 " + s);
               successResult1.set(s);
               phaser.arriveAndAwaitAdvance(); // result set
             });
         successPromise.onSuccess(
             s -> {
-              TracingContextUtils.getCurrentSpan().addEvent("Promised 2 " + s);
+              tracer.getCurrentSpan().addEvent("Promised 2 " + s);
               successResult2.set(s);
               phaser.arriveAndAwaitAdvance(); // result set
             });
diff --git a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/statelesscommonrequesthandler/RequestHandler.java b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/statelesscommonrequesthandler/RequestHandler.java
index 63a8b51a342..0a01790d2ea 100644
--- a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/statelesscommonrequesthandler/RequestHandler.java
+++ b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/statelesscommonrequesthandler/RequestHandler.java
@@ -9,7 +9,6 @@
 import io.opentelemetry.trace.Span;
 import io.opentelemetry.trace.Span.Kind;
 import io.opentelemetry.trace.Tracer;
-import io.opentelemetry.trace.TracingContextUtils;
 
 /**
  * One instance per Client. 'beforeRequest' and 'afterResponse' are executed in the same thread for
@@ -31,13 +30,13 @@ public RequestHandler(Tracer tracer) {
   /** beforeRequest handler....... */
   public void beforeRequest(Object request) {
     Span span = tracer.spanBuilder(OPERATION_NAME).setSpanKind(Kind.SERVER).startSpan();
-    tlsScope.set(TracingContextUtils.currentContextWith(span));
+    tlsScope.set(tracer.withSpan(span));
   }
 
   /** afterResponse handler....... */
   public void afterResponse(Object response) {
     // Finish the Span
-    TracingContextUtils.getCurrentSpan().end();
+    tracer.getCurrentSpan().end();
 
     // Deactivate the Span
     tlsScope.get().close();
diff --git a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/suspendresumepropagation/SuspendResume.java b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/suspendresumepropagation/SuspendResume.java
index b370a9ad484..73a4289e6f7 100644
--- a/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/suspendresumepropagation/SuspendResume.java
+++ b/sdk_extensions/testbed/src/test/java/io/opentelemetry/sdk/extensions/trace/testbed/suspendresumepropagation/SuspendResume.java
@@ -8,21 +8,24 @@
 import io.opentelemetry.context.Scope;
 import io.opentelemetry.trace.Span;
 import io.opentelemetry.trace.Tracer;
-import io.opentelemetry.trace.TracingContextUtils;
 
 final class SuspendResume {
+  private final Tracer tracer;
   private final Span span;
 
   public SuspendResume(int id, Tracer tracer) {
+    // Passed along here for testing. Normally should be referenced via GlobalTracer.get().
+    this.tracer = tracer;
+
     Span span = tracer.spanBuilder("job " + id).startSpan();
     span.setAttribute("component", "suspend-resume");
-    try (Scope scope = TracingContextUtils.currentContextWith(span)) {
+    try (Scope scope = tracer.withSpan(span)) {
       this.span = span;
     }
   }
 
   public void doPart(String name) {
-    try (Scope scope = TracingContextUtils.currentContextWith(span)) {
+    try (Scope scope = tracer.withSpan(span)) {
       span.addEvent("part: " + name);
     }
   }