簡體   English   中英

Java 熱點可維護性代理 SystemDictionary.ClassVisitor 自 JDK11 以來不可用

[英]Java Hotspot Serviceability Agent SystemDictionary.ClassVisitor unavailable since JDK11

我正在嘗試構建一個非常基本的 Java 熱點可維護性代理來轉儲一個特定加載方法的字節碼。 這是我代理的代碼:

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);
    }
}

我用以下行編譯:

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

它修復了我之前遇到的導入問題,但似乎自 JDK11 以來, SystemVisitor.ClassVisitor接口不再存在,因為我在編譯時遇到錯誤:

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

另外,我在網上找不到任何文檔,這太令人沮喪了...... 請參閱 javadoc

JDK8 中的系統詞典
JDK11 中的系統詞典

歡迎任何修復/解決方法:)

jdk.hotspot.agent是一個 JDK 內部模塊,不是任何標准的一部分,不適合最終用戶,因此沒有記錄。

因此,這個模塊的 API 即使在 JDK 的次要更新中也可以任意更改。 為一個版本的 JDK 編寫的代碼不需要與其他 JDK 版本兼容。 這是很容易理解的,因為 Serviceability Agent 反映了內部 JVM 結構,這些結構可能會在不同版本之間發生變化(並且確實會發生變化)。

所以你需要一個不同的 JDK 11 代碼。它可能看起來像這樣:

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);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM