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

Fight the Future

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

How to get an application class loader in Java Agent method

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?

material of my session in JJUG CCC 2016 fall

I talked about Java Agent and bytecode manipulation libraries in JJUG CCC 2016 fall.

My session room was filled to capacity with bytecode fans!

This is a material of this session.

www.slideshare.net