소스 검색

Avoid loading `Config` in `DDSpecification`

Loading `Config` in static section of `DDSpecification` happens before
bootstrap jar has been setup. This in turn causes problems down the
road because some of the classes are later loaded from bootstrap and
confuse things.
Nikolay Martynov 5 년 전
부모
커밋
ad79db6183
1개의 변경된 파일21개의 추가작업 그리고 45개의 파일을 삭제
  1. 21 45
      utils/test-utils/src/main/groovy/datadog/trace/util/test/DDSpecification.groovy

+ 21 - 45
utils/test-utils/src/main/groovy/datadog/trace/util/test/DDSpecification.groovy

@@ -6,8 +6,6 @@ import net.bytebuddy.dynamic.ClassFileLocator
 import net.bytebuddy.dynamic.Transformer
 import spock.lang.Specification
 
-import java.lang.reflect.Modifier
-
 import static net.bytebuddy.description.modifier.FieldManifestation.VOLATILE
 import static net.bytebuddy.description.modifier.Ownership.STATIC
 import static net.bytebuddy.description.modifier.Visibility.PUBLIC
@@ -17,12 +15,6 @@ import static net.bytebuddy.matcher.ElementMatchers.none
 abstract class DDSpecification extends Specification {
   private static final String CONFIG = "datadog.trace.api.Config"
 
-  static class ConfigInstance {
-    // Wrapped in a static class to lazy load.
-    static final CONFIG_INSTANCE_FIELD = Class.forName(CONFIG).getDeclaredField("INSTANCE")
-    static final RUNTIME_ID_FIELD = Class.forName(CONFIG).getDeclaredField("runtimeId")
-  }
-
   static {
     makeConfigInstanceModifiable()
   }
@@ -36,43 +28,27 @@ abstract class DDSpecification extends Specification {
     }
 
     def instrumentation = ByteBuddyAgent.install()
-    final transformer =
-      new AgentBuilder.Default()
-        .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
-        .with(AgentBuilder.RedefinitionStrategy.Listener.ErrorEscalating.FAIL_FAST)
-      // Config is injected into the bootstrap, so we need to provide a locator.
-        .with(
-          new AgentBuilder.LocationStrategy.Simple(
-            ClassFileLocator.ForClassLoader.ofSystemLoader()))
-        .ignore(none()) // Allow transforming bootstrap classes
-        .type(named(CONFIG))
-        .transform { builder, typeDescription, classLoader, module ->
-          builder
-            .field(named("INSTANCE"))
-            .transform(Transformer.ForField.withModifiers(PUBLIC, STATIC, VOLATILE))
-        }
-      // Making runtimeId modifiable so that it can be preserved when resetting config in tests
-        .transform { builder, typeDescription, classLoader, module ->
-          builder
-            .field(named("runtimeId"))
-            .transform(Transformer.ForField.withModifiers(PUBLIC, VOLATILE))
-        }
-        .installOn(instrumentation)
+    new AgentBuilder.Default()
+      .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
+      .with(AgentBuilder.RedefinitionStrategy.Listener.ErrorEscalating.FAIL_FAST)
+    // Config is injected into the bootstrap, so we need to provide a locator.
+      .with(
+        new AgentBuilder.LocationStrategy.Simple(
+          ClassFileLocator.ForClassLoader.ofSystemLoader()))
+      .ignore(none()) // Allow transforming bootstrap classes
+      .type(named(CONFIG))
+      .transform { builder, typeDescription, classLoader, module ->
+        builder
+          .field(named("INSTANCE"))
+          .transform(Transformer.ForField.withModifiers(PUBLIC, STATIC, VOLATILE))
+      }
+    // Making runtimeId modifiable so that it can be preserved when resetting config in tests
+      .transform { builder, typeDescription, classLoader, module ->
+        builder
+          .field(named("runtimeId"))
+          .transform(Transformer.ForField.withModifiers(PUBLIC, VOLATILE))
+      }
+      .installOn(instrumentation)
     isConfigInstanceModifiable = true
-
-    final field = ConfigInstance.CONFIG_INSTANCE_FIELD
-    assert Modifier.isPublic(field.getModifiers())
-    assert Modifier.isStatic(field.getModifiers())
-    assert Modifier.isVolatile(field.getModifiers())
-    assert !Modifier.isFinal(field.getModifiers())
-
-    final runtimeIdField = ConfigInstance.RUNTIME_ID_FIELD
-    assert Modifier.isPublic(runtimeIdField.getModifiers())
-    assert !Modifier.isStatic(ConfigInstance.RUNTIME_ID_FIELD.getModifiers())
-    assert Modifier.isVolatile(runtimeIdField.getModifiers())
-    assert !Modifier.isFinal(runtimeIdField.getModifiers())
-
-    // No longer needed (Unless class gets retransformed somehow).
-    instrumentation.removeTransformer(transformer)
   }
 }