読者です 読者をやめる 読者になる 読者になる

Fight the Future

何かを始めたら、半分成功したのと同じ

How to get an application class loader in Java Agent method

java jvm

In Java Agent method, such as premain() or agentmain(), class loader is system classloader, not application class loader.

If you intent to change bytecode of class loaded by application class loader, you will need an application class loader.

To get this, I think there is only one way. Get from Instrument API, as shown below.

public static void agentmain(String agentArgs, Instrumentation inst) throws Exception {
  Class[] classArray = inst.getAllLoadedClasses();
}

getAllLoadedClasses() returns an array of all classes currently loaded by the JVM. So, we need to seek the application class loader from these.

Map<String, Class> classMap = Arrays
                .stream(
                   inst
                     .getAllLoadedClasses()
                )
                .collect(
                  Collectors
                    .toMap(
                      c -> c.getName(), c -> c, (c1, c2) -> c1
                    )
                );

String target = "com.example.HelloWorld";
ClassLoader classLoader = classMap.get(target).getClassLoader();

It works well, but Agent class need to know the application class name. Is this okay?