Apply doubled-check locking + same approach to attributes definition for netty-4.1
MODIFY
dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/WeakMap.java
dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/WeakMap.java
@@ -107,10 +107,14 @@ public interface WeakMap<K, V> {
}
@Override
- public synchronized V getOrCreate(K key, ValueSupplier<V> supplier) {
+ public V getOrCreate(K key, ValueSupplier<V> supplier) {
+ if (!map.containsKey(key)) {
+ synchronized (this) {
if (!map.containsKey(key)) {
map.put(key, supplier.get());
}
+ }
+ }
return map.get(key);
}

MODIFY
dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/WeakMapSuppliers.java
dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/WeakMapSuppliers.java
@@ -178,9 +178,13 @@ class WeakMapSuppliers {
@Override
public V getOrCreate(K key, ValueSupplier<V> supplier) {
+ if (!map.containsKey(key)) {
+ synchronized (this) {
if (!map.containsKey(key)) {
map.put(key, supplier.get());
}
+ }
+ }
return map.get(key);
}

MODIFY
dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/AttributeKeys.java
dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/AttributeKeys.java
package datadog.trace.instrumentation.netty41;
+import datadog.trace.bootstrap.WeakMap;
import datadog.trace.context.TraceScope;
import datadog.trace.instrumentation.netty41.client.HttpClientTracingHandler;
import datadog.trace.instrumentation.netty41.server.HttpServerTracingHandler;
import io.netty.util.AttributeKey;
import io.opentracing.Span;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
public class AttributeKeys {
+
+ private static final WeakMap<ClassLoader, Map<String, AttributeKey<?>>> map =
+ WeakMap.Implementation.DEFAULT.get();
+
+ private static final WeakMap.ValueSupplier<Map<String, AttributeKey<?>>> mapSupplier =
+ new WeakMap.ValueSupplier<Map<String, AttributeKey<?>>>() {
+ @Override
+ public Map<String, AttributeKey<?>> get() {
+ return new ConcurrentHashMap<>();
+ }
+ };
+
public static final AttributeKey<TraceScope.Continuation>
PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY =
- AttributeKey.valueOf("datadog.trace.instrumentation.netty41.parent.connect.continuation");
+ attributeKey("datadog.trace.instrumentation.netty41.parent.connect.continuation");
/**
* This constant is copied over to datadog.trace.instrumentation.ratpack.server.TracingHandler, so
* if this changes, that must also change.
*/
public static final AttributeKey<Span> SERVER_ATTRIBUTE_KEY =
- AttributeKey.valueOf(HttpServerTracingHandler.class.getName() + ".span");
+ attributeKey(HttpServerTracingHandler.class.getName() + ".span");
public static final AttributeKey<Span> CLIENT_ATTRIBUTE_KEY =
- AttributeKey.valueOf(HttpClientTracingHandler.class.getName() + ".span");
+ attributeKey(HttpClientTracingHandler.class.getName() + ".span");
+
+ /**
+ * Generate an attribute key or reuse the one existing in the global app map. This implementation
+ * creates attributes only once even if the current class is loaded by several class loaders and
+ * prevents an issue with Apache Atlas project were this class loaded by multiple class loaders,
+ * while the Attribute class is loaded by a third class loader and used internally for the
+ * cassandra driver.
+ */
+ private static <T> AttributeKey<T> attributeKey(String key) {
+ Map<String, AttributeKey<?>> classLoaderMap =
+ map.getOrCreate(AttributeKey.class.getClassLoader(), mapSupplier);
+ if (classLoaderMap.containsKey(key)) {
+ return (AttributeKey<T>) classLoaderMap.get(key);
+ }
+
+ final AttributeKey<T> value = AttributeKey.valueOf(key);
+ classLoaderMap.put(key, value);
+ return value;
+ }
}

Apply doubled-check locking + same approach to attributes definition for netty-4.1