diff --git a/dd-java-agent/agent-tooling/agent-tooling.gradle b/dd-java-agent/agent-tooling/agent-tooling.gradle index 46658ae46e..609bbee3c7 100644 --- a/dd-java-agent/agent-tooling/agent-tooling.gradle +++ b/dd-java-agent/agent-tooling/agent-tooling.gradle @@ -19,6 +19,7 @@ dependencies { testCompile deps.opentracing testCompile project(':dd-java-agent:testing') + testCompile project(':utils:gc-utils') instrumentationMuzzle sourceSets.main.output instrumentationMuzzle configurations.compile diff --git a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/WeakConcurrentSupplierTest.groovy b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/WeakConcurrentSupplierTest.groovy index 997347ea4e..a883c73fd2 100644 --- a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/WeakConcurrentSupplierTest.groovy +++ b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/WeakConcurrentSupplierTest.groovy @@ -1,7 +1,8 @@ package datadog.trace.agent.tooling -import datadog.trace.agent.test.TestUtils + import datadog.trace.bootstrap.WeakMap +import datadog.trace.util.gc.GCUtils import spock.lang.Shared import spock.lang.Specification @@ -47,7 +48,7 @@ class WeakConcurrentSupplierTest extends Specification { when: def supplierRef = new WeakReference(supplier) supplier = null - TestUtils.awaitGC(supplierRef) + GCUtils.awaitGC(supplierRef) then: ref.get() == null @@ -68,7 +69,7 @@ class WeakConcurrentSupplierTest extends Specification { when: def mapRef = new WeakReference(map) map = null - TestUtils.awaitGC(mapRef) + GCUtils.awaitGC(mapRef) then: ref.get() == null @@ -84,7 +85,7 @@ class WeakConcurrentSupplierTest extends Specification { setup: def key = new Object() map.put(key, "value") - TestUtils.awaitGC() + GCUtils.awaitGC() expect: map.size() == 1 @@ -92,7 +93,7 @@ class WeakConcurrentSupplierTest extends Specification { when: def keyRef = new WeakReference(key) key = null - TestUtils.awaitGC(keyRef) + GCUtils.awaitGC(keyRef) if (name == "WeakConcurrent") { // Sleep enough time for cleanup thread to get scheduled. diff --git a/dd-java-agent/dd-java-agent.gradle b/dd-java-agent/dd-java-agent.gradle index cb118eb935..23bce7b0d7 100644 --- a/dd-java-agent/dd-java-agent.gradle +++ b/dd-java-agent/dd-java-agent.gradle @@ -92,6 +92,7 @@ modifyPom { dependencies { testCompile project(':dd-trace-api') testCompile project(':dd-trace-ot') + testCompile project(':utils:gc-utils') testCompile deps.opentracingMock testCompile deps.testLogging diff --git a/dd-java-agent/src/test/groovy/datadog/trace/agent/integration/classloading/ClassLoadingTest.groovy b/dd-java-agent/src/test/groovy/datadog/trace/agent/integration/classloading/ClassLoadingTest.groovy index 781248df2e..02cd9a8511 100644 --- a/dd-java-agent/src/test/groovy/datadog/trace/agent/integration/classloading/ClassLoadingTest.groovy +++ b/dd-java-agent/src/test/groovy/datadog/trace/agent/integration/classloading/ClassLoadingTest.groovy @@ -4,6 +4,7 @@ import datadog.test.ClassToInstrument import datadog.test.ClassToInstrumentChild import datadog.trace.agent.test.IntegrationTestUtils import datadog.trace.api.Trace +import datadog.trace.util.gc.GCUtils import spock.lang.Specification import java.lang.ref.WeakReference @@ -39,7 +40,7 @@ class ClassLoadingTest extends Specification { loader.loadClass(ClassToInstrument.getName()) loader = null - IntegrationTestUtils.awaitGC(ref) + GCUtils.awaitGC(ref) then: null == ref.get() diff --git a/dd-java-agent/src/test/java/datadog/trace/agent/test/IntegrationTestUtils.java b/dd-java-agent/src/test/java/datadog/trace/agent/test/IntegrationTestUtils.java index 83b48a0acb..7f9f856e36 100644 --- a/dd-java-agent/src/test/java/datadog/trace/agent/test/IntegrationTestUtils.java +++ b/dd-java-agent/src/test/java/datadog/trace/agent/test/IntegrationTestUtils.java @@ -11,7 +11,6 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.lang.ref.WeakReference; import java.lang.reflect.Field; import java.net.URL; import java.util.ArrayList; @@ -187,20 +186,6 @@ public class IntegrationTestUtils { return (String[]) f.get(null); } - public static void awaitGC() { - Object obj = new Object(); - final WeakReference ref = new WeakReference<>(obj); - obj = null; - awaitGC(ref); - } - - public static void awaitGC(final WeakReference ref) { - while (ref.get() != null) { - System.gc(); - System.runFinalization(); - } - } - /** * On a separate JVM, run the main method for a given class. * diff --git a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/TestUtils.java b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/TestUtils.java index 69cbea0951..413b151538 100644 --- a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/TestUtils.java +++ b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/TestUtils.java @@ -19,7 +19,6 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.lang.ref.WeakReference; import java.lang.reflect.Field; import java.net.MalformedURLException; import java.net.ServerSocket; @@ -218,20 +217,6 @@ public class TestUtils { } } - public static void awaitGC() { - Object obj = new Object(); - final WeakReference ref = new WeakReference<>(obj); - obj = null; - awaitGC(ref); - } - - public static void awaitGC(final WeakReference ref) { - while (ref.get() != null) { - System.gc(); - System.runFinalization(); - } - } - public static ClassPath getTestClasspath() { return testClasspath; } @@ -245,7 +230,7 @@ public class TestUtils { } try { return ClassPath.from(testClassLoader); - } catch (IOException e) { + } catch (final IOException e) { throw new RuntimeException(e); } } @@ -254,15 +239,15 @@ public class TestUtils { * Parse JVM classpath and return ClassLoader containing all classpath entries. Inspired by Guava. */ private static ClassLoader buildJavaClassPathClassLoader() { - ImmutableList.Builder urls = ImmutableList.builder(); - for (String entry : Splitter.on(PATH_SEPARATOR.value()).split(JAVA_CLASS_PATH.value())) { + final ImmutableList.Builder urls = ImmutableList.builder(); + for (final String entry : Splitter.on(PATH_SEPARATOR.value()).split(JAVA_CLASS_PATH.value())) { try { try { urls.add(new File(entry).toURI().toURL()); - } catch (SecurityException e) { // File.toURI checks to see if the file is a directory + } catch (final SecurityException e) { // File.toURI checks to see if the file is a directory urls.add(new URL("file", null, new File(entry).getAbsolutePath())); } - } catch (MalformedURLException e) { + } catch (final MalformedURLException e) { System.err.println( String.format( "Error injecting bootstrap jar: Malformed classpath entry: %s. %s", entry, e)); diff --git a/dd-java-agent/testing/src/test/groovy/context/FieldBackedProviderTest.groovy b/dd-java-agent/testing/src/test/groovy/context/FieldBackedProviderTest.groovy index 4adf146891..1aba4566ec 100644 --- a/dd-java-agent/testing/src/test/groovy/context/FieldBackedProviderTest.groovy +++ b/dd-java-agent/testing/src/test/groovy/context/FieldBackedProviderTest.groovy @@ -3,6 +3,7 @@ package context import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.TestUtils import datadog.trace.api.Config +import datadog.trace.util.gc.GCUtils import net.bytebuddy.agent.ByteBuddyAgent import net.bytebuddy.utility.JavaModule import spock.lang.Requires @@ -101,7 +102,7 @@ class FieldBackedProviderTest extends AgentTestRunner { final int count = keyValue.get().incrementContextCount() WeakReference instanceRef = new WeakReference(keyValue.get()) keyValue.set(null) - TestUtils.awaitGC(instanceRef) + GCUtils.awaitGC(instanceRef) then: instanceRef.get() == null diff --git a/dd-java-agent/testing/src/test/java/muzzle/MuzzleWeakReferenceTest.java b/dd-java-agent/testing/src/test/java/muzzle/MuzzleWeakReferenceTest.java index 9b3af88423..8420aa5b71 100644 --- a/dd-java-agent/testing/src/test/java/muzzle/MuzzleWeakReferenceTest.java +++ b/dd-java-agent/testing/src/test/java/muzzle/MuzzleWeakReferenceTest.java @@ -1,9 +1,9 @@ package muzzle; -import datadog.trace.agent.test.TestUtils; import datadog.trace.agent.tooling.muzzle.Reference; import datadog.trace.agent.tooling.muzzle.ReferenceCreator; import datadog.trace.agent.tooling.muzzle.ReferenceMatcher; +import datadog.trace.util.gc.GCUtils; import java.lang.ref.WeakReference; import java.net.URL; import java.net.URLClassLoader; @@ -26,7 +26,7 @@ public class MuzzleWeakReferenceTest { final ReferenceMatcher refMatcher = new ReferenceMatcher(refs); refMatcher.getMismatchedReferenceSources(loader); loader = null; - TestUtils.awaitGC(clRef); + GCUtils.awaitGC(clRef); return clRef.get() == null; } } diff --git a/dd-java-agent/testing/testing.gradle b/dd-java-agent/testing/testing.gradle index f545854164..a878e06820 100644 --- a/dd-java-agent/testing/testing.gradle +++ b/dd-java-agent/testing/testing.gradle @@ -32,6 +32,8 @@ dependencies { compile deps.groovy + testCompile project(':utils:gc-utils') + // test instrumenting java 1.1 bytecode testCompile group: 'net.sf.jt400', name: 'jt400', version: '6.1' diff --git a/dd-trace-ot/dd-trace-ot.gradle b/dd-trace-ot/dd-trace-ot.gradle index 966b3cd543..66a2258510 100644 --- a/dd-trace-ot/dd-trace-ot.gradle +++ b/dd-trace-ot/dd-trace-ot.gradle @@ -38,6 +38,7 @@ dependencies { testImplementation deps.autoservice testCompile project(":dd-java-agent:testing") + testCompile project(':utils:gc-utils') testCompile group: 'org.assertj', name: 'assertj-core', version: '2.9.+' testCompile group: 'org.mockito', name: 'mockito-core', version: '2.19.0' testCompile group: 'org.objenesis', name: 'objenesis', version: '2.6' diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/PendingTraceTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/PendingTraceTest.groovy index 3b9e1a347a..92ced670b8 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/PendingTraceTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/PendingTraceTest.groovy @@ -1,8 +1,9 @@ package datadog.opentracing -import datadog.trace.agent.test.TestUtils + import datadog.trace.api.Config import datadog.trace.common.writer.ListWriter +import datadog.trace.util.gc.GCUtils import spock.lang.Specification import spock.lang.Subject import spock.lang.Timeout @@ -113,7 +114,7 @@ class PendingTraceTest extends Specification { when: def childRef = new WeakReference<>(child) child = null - TestUtils.awaitGC(childRef) + GCUtils.awaitGC(childRef) while (trace.pendingReferenceCount.get() > 0) { trace.clean() } diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/scopemanager/ScopeManagerTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/scopemanager/ScopeManagerTest.groovy index 0b20b084dd..a6d30eadd1 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/scopemanager/ScopeManagerTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/scopemanager/ScopeManagerTest.groovy @@ -3,9 +3,9 @@ package datadog.opentracing.scopemanager import datadog.opentracing.DDSpan import datadog.opentracing.DDSpanContext import datadog.opentracing.DDTracer -import datadog.trace.agent.test.TestUtils import datadog.trace.common.writer.ListWriter import datadog.trace.context.ScopeListener +import datadog.trace.util.gc.GCUtils import io.opentracing.Scope import io.opentracing.Span import io.opentracing.noop.NoopSpan @@ -154,7 +154,7 @@ class ScopeManagerTest extends Specification { continuation.activate() if (forceGC) { continuation = null // Continuation references also hold up traces. - TestUtils.awaitGC() // The goal here is to make sure that continuation DOES NOT get GCed + GCUtils.awaitGC() // The goal here is to make sure that continuation DOES NOT get GCed while (((DDSpanContext) scope.span().context()).trace.clean()) { } } @@ -204,7 +204,7 @@ class ScopeManagerTest extends Specification { if (forceGC) { def continuationRef = new WeakReference<>(continuation) continuation = null // Continuation references also hold up traces. - TestUtils.awaitGC(continuationRef) + GCUtils.awaitGC(continuationRef) while (traceCount.get() == 0) { // wait until trace count increments or timeout expires } diff --git a/dd-trace/dd-trace.gradle b/dd-trace/dd-trace.gradle index 660c36ea26..f18204bea5 100644 --- a/dd-trace/dd-trace.gradle +++ b/dd-trace/dd-trace.gradle @@ -5,15 +5,14 @@ dependencies { annotationProcessor deps.autoservice implementation deps.autoservice - compile project(':dd-java-agent:agent-bootstrap') compile project(':dd-trace-api') - compile deps.jackson compile deps.slf4j - // any higher versions seems to break ES tests with this exception: - // java.lang.NoSuchMethodError: com.fasterxml.jackson.dataformat.smile.SmileGenerator.getOutputContext() - compile group: 'org.msgpack', name: 'jackson-dataformat-msgpack', version: '0.8.14' + compile deps.jackson + compile group: 'org.msgpack', name: 'jackson-dataformat-msgpack', version: '0.8.16' + compile project(':utils:gc-utils') + // Spock uses that for mocking testCompile deps.bytebuddy testCompile group: 'org.objenesis', name: 'objenesis', version: '2.6' // Last version to support Java7 diff --git a/dd-trace/src/test/groovy/datadog/trace/tracer/TracerTest.groovy b/dd-trace/src/test/groovy/datadog/trace/tracer/TracerTest.groovy index 4824baa218..df04a03527 100644 --- a/dd-trace/src/test/groovy/datadog/trace/tracer/TracerTest.groovy +++ b/dd-trace/src/test/groovy/datadog/trace/tracer/TracerTest.groovy @@ -5,6 +5,7 @@ import datadog.trace.tracer.sampling.AllSampler import datadog.trace.tracer.writer.AgentWriter import datadog.trace.tracer.writer.SampleRateByService import datadog.trace.tracer.writer.Writer +import datadog.trace.util.gc.GCUtils import spock.lang.Shared import spock.lang.Specification @@ -125,7 +126,7 @@ class TracerTest extends Specification { span = null def traceRef = new WeakReference<>(rootSpan.getTrace()) rootSpan = null - TestUtils.awaitGC(traceRef) + GCUtils.awaitGC(traceRef) then: "invalid trace is written" testWriter.waitForTraces(1) @@ -151,7 +152,7 @@ class TracerTest extends Specification { continuation = null def traceRef = new WeakReference<>(rootSpan.getTrace()) rootSpan = null - TestUtils.awaitGC(traceRef) + GCUtils.awaitGC(traceRef) then: "invalid trace is written" testWriter.waitForTraces(1) diff --git a/settings.gradle b/settings.gradle index 802a6090c5..65308da2df 100644 --- a/settings.gradle +++ b/settings.gradle @@ -16,6 +16,7 @@ include ':dd-java-agent:agent-jmxfetch' // misc include ':dd-java-agent:testing' +include ':utils:gc-utils' // smoke tests include ':dd-smoke-tests:play' diff --git a/utils/gc-utils/gc-utils.gradle b/utils/gc-utils/gc-utils.gradle new file mode 100644 index 0000000000..ff6901ae6f --- /dev/null +++ b/utils/gc-utils/gc-utils.gradle @@ -0,0 +1 @@ +apply from: "${rootDir}/gradle/java.gradle" diff --git a/dd-trace/src/test/groovy/datadog/trace/tracer/TestUtils.java b/utils/gc-utils/src/main/java/datadog/trace/util/gc/GCUtils.java similarity index 80% rename from dd-trace/src/test/groovy/datadog/trace/tracer/TestUtils.java rename to utils/gc-utils/src/main/java/datadog/trace/util/gc/GCUtils.java index 354fdb433c..5b899897e9 100644 --- a/dd-trace/src/test/groovy/datadog/trace/tracer/TestUtils.java +++ b/utils/gc-utils/src/main/java/datadog/trace/util/gc/GCUtils.java @@ -1,9 +1,8 @@ -package datadog.trace.tracer; +package datadog.trace.util.gc; import java.lang.ref.WeakReference; -// TODO: stop copy-pasting this! -public class TestUtils { +public abstract class GCUtils { public static void awaitGC() { Object obj = new Object();