我正在尝试构建一个非常基本的Java Hotspot服务代理,以转储一个特定加载方法的字节码。这是我经纪人的代码:
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
欢迎使用任何修复/解决方法:)
发布于 2021-10-05 10:21:48
jdk.hotspot.agent是JDK内部模块,不是任何标准的一部分,不适合最终用户,因此没有文档化。
因此,即使在一个小小的JDK更新中,也可以任意更改该模块的API。为JDK的一个版本编写的代码不需要与其他JDK版本兼容。这一点是非常理解的,因为Serviceability反映了内部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);
}
}https://stackoverflow.com/questions/69447986
复制相似问题