AntoineG
AntoineG

Reputation: 103

Java Hotspot Serviceability Agent SystemDictionary.ClassVisitor unavailable since JDK11

I am trying to build a very basic Java Hotspot Serviceability agent to dump the bytecode of one specific loaded method. This is the code of my agent :

package sun.jvm.hotspot.jdi;

import sun.jvm.hotspot.oops.InstanceKlass;
import sun.jvm.hotspot.oops.Method;
import sun.jvm.hotspot.oops.Klass;
import sun.jvm.hotspot.memory.SystemDictionary;
import sun.jvm.hotspot.runtime.VM;
import sun.jvm.hotspot.tools.Tool;

public class GetBytecode extends Tool {

    @Override
    public void run() {
        VM.getVM().getSystemDictionary().allClassesDo(new SystemDictionary.ClassVisitor() {
            public void visit(Klass klass) {
                if (klass.getName().asString().equals("MyDebugger")) {
                    Method method = ((InstanceKlass) klass).findMethod("sendMessage", "()V");
                    for (byte bc : method.getByteCode()) {
                        System.out.printf("%02x ", bc);
                    }
                }
            }
        });
    }

    public static void main(String[] args) {
        new GetBytecode().execute(args);
    }
}

which I compile with the following line:

javac --add-modules=jdk.hotspot.agent --add-exports "jdk.hotspot.agent/sun.jvm.hotspot.memory.SystemDictionary=ALL-UNNAMED" --add-exports "jdk.hotspot.agent/sun.jvm.hotspot.memory=ALL-UNNAMED" --add-exports "jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED" --add-exports "jdk.hotspot.agent/sun.jvm.hotspot.tools=ALL-UNNAMED"  --add-exports  "jdk.hotspot.agent/sun.jvm.hotspot.runtime=ALL-UNNAMED" --add-exports "jdk.hotspot.agent/sun.jvm.hotspot.classfile=ALL-UNNAMED" *.java

It fixes the import issues that I had before, but it seems like since JDK11 the SystemVisitor.ClassVisitor interface does not exist anymore, as I get an error while compiling :

GetBytecode.java:14: error: cannot find symbol
        VM.getVM().getSystemDictionary().allClassesDo(new SystemDictionary.ClassVisitor() {
                                                                          ^
  symbol:   class ClassVisitor
  location: class SystemDictionary
1 error

Also, I cannot find any doc online, which is so frustrating... See javadoc

SystemDictionary in JDK8
SystemDictionary in JDK11

Any fix / workaround is welcome :)

Upvotes: 0

Views: 581

Answers (1)

apangin
apangin

Reputation: 98350

jdk.hotspot.agent is a JDK internal module, not a part of any standard, not intended for end users, and therefore, not documented.

As a consequence, the API of this module can be arbitrarily changed even in a minor JDK update. The code written for one version of JDK is not required to be compatible with other JDK version. This is quite understood, since Serviceability Agent reflects internal JVM structures, which may change (and do change) from version to version.

So you'd need a different code for JDK 11. It may look like this:

import sun.jvm.hotspot.oops.InstanceKlass;
import sun.jvm.hotspot.oops.Method;
import sun.jvm.hotspot.runtime.VM;
import sun.jvm.hotspot.tools.Tool;

public class GetBytecode extends Tool {

    @Override
    public void run() {
        VM.getVM().getSystemDictionary().sharedDictionary().allEntriesDo((klass, loader) -> {
            if (klass.getName().asString().equals("MyDebugger")) {
                Method method = ((InstanceKlass) klass).findMethod("sendMessage", "()V");
                for (byte bc : method.getByteCode()) {
                    System.out.printf("%02x ", bc);
                }
            }
        }, null);
    }

    public static void main(String[] args) {
        new GetBytecode().execute(args);
    }
}

Upvotes: 2

Related Questions