Search code examples
javaclassloaderbyte-buddyopen-telemetryjavaagents

Can't use static variable in @Advice.OnMethodEnter method in opentelemetry javaagent extension


I'm trying to create an extension for opentelemetry javaagent. I need some static variables outside the methods to handle spans. But I get the error java.lang.ClassNotFoundException for a class where static variables are defined. The simplest code to reproduce:

public static class MethodAdvice {

        public static Integer CONST = 123;

        @Advice.OnMethodEnter(suppress = Throwable.class)
        public static void onEnter() {
            try {
                System.out.println(CONST.toString());
//                Class.forName(MethodAdvice.class.getName());
            } catch (Throwable e) {
                System.out.println("ERROR: " + e.getCause().toString());
                throw new RuntimeException(e);
            }
        }
    }

I get error when using CONST static variable for the first time. The same if I try to load the class. How can I use a static variable defined outside of the @Advice method? As I can see the opentelemetry library uses static variables outside the methods and it works, but I can't figure out how it is handled there.


Solution

  • The OpenTelemetry Java agent loads Advice classes inside of its own isolated AgentClassLoader.

    But the Advice method bytecode is inlined into the instrumented application classes.

    And application classes do not have access to the AgentClassLoader.

    You'll want to move your constant to a "helper" class, which this OTel Java agent will inject into the application class loader, and so will be accessible from your advice.

    This documentation should help: https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/docs/contributing/writing-instrumentation-module.md#write-an-instrumentationmodule-step-by-step