当前位置: 首页 > 知识库问答 >
问题:

Java Hotspot Serviceability Agent SystemDictionary.ClassVisitor自JDK11以来不可用

司马弘益
2023-03-14
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

欢迎任何修复/变通方法:)

共有1个答案

周泰
2023-03-14

JDK.hotspot.agent是一个JDK内部模块,不是任何标准的一部分,不面向最终用户,因此没有文档化。

因此,该模块的API可以任意更改,即使是在较小的JDK更新中也是如此。为一个JDK版本编写的代码不需要与其他JDK版本兼容。这是很好理解的,因为Serviceability代理反映了内部JVM结构,这些结构可能会随着版本的变化而变化(并且确实会变化)。

因此,您需要一个不同的JDK11代码。它可能是这样的:

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);
    }
}
 类似资料:
  • pom.xml: 有什么想法可以解决这个问题吗?

  • 这是错误的方法/代码吗?如果你能提出更好的方法/代码,那就太好了。

  • 问题内容: 题: 在这里,“ MyClass”类可以通过调用“ Object”类中的clone方法来克隆其自己的对象。当我尝试在同一包“ GoodQuestions”中的另一个类(“ TestSingleTon”)中克隆此类(“ MyClass”)的类时,会引发以下编译时错误。 “来自对象类型的方法clone()不可见 ” 所以这是引发上述错误的代码? 问题答案: 发生此错误的原因是在对象类中cl

  • 在将我的android studio更新到4.2版本后,我在Logcat中没有可调试的进程可供选择。构建变体是调试的,我已经检查了其他解决我的问题的StackOverflow帖子,但没有找到任何东西。此外,我尝试了旧版本,结果发现4.1.3没有这个问题,过程是可见的,但我在4.2和4.2.1和大黄蜂中有这个问题,似乎新版本有问题。我想知道如果其他人有同样的问题,任何帮助都将不胜感激。 注意:即使调

  • 本文向大家介绍Python可以用来做什么,包括了Python可以用来做什么的使用技巧和注意事项,需要的朋友参考一下 Python技术可做web开发 很多人只了解Java、PHP可做web开发,但针对Python也可以做web开发却了解很少。很多人将会不清楚,Python实际上是和互联网技术一起长大的。做为动态性语言,而且具备高些的抽象层次的Python和Perl,迅速就被开发者们发觉更合适用以开发

  • 我遇到了一个问题,似乎没有将来自馈线的数据添加到会话中。我正在测试一个系统,其中一个用户有一个角色(即用户或管理员),我需要根据角色执行各种测试。在高级教程之后,我将链拆分为不同的对象(每个对象都在自己的文件中)——其中一个对象包含登录过程,无论用户角色如何,登录过程都是相同的。我不想重复使用这个,但要用不同的喂食器。 我使用csv feeder加载用户名和密码,但看起来它无法将数据添加到会话中,