I set up a small test project using java 9 modules. The structure looks like this:
.
├── build.gradle
└── src
├── main
│ └── java
│ ├── module-info.java
│ └── slfTest
│ └── Main.java
└── test
└── java
└── slfTest
└── MainTest.java
(Feel free to clone and have a look yourself: git clone https://github.com/michas2/slfTest.git
)
The classes Main and Main Test only log some simple output:
Logger logger = LoggerFactory.getLogger(Main.class);
logger.info("Hello World");
Now gradle run
works as expected, but gradle test
gives a ClassCastException.
$ gradle run -q
[main] INFO slfTest.Main - Hello World
$ gradle test -q
java.lang.ClassCastException: org.slf4j.simple/org.slf4j.simple.SimpleLoggerFactory cannot be cast to org.gradle.internal.logging.slf4j.OutputEventListenerBackedLoggerContext
at org.gradle.internal.logging.slf4j.Slf4jLoggingConfigurer.configure(Slf4jLoggingConfigurer.java:42)
at org.gradle.internal.logging.config.LoggingSystemAdapter.startCapture(LoggingSystemAdapter.java:54)
at org.gradle.internal.logging.services.DefaultLoggingManager$StartableLoggingSystem.start(DefaultLoggingManager.java:297)
at org.gradle.internal.logging.services.DefaultLoggingManager.start(DefaultLoggingManager.java:73)
at org.gradle.internal.logging.services.DefaultLoggingManager.start(DefaultLoggingManager.java:37)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:83)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:64)
at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:62)
at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:67)
Removing the java 9 module makes things work again. Therefore I assume there is module access problem. - What is the right way to fix it?
The content of module-info.java
is:
module slfTest {
requires org.slf4j;
exports slfTest;
}
When gradle runs the tests, gradle tries to inject its own logging backend. - Guess this is the part where some module access problem arise.
Java Module System is a major change in Java 9 version. Java added this feature to collect Java packages and code into a single unit called module. In earlier versions of Java, there was no concept of module to create modular Java applications, that why size of application increased and difficult to move around.
When Project Jigsaw developed the Java Platform Module System it decided that a modular JAR is a regular JAR with a module descriptor, a module-info. class , in its root folder. That means a JAR can only define a single module.
Java 9 Module System has a “java. It's known as Base Module. It's an Independent module and does NOT dependent on any other modules. By default, all other Modules dependent on this module. That's why “java.
No. There is no need to switch to modules. There has never been a need to switch to modules. Java 9 and later releases support traditional JAR files on the traditional class path, via the concept of the unnamed module, and will likely do so until the heat death of the universe.
This is a known issue in gradle.
For more reference see here at
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With