我试图通过使用重写类的字节码来做到这一点ASM 4.0 http://download.forge.objectweb.org/asm/asm4-guide.pdf来替换所有的native
方法与非native
stubs.
到目前为止我有这个:
class ClassAdapter extends ClassVisitor {
public ClassAdapter(ClassVisitor cv) {
super(Opcodes.ASM4, cv);
}
@Override
public MethodVisitor visitMethod(int access, String base, String desc, String signature, String[] exceptions) {
return cv.visitMethod(access & ~Opcodes.ACC_NATIVE, base, desc, signature, exceptions);
}
}
这是由执行的
private static byte[] instrument(byte[] originalBytes, ClassLoader loader) {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
ClassAdapter adapter = new ClassAdapter(cw);
ClassReader cr = new ClassReader(originalBytes);
cr.accept(adapter, ClassReader.SKIP_FRAMES);
return cw.toByteArray();
}
这看起来很简单:我剥离ACC_NATIVE
关闭该方法中的visitMethod()
并保持其他一切不变。但是,当我这样做时java.lang.Object
,它死了
Exception in thread "main"
Exception: java.lang.StackOverflowError thrown from the UncaughtExceptionHandler in thread "main"
StackOverflow 发生在仪器仪表时间,不是在runtime,我认为这很不寻常。但是,如果我删除& ~Opcodes.ACC_NATIVE
修饰符,java.lang.Object
被重写(在本例中未更改)并完美执行。
显然我没有做正确的事情,并且更换了native
方法与非native
方法并不像剥离那么简单native
方法上的修饰符,但我不知道从哪里开始。这ASM Docs http://download.forge.objectweb.org/asm/asm4-guide.pdf不要谈论与native
方法都没有。有 ASM 工作经验的人知道我需要做什么才能获得native
方法重写可以工作吗?
EDIT
抱歉,那条简短、无用的消息就是e.printStackTrace()
正在给我,但是使用e.getStackTrace()
我设法得到一些有用的东西:
java.util.concurrent.ConcurrentHashMap.hash(ConcurrentHashMap.java:332)
java.util.concurrent.ConcurrentHashMap.put(ConcurrentHashMap.java:1124)
java.util.Collections$SetFromMap.add(Collections.java:3903)
sandbox.classloader.MyClassLoader.instrument(Unknown Source)
sandbox.classloader.MyClassLoader.loadClass(Unknown Source)
java.lang.ClassLoader.defineClass1(Native Method)
java.lang.ClassLoader.defineClass(ClassLoader.java:791)
java.lang.ClassLoader.defineClass(ClassLoader.java:634)
sandbox.classloader.MyClassLoader.findClass(Unknown Source)
sandbox.classloader.MyClassLoader.loadClass(Unknown Source)
sandbox.Tester.main(Unknown Source)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:601)
com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
所以在我看来,错误实际上是在执行时发生的(例如,我错误地认为它是在检测时发生的),并且是调用的结果hashCode()
。既然如此,hashCode()
我(可能错误地)剥夺了它的本机方法之一native
修饰符。所以很明显它是calling the native
- 删除导致问题的方法。
看起来是什么really奇怪的是堆栈跟踪只有 16 帧深;鉴于这是一个StackOverflowError
.