java - 重新初始化 Java 类

标签 java static initialization jvmti

我们正在开发 JVMTI Java 代理,用于检测 Java 类文件。其中一小部分(显然)是 native C++ 代码,但较大部分是 Java 代码,它通过网络加载并从 native 代理代码调用。 我们使用代码覆盖率工具来收集 java 部分的测试覆盖率,该部分执行源代码检测。

现在,当我们的代理启动时,一些类会被初始化,特别是 java.lang.ref.Reference,它会启动一个线程。我们的代理使用自定义 java 代码来检测线程启动方法,该代码由代码覆盖率工具检测。 覆盖工具在我们的 java 代理代码中放置了一些带有静态初始化器的静态内部类,因此它会作为 java.lang.ref.Reference 初始化的结果而被执行。

问题是,此时(当 java.lang.ref.Reference 初始化时),JVM 的一些基本功能尚未到位。具体来说,代码覆盖工具初始值设定项想要访问 System.getProperty(String name),但 System.props 仍然为 null,因此调用会导致 NullPointerException。 这导致代码覆盖工具的静态内部类未初始化,该类处于初始化错误状态,结果为NoClassDefFoundError。每次对此类的后续访问都会导致 NoClassDefFoundError。

我现在的意图是忽略这个初始初始化错误,并等到VM_Start,然后将相关类的ClassState重置为“linked”。这样我希望 JVM 在后续访问该类时会尝试再次初始化该类。

有谁知道是否可以通过 JVMTI 代理来完成此操作,并给我一些如何完成此操作的建议?

最佳答案

从你的描述中,我感觉你的代码耦合得太紧了。您真正想要的是在开始测试之前拥有一个已初始化的 Java VM。

因此,我建议将代码分为三个类,而不是搞乱 native 代码和代理:

  • 抽象基类中的 Java 代码
  • 扩展基类并使用 native C++ 代码实现抽象方法的类。理想情况下,此类不应包含除 native 方法声明之外的任何 Java 代码。
  • 用于测试的模型类,它定义了具有空主体(或仅返回 null)的相同方法。

对于测试,实例化模型类。覆盖测试所需的方法,以便您可以返回被测代码所需的模拟数据对象(有关模拟测试的一些示例,请参阅 mockito)

或者,在测试用例中测试 Java 加载代码。在所有其他测试中,将类添加到类路径中并像往常一样实例化它。

关于java - 重新初始化 Java 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5311850/

相关文章:

java - 为什么这段代码有效?

Java Swing JScrollPane 不滚动/缩放

java - 如何将 Observable<byte[]> 转换为 Observable<String>?

java - 看不见的 window 是贪婪的

php - 判断一个静态方法是被静态调用还是作为实例方法被调用

java - 从 DatePicker 更新 TextView

c - 未初始化的指针与 NULL 和 0

ios - 数组初始化导致构建失败 - arrayForceCastU

javascript - 复选框初始化(具体化)

java - 排序数组 - 谁能帮助我解决失败的问题?