Create context store map at most once (DataDog/dd-trace-java#1570)
MODIFY
agent-tooling/src/main/java/io/opentelemetry/auto/tooling/Instrumenter.java
agent-tooling/src/main/java/io/opentelemetry/auto/tooling/Instrumenter.java
@@ -82,8 +82,9 @@ public interface Instrumenter {
instrumentationPrimaryName = instrumentationName;
enabled = Config.get().isIntegrationEnabled(instrumentationNames, defaultEnabled());
- if (!contextStore().isEmpty()) {
- contextProvider = new FieldBackedProvider(this);
+ Map<String, String> contextStore = contextStore();
+ if (!contextStore.isEmpty()) {
+ contextProvider = new FieldBackedProvider(this, contextStore);
} else {
contextProvider = NoopContextProvider.INSTANCE;
}

MODIFY
agent-tooling/src/main/java/io/opentelemetry/auto/tooling/context/FieldBackedProvider.java
agent-tooling/src/main/java/io/opentelemetry/auto/tooling/context/FieldBackedProvider.java
@@ -114,6 +114,7 @@ public class FieldBackedProvider implements InstrumentationContextProvider {
private final Instrumenter.Default instrumenter;
private final ByteBuddy byteBuddy;
+ private final Map<String, String> contextStore;
/** fields-accessor-interface-name -> fields-accessor-interface-dynamic-type */
private final Map<String, DynamicType.Unloaded<?>> fieldAccessorInterfaces;
@@ -127,8 +128,10 @@ public class FieldBackedProvider implements InstrumentationContextProvider {
private final boolean fieldInjectionEnabled;
- public FieldBackedProvider(final Instrumenter.Default instrumenter) {
+ public FieldBackedProvider(
+ final Instrumenter.Default instrumenter, Map<String, String> contextStore) {
this.instrumenter = instrumenter;
+ this.contextStore = contextStore;
byteBuddy = new ByteBuddy();
fieldAccessorInterfaces = generateFieldAccessorInterfaces();
fieldAccessorInterfacesInjector = bootstrapHelperInjector(fieldAccessorInterfaces.values());
@@ -141,7 +144,7 @@ public class FieldBackedProvider implements InstrumentationContextProvider {
@Override
public AgentBuilder.Identified.Extendable instrumentationTransformer(
AgentBuilder.Identified.Extendable builder) {
- if (!instrumenter.contextStore().isEmpty()) {
+ if (!contextStore.isEmpty()) {
/*
* Install transformer that rewrites accesses to context store with specialized bytecode that
* invokes appropriate storage implementation.
@@ -242,12 +245,12 @@ public class FieldBackedProvider implements InstrumentationContextProvider {
"Incorrect Context Api Usage detected. Cannot find map holder class for %s context %s. Was that class defined in contextStore for instrumentation %s?",
keyClassName, contextClassName, instrumenter.getClass().getName()));
}
- if (!contextClassName.equals(instrumenter.contextStore().get(keyClassName))) {
+ if (!contextClassName.equals(contextStore.get(keyClassName))) {
throw new IllegalStateException(
String.format(
"Incorrect Context Api Usage detected. Incorrect context class %s, expected %s for instrumentation %s",
contextClassName,
- instrumenter.contextStore().get(keyClassName),
+ contextStore.get(keyClassName),
instrumenter.getClass().getName()));
}
// stack: contextClass | keyClass
@@ -379,7 +382,7 @@ public class FieldBackedProvider implements InstrumentationContextProvider {
AgentBuilder.Identified.Extendable builder) {
if (fieldInjectionEnabled) {
- for (final Map.Entry<String, String> entry : instrumenter.contextStore().entrySet()) {
+ for (final Map.Entry<String, String> entry : contextStore.entrySet()) {
/*
* For each context store defined in a current instrumentation we create an agent builder
* that injects necessary fields.
@@ -614,8 +617,8 @@ public class FieldBackedProvider implements InstrumentationContextProvider {
private Map<String, DynamicType.Unloaded<?>> generateContextStoreImplementationClasses() {
final Map<String, DynamicType.Unloaded<?>> contextStoreImplementations =
- new HashMap<>(instrumenter.contextStore().size());
- for (final Map.Entry<String, String> entry : instrumenter.contextStore().entrySet()) {
+ new HashMap<>(contextStore.size());
+ for (final Map.Entry<String, String> entry : contextStore.entrySet()) {
final DynamicType.Unloaded<?> type =
makeContextStoreImplementationClass(entry.getKey(), entry.getValue());
contextStoreImplementations.put(type.getTypeDescription().getName(), type);
@@ -980,8 +983,8 @@ public class FieldBackedProvider implements InstrumentationContextProvider {
private Map<String, DynamicType.Unloaded<?>> generateFieldAccessorInterfaces() {
final Map<String, DynamicType.Unloaded<?>> fieldAccessorInterfaces =
- new HashMap<>(instrumenter.contextStore().size());
- for (final Map.Entry<String, String> entry : instrumenter.contextStore().entrySet()) {
+ new HashMap<>(contextStore.size());
+ for (final Map.Entry<String, String> entry : contextStore.entrySet()) {
final DynamicType.Unloaded<?> type =
makeFieldAccessorInterface(entry.getKey(), entry.getValue());
fieldAccessorInterfaces.put(type.getTypeDescription().getName(), type);

Create context store map at most once (DataDog/dd-trace-java#1570)