模块 java.base 不读取模块 java.desktop

module java.base does not read module java.desktop

当我 运行 这个测试(使用 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)
....

我正在使用 build 177。

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

为什么我得到那个异常?

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

issue 已针对 JMockit 1.34 修复。

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