我有一个项目,我已经为Log4j添加了一个可选的依赖项:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.19.0</version>
<optional>true</optional>
</dependency>
在我的模块描述符中,我添加了实现和API的需求:
requires static org.apache.logging.log4j;
requires static org.apache.logging.log4j.core;
如果我将项目构建为预模块项目,则项目构建成功。但是,当我将项目构建为模块时,JUnit失败了。虽然最初的错误并不清楚,但将-e
添加到Maven命令中会显示以下错误:
TestEngine with ID 'junit-jupiter' failed to discover tests
org.junit.platform.commons.JUnitException: TestEngine with ID 'junit-jupiter' failed to discover tests
at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverEngineRoot(EngineDiscoveryOrchestrator.java:160)
at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverSafely(EngineDiscoveryOrchestrator.java:132)
at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:107)
at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:78)
at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:110)
at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:78)
at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.discover(DefaultLauncherSession.java:81)
at org.apache.maven.surefire.junitplatform.LazyLauncher.discover(LazyLauncher.java:48)
at org.apache.maven.surefire.junitplatform.TestPlanScannerFilter.accept(TestPlanScannerFilter.java:56)
at org.apache.maven.surefire.api.util.DefaultScanResult.applyFilter(DefaultScanResult.java:102)
at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.scanClasspath(JUnitPlatformProvider.java:167)
at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:139)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:456)
at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:169)
at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:595)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:581)
Caused by: org.junit.platform.commons.JUnitException: ClassSelector [className = 'com.github.robtimus.junit.support.extension.testlogger.Log4jLoggerContextTest'] resolution failed
at org.junit.platform.launcher.listeners.discovery.AbortOnFailureLauncherDiscoveryListener.selectorProcessed(AbortOnFailureLauncherDiscoveryListener.java:39)
at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolveCompletely(EngineDiscoveryRequestResolution.java:103)
at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.run(EngineDiscoveryRequestResolution.java:83)
at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolver.resolve(EngineDiscoveryRequestResolver.java:113)
at org.junit.jupiter.engine.discovery.DiscoverySelectorResolver.resolveSelectors(DiscoverySelectorResolver.java:46)
at org.junit.jupiter.engine.JupiterTestEngine.discover(JupiterTestEngine.java:69)
at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverEngineRoot(EngineDiscoveryOrchestrator.java:152)
... 15 more
Caused by: java.lang.NoClassDefFoundError: org/apache/logging/log4j/util/Supplier
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1017)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1096)
at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:206)
at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:759)
at java.base/jdk.internal.loader.BuiltinClassLoader.findClassInModuleOrNull(BuiltinClassLoader.java:680)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:605)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:579)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3166)
at java.base/java.lang.Class.getDeclaredMethods(Class.java:2309)
at org.junit.platform.commons@1.9.0/org.junit.platform.commons.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:1494)
at org.junit.platform.commons@1.9.0/org.junit.platform.commons.util.ReflectionUtils.findMethod(ReflectionUtils.java:1343)
at org.junit.platform.commons@1.9.0/org.junit.platform.commons.util.ReflectionUtils.isMethodPresent(ReflectionUtils.java:1244)
at org.junit.jupiter.engine.discovery.predicates.IsTestClassWithTests.hasTestOrTestFactoryOrTestTemplateMethods(IsTestClassWithTests.java:50)
at org.junit.jupiter.engine.discovery.predicates.IsTestClassWithTests.test(IsTestClassWithTests.java:46)
at org.junit.jupiter.engine.discovery.ClassSelectorResolver.resolve(ClassSelectorResolver.java:67)
at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.lambda$resolve$2(EngineDiscoveryRequestResolution.java:135)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1632)
at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:127)
at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:502)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:488)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:543)
at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:189)
at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:126)
at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolveCompletely(EngineDiscoveryRequestResolution.java:92)
... 20 more
Caused by: java.lang.ClassNotFoundException: org.apache.logging.log4j.util.Supplier
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
... 52 more
不幸的是,这就是我卡住的地方。当我添加-X
时,我看到API和核心模块在编译和运行测试时都被添加到模块路径中。这是从创建的surefireargs
文件:
--module-path
"D:\Code\Java\github\misc\junit-support\target\classes;D:\Programs\Maven.repository\org\junit\jupiter\junit-jupiter-api\5.9.0\junit-jupiter-api-5.9.0.jar;D:\Programs\Maven.repository\org\junit\platform\junit-platform-commons\1.9.0\junit-platform-commons-1.9.0.jar;D:\Programs\Maven.repository\org\junit\jupiter\junit-jupiter-params\5.9.0\junit-jupiter-params-5.9.0.jar;D:\Programs\Maven.repository\org\hamcrest\hamcrest\2.2\hamcrest-2.2.jar;D:\Programs\Maven.repository\org\mockito\mockito-core\4.8.0\mockito-core-4.8.0.jar;D:\Programs\Maven.repository\com\github\robtimus\io-functions\2.0\io-functions-2.0.jar;D:\Programs\Maven.repository\org\apache\logging\log4j\log4j-api\2.19.0\log4j-api-2.19.0.jar;D:\Programs\Maven.repository\org\apache\logging\log4j\log4j-core\2.19.0\log4j-core-2.19.0.jar;D:\Programs\Maven.repository\ch\qos\logback\logback-classic\1.4.5\logback-classic-1.4.5.jar;D:\Programs\Maven.repository\ch\qos\logback\logback-core\1.4.5\logback-core-1.4.5.jar;D:\Programs\Maven.repository\org\slf4j\slf4j-api\2.0.4\slf4j-api-2.0.4.jar;D:\Programs\Maven.repository\ch\qos\reload4j\reload4j\1.2.23\reload4j-1.2.23.jar;D:\Programs\Maven.repository\org\opentest4j\opentest4j\1.2.0\opentest4j-1.2.0.jar;D:\Programs\Maven.repository\org\apiguardian\apiguardian-api\1.1.2\apiguardian-api-1.1.2.jar"
--class-path
"D:\Programs\Maven.repository\org\apache\maven\surefire\surefire-booter\3.0.0-M7\surefire-booter-3.0.0-M7.jar;D:\Programs\Maven.repository\org\apache\maven\surefire\surefire-api\3.0.0-M7\surefire-api-3.0.0-M7.jar;D:\Programs\Maven.repository\org\apache\maven\surefire\surefire-logger-api\3.0.0-M7\surefire-logger-api-3.0.0-M7.jar;D:\Programs\Maven.repository\org\apache\maven\surefire\surefire-shared-utils\3.0.0-M7\surefire-shared-utils-3.0.0-M7.jar;D:\Programs\Maven.repository\org\apache\maven\surefire\surefire-extensions-spi\3.0.0-M7\surefire-extensions-spi-3.0.0-M7.jar;D:\Code\Java\github\misc\junit-support\target\test-classes;D:\Programs\Maven.repository\org\junit\jupiter\junit-jupiter\5.9.0\junit-jupiter-5.9.0.jar;D:\Programs\Maven.repository\org\junit\jupiter\junit-jupiter-engine\5.9.0\junit-jupiter-engine-5.9.0.jar;D:\Programs\Maven.repository\org\junit\platform\junit-platform-engine\1.9.0\junit-platform-engine-1.9.0.jar;D:\Programs\Maven.repository\net\bytebuddy\byte-buddy\1.12.14\byte-buddy-1.12.14.jar;D:\Programs\Maven.repository\net\bytebuddy\byte-buddy-agent\1.12.14\byte-buddy-agent-1.12.14.jar;D:\Programs\Maven.repository\org\objenesis\objenesis\3.2\objenesis-3.2.jar;D:\Programs\Maven.repository\commons-io\commons-io\2.11.0\commons-io-2.11.0.jar;D:\Programs\Maven.repository\org\junit\platform\junit-platform-testkit\1.9.0\junit-platform-testkit-1.9.0.jar;D:\Programs\Maven.repository\org\assertj\assertj-core\3.23.1\assertj-core-3.23.1.jar;D:\Programs\Maven.repository\org\junit\platform\junit-platform-launcher\1.9.0\junit-platform-launcher-1.9.0.jar;D:\Programs\Maven.repository\org\junit-pioneer\junit-pioneer\1.9.0\junit-pioneer-1.9.0.jar;D:\Programs\Maven.repository\org\apache\maven\surefire\surefire-junit-platform\3.0.0-M7\surefire-junit-platform-3.0.0-M7.jar;D:\Programs\Maven.repository\org\apache\maven\surefire\common-java5\3.0.0-M7\common-java5-3.0.0-M7.jar"
--patch-module
com.github.robtimus.junit.support="D:\Code\Java\github\misc\junit-support\target\test-classes"
--add-opens
com.github.robtimus.junit.support/com.github.robtimus.junit.support=ALL-UNNAMED
--add-opens
com.github.robtimus.junit.support/com.github.robtimus.junit.support.examples.collections=ALL-UNNAMED
--add-opens
com.github.robtimus.junit.support/com.github.robtimus.junit.support.examples.covariantreturn=ALL-UNNAMED
--add-opens
com.github.robtimus.junit.support/com.github.robtimus.junit.support.examples.delegation=ALL-UNNAMED
--add-opens
com.github.robtimus.junit.support/com.github.robtimus.junit.support.examples.io=ALL-UNNAMED
--add-opens
com.github.robtimus.junit.support/com.github.robtimus.junit.support.extension=ALL-UNNAMED
--add-opens
com.github.robtimus.junit.support/com.github.robtimus.junit.support.extension.testlogger=ALL-UNNAMED
--add-opens
com.github.robtimus.junit.support/com.github.robtimus.junit.support.extension.testresource=ALL-UNNAMED
--add-opens
com.github.robtimus.junit.support/com.github.robtimus.junit.support.params=ALL-UNNAMED
--add-opens
com.github.robtimus.junit.support/com.github.robtimus.junit.support.test.collections=ALL-UNNAMED
--add-modules
com.github.robtimus.junit.support
--add-reads
com.github.robtimus.junit.support=ALL-UNNAMED
org.apache.maven.surefire.booter.ForkedBooter
我也尝试打开类的包,但随后我得到以下警告:
WARNING: Unknown module: org.apache.logging.log4j specified to --add-opens
因此,即使两个Log4j模块都添加到模块路径中,并且org.apache.logging.log4j.util.Supplier
存在于JAR文件中,但在运行测试时无法找到它。这甚至没有本地化到我的本地机器;GitHub动作也失败了:https://github.com/robtimus/junit-support/actions/runs/3558874573/jobs/5977845973
编辑:添加以下插件并不能解决问题(插件已经将源和目标设置为11):
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<release>11</release>
</configuration>
</plugin>
我通过将--add-modules
添加到surefire插件的argLine
来解决这个问题。我不仅要添加Logj4,还要添加logback,它们都有同样的问题。另外,因为我在日志配置中添加了一些自定义测试附件,所以我也必须打开这些模块的包。
结果:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>
--add-modules org.apache.logging.log4j
--add-modules ch.qos.logback.classic
--add-modules ch.qos.logback.core
--add-opens com.github.robtimus.junit.support/com.github.robtimus.junit.support.extension.testlogger=java.logging
--add-opens com.github.robtimus.junit.support/com.github.robtimus.junit.support.extension.testlogger=org.apache.logging.log4j.core
--add-opens com.github.robtimus.junit.support/com.github.robtimus.junit.support.extension.testlogger=ch.qos.logback.core
--add-opens com.github.robtimus.junit.support/com.github.robtimus.junit.support.extension.testlogger=ch.qos.reload4j
<!-- other existing add-opens omitted -->
</argLine>
</configuration>
</plugin>