6

当我运行这个测试时(使用 jmockit 和 TestNG,不确定这是否相关):

public class Test {
  @Test public void test(@Mocked ProcessBuilder pb) throws IOException {
    new Expectations() {{ pb.start(); result = null; }};
    assertNull(m());
  }

  public static Process m() throws IOException {
    return new ProcessBuilder("").start();
  }
}

我得到这个例外:

java.lang.IllegalAccessError: class java.lang.ProcessBuilder (in module java.base) cannot access class javax.print.PrintException (in module java.desktop) because module java.base does not read module java.desktop

at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java)
....

我正在使用构建 177。

我可以使用--add-reads java.base=java.desktop参数重新运行测试,它工作正常,但我真的不明白这里发生了什么。

为什么我得到那个例外?

4

2 回答 2

8

IllegalAccessError 提示 JMockit 已通过对 java.desktop 模块中的异常的引用来检测 ProcessBuilder(在 java.base 中)。我不知道它为什么选择这个例外,这可能是 JMockit 邮件列表的东西。但是,它确实解释了为什么--add-reads解决了这个问题。

于 2017-07-10T19:36:00.227 回答
2

问题已针对 JMockit 1.34 进行了修复。

在启动期间,JMockit 会修改一个 JRE 类(添加一些字段),以便为 JRE 类的模拟提供支持。被修改的实际类是任意的,并且javax.print.PrintException被使用(作为次要选择)只是因为它通常不会在典型的测试运行中加载。在 JDK 9 上,这个类不能从“基础”模块访问,所以现在它被另一个替换了。

于 2017-07-13T02:17:17.190 回答