-
Notifications
You must be signed in to change notification settings - Fork 6
Description
In a multi-module project, the generated classpath collects all dependencies of all modules, even though the test-class to mutate "lives" in only one of them.
This is especially problematic when one of the modules contains a "toxic" dependency that conflicts with other modules at runtime.
For example, "log4j-slf4j-impl" and "log4j-to-slf4j" cannot co-exist at runtime, but if one module depends on the first, and one on the latter, no test can be mutated.
An excerpt of the verbose log of PIT:
08:56:32 PIT >> INFO : MINION : 08:56:32 PIT >> FINE : Gathering coverage for test Description [testClass=net.dashumankapital.a.DemoTest, name=[engine:junit-jupiter]/[class:net.dashumankapital.a.DemoTest]/[method:justChecking()]]
08:56:32 PIT >> INFO : MINION : 08:56:32 PIT >> SEVERE : Description [testClass=net.dashumankapital.a.DemoTest, name=[engine:junit-jupiter]/[class:net.dashumankapital.a.DemoTest]/[method:justChecking()]]
08:56:32 PIT >> INFO : MINION : java.lang.ExceptionInInitializerError
08:56:32 PIT >> INFO : MINION : at net.dashumankapital.a.DemoTest.justChecking(DemoTest.java:11)
08:56:32 PIT >> INFO : MINION : at java.base/java.lang.reflect.Method.invoke(Method.java:569)
08:56:32 PIT >> INFO : MINION : at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
08:56:32 PIT >> INFO : MINION : at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
08:56:32 PIT >> INFO : MINION : Caused by: org.apache.logging.log4j.LoggingException: log4j-slf4j-impl cannot be present with log4j-to-slf4j
08:56:32 PIT >> INFO : MINION : at org.apache.logging.slf4j.Log4jLoggerFactory.validateContext(Log4jLoggerFactory.java:67)
08:56:32 PIT >> INFO : MINION : at org.apache.logging.slf4j.Log4jLoggerFactory.newLogger(Log4jLoggerFactory.java:49)
08:56:32 PIT >> INFO : MINION : at org.apache.logging.slf4j.Log4jLoggerFactory.newLogger(Log4jLoggerFactory.java:32)
08:56:32 PIT >> INFO : MINION : at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(AbstractLoggerAdapter.java:52)
08:56:32 PIT >> INFO : MINION : at org.apache.logging.slf4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:32)
08:56:32 PIT >> INFO : MINION : at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:363)
08:56:32 PIT >> INFO : MINION : at org.apache.logging.slf4j.SLF4JLoggerContext.getLogger(SLF4JLoggerContext.java:39)
08:56:32 PIT >> INFO : MINION : at org.apache.logging.log4j.spi.LoggerContext.getLogger(LoggerContext.java:46)
08:56:32 PIT >> INFO : MINION : at org.apache.logging.log4j.LogManager.getLogger(LogManager.java:555)
08:56:32 PIT >> INFO : MINION : at net.dashumankapital.a.Demo.<clinit>(Demo.java:7)
08:56:32 PIT >> INFO : MINION : ... 4 more
I will attach a small sample project that demonstrates this.
Pick either of the test classes. "Normal" test execution works just fine. The sample project is naturally bogus, the most important bit is that neither module pulls in both dependencies, but in combination they do, and they do not depend on each other.
My "real" project consists of many modules, some of them totally independent, containing legacy stuff. And of those, one of them uses such "toxic" dependency (which I cannot get easily rid of). Since there is no Maven/dependency trickery to pull that I'm aware of, this effectively prevents mutating any test class of the entire project.
My proposed solution would be to use only the modules for classpath-file generation that are actually needed by the test(s).