module java.base does not read module java.desktop
Asked Answered
U

2

7

When I run this test (using jmockit and TestNG, not sure if that's relevant):

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();
  }
}

I get this exception:

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)
....

I am using build 177.

I can rerun the test using --add-reads java.base=java.desktop argument and it works fine but I don't really understand what is happening here.

Why am I getting that exception?

Unhealthy answered 10/7, 2017 at 17:33 Comment(3)
My guess would be some interaction with classes that are being loaded implicitly; PrintException does extend IOException, and this feels like the inexplicable HeadlessExceptions when using something not obviously Swing-related. I suggest filing a bug about a possible hidden class dependency.Allure
Are the classes/jars on the modulepath or the classpath? Are any modules defined for your code?Tabby
@MichaelEaster on the classpath - I haven't defined any module. It's a simple project with a pom.xml with a dependency on TestNG and jmockit and one file (the Test class in the question). The pom includes an argLine of -Djdk.attach.allowAttachSelf for surefire to allow jmockit to run.Unhealthy
A
2

The issue has been fixed for JMockit 1.34.

During startup, JMockit modifies a JRE class (adding a few fields) in order to provide support for the mocking of JRE classes. The actual class which gets modified is arbitrary, and javax.print.PrintException was used (as a secondary choice) just because it usually never gets loaded in a typical test run. On JDK 9, this class is not accessible from the "base" module, so it was now replaced by another one which is.

Alfieri answered 13/7, 2017 at 2:17 Comment(0)
U
8

The IllegalAccessError hints that JMockit has instrumented ProcessBuilder (in java.base) with a reference to an exception in the java.desktop module. I don't know why it choose this exception, that may be something for the JMockit mailing list. However it does explain why --add-reads fixes the issue.

Unmeant answered 10/7, 2017 at 19:36 Comment(1)
Thanks - I've raised the issue there: github.com/jmockit/jmockit1/issues/428Unhealthy
A
2

The issue has been fixed for JMockit 1.34.

During startup, JMockit modifies a JRE class (adding a few fields) in order to provide support for the mocking of JRE classes. The actual class which gets modified is arbitrary, and javax.print.PrintException was used (as a secondary choice) just because it usually never gets loaded in a typical test run. On JDK 9, this class is not accessible from the "base" module, so it was now replaced by another one which is.

Alfieri answered 13/7, 2017 at 2:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.