我们正在研究用于测试java类文件的JVMTI Java代理。它的一小部分(显然)是本地C++代码,但更大的部分是Java代码,它通过网络加载并从本地代理程序代码调用。 我们使用代码覆盖工具来收集测试覆盖的java部分,它做源代码的工具。重新初始化Java类
现在,当我们的代理启动时,一些类会被初始化,特别是启动一个Thread的java.lang.ref.Reference。我们的代理使用自定义Java代码来处理线程启动方法,该代码由代码覆盖率工具进行检测。 覆盖工具将静态初始化器的一些静态内部类放入我们的Java代理程序代码中,所以这将作为java.lang.ref.Reference初始化的结果而执行。
问题是,在这个时候(当java.lang.ref.Reference被初始化时),JVM的一些基本功能还没有到位。具体来说,代码覆盖工具初始值设定项要访问System.getProperty(String name),但System.props仍然为空,因此调用会导致NullPointerException。 这导致代码覆盖率工具的静态内部类未被初始化,该类处于状态initialization_error,结果为NoClassDefFoundError。每次跟进访问此类都会导致NoClassDefFoundError。
我现在的意图是忽略这个初始化初始化错误,并等到VM_Start,然后重新设置相关类的ClassState为“链接”。这样我希望JVM会在后续访问类时再次尝试初始化类。
有没有人有一个想法,如果这可以从JVMTI代理完成,并给我一些建议如何做到这一点?
我们正处于一个集成测试的场景,也就是说我们希望在“真实世界”情况下而不是在模拟中测试我们的仪器和仪器化代码。正如我在之前的评论中所说的,唯一的问题是代码覆盖工具,它过早地进入游戏。由于这个工具不在我们的控制之下,并且是封闭源,所以我没有可能在那里改变任何东西。 – Ron 2011-03-15 14:22:58
PS:是的,你说得对,本机代码与虚拟机紧密耦合,但这就是我们想要的东西:我们需要尽可能深入地发现虚拟机中发生的任何事情。这不是任何最终用户应用程序,这是一个非常技术性的分析工具。 – Ron 2011-03-15 14:25:53
尝试像JaCoCo或EclEmma这样的其他代码覆盖工具。 – 2011-03-16 14:24:49