diff --git a/javaagent-instrumentation-api/src/main/java/io/opentelemetry/javaagent/instrumentation/api/InstrumentationContext.java b/javaagent-instrumentation-api/src/main/java/io/opentelemetry/javaagent/instrumentation/api/InstrumentationContext.java index 9f80bc0656..6ed42aed9c 100644 --- a/javaagent-instrumentation-api/src/main/java/io/opentelemetry/javaagent/instrumentation/api/InstrumentationContext.java +++ b/javaagent-instrumentation-api/src/main/java/io/opentelemetry/javaagent/instrumentation/api/InstrumentationContext.java @@ -18,7 +18,12 @@ public class InstrumentationContext { *
In reality, the calls to this method are re-written to something more performant * while injecting advice into a method. * - *
This method must only be called within an Advice class. + *
When this method is called from outside of an Advice class it can only access {@link
+ * ContextStore} when it is already created. For this {@link ContextStore} either needs to be
+ * added to {@code
+ * io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule#getMuzzleContextStoreClasses()}
+ * or be used in an Advice or Helper class which automatically adds it to {@code
+ * InstrumentationModule#getMuzzleContextStoreClasses()}
*
* @param keyClass The key class context is attached to.
* @param contextClass The context class attached to the user class.
@@ -28,7 +33,27 @@ public class InstrumentationContext {
*/
public static ContextStore
get(
Class
{
+ ContextStore
get(Class
ContextStore
getContextStore(
+ Class
) method.invoke(null, keyClass, contextClass);
+ } catch (ClassNotFoundException exception) {
+ throw new IllegalStateException("Context store not found", exception);
+ } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException exception) {
+ throw new IllegalStateException("Failed to get context store", exception);
+ }
+ }
+
@Override
public AgentBuilder.Identified.Extendable instrumentationTransformer(
AgentBuilder.Identified.Extendable builder) {
@@ -989,10 +1005,10 @@ public class FieldBackedProvider implements InstrumentationContextProvider {
return (builder, typeDescription, classLoader, module) -> builder.visit(visitor);
}
- private String getContextStoreImplementationClassName(
+ private static String getContextStoreImplementationClassName(
String keyClassName, String contextClassName) {
return DYNAMIC_CLASSES_PACKAGE
- + getClass().getSimpleName()
+ + FieldBackedProvider.class.getSimpleName()
+ "$ContextStore$"
+ Utils.convertToInnerClassName(keyClassName)
+ "$"
diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/InstrumentationModuleInstaller.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/InstrumentationModuleInstaller.java
index 097c403b4b..08461edcf5 100644
--- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/InstrumentationModuleInstaller.java
+++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/InstrumentationModuleInstaller.java
@@ -12,6 +12,7 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
+import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext;
import io.opentelemetry.javaagent.tooling.HelperInjector;
import io.opentelemetry.javaagent.tooling.TransformSafeLogger;
import io.opentelemetry.javaagent.tooling.Utils;
@@ -113,12 +114,23 @@ public final class InstrumentationModuleInstaller {
InstrumentationModule instrumentationModule) {
Map