静态重新初始化Java类
我们正在开发一个JVMTI Java代理,用于为Java类文件提供工具。它的一小部分是(显然)本地C++代码,但更大的部分是java代码,它通过网络加载并从本地代理代码调用。 我们使用一个代码覆盖率工具来收集java部分的测试覆盖率,java部分进行源代码检测
现在,当我们的代理启动时,一些类被初始化,特别是java。lang.ref.Reference,它启动一个线程。我们的代理使用自定义java代码插入线程启动方法,该代码由代码覆盖工具插入。 coverage工具在java代理代码中放置了一些带有静态初始值设定项的静态内部类,因此这是java的结果。lang.ref.Reference正在初始化
问题是,此时(当java.lang.ref.Reference被初始化时),JVM的一些基本功能还没有到位。具体来说,代码覆盖工具初始值设定项希望访问系统。getProperty(字符串名称),但不是系统。props仍然为null,因此调用会导致NullPointerException。 这导致代码覆盖工具的静态内部类未初始化,该类处于初始化错误状态,结果是NoClassDefFoundError。对该类的每次后续访问都会导致NoClassDefFoundError
我现在的意图是忽略这个初始初始化错误,等待VM_启动,然后将相关类的ClassState重置为“linked”。通过这种方式,我希望JVM将尝试在后续访问类时再次初始化该类
有没有人知道,如果JVMTI的经纪人能做到这一点,并给我一些建议如何做到这一点
# 1 楼答案
VM_启动后重新传输FormClasses将生成一个新的类加载钩子供参考,允许您在安全的VM阶段执行指令插入。。。要么重新传输引用,要么重新传输GetLoadedClass并重新传输它们
# 2 楼答案
从你的描述中,我感觉你的代码耦合得太紧密了。你真正想要的是在你开始测试之前有一个初始化的Java虚拟机
因此,我建议将代码分为三类,而不是混淆本机代码和代理:
null
)的相同方法李>对于测试,实例化模型类。重写测试所需的方法,以便返回测试代码所需的模拟数据对象(有关模拟测试的示例,请参见mockito)
或者,在测试用例中测试Java加载代码。在所有其他测试中,将类添加到类路径中,并像往常一样实例化它