Maven: класс Log4j не найден

У меня есть проект, для которого я добавил необязательную зависимость к 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 [email protected]/org.junit.platform.commons.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:1494)
        at [email protected]/org.junit.platform.commons.util.ReflectionUtils.findMethod(ReflectionUtils.java:1343)
        at [email protected]/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>

Поскольку версия 2.x не полностью модульная, можете ли вы проверить последнюю версию 3.0.0-SNAPSHOT? Он доступен в репозитории Apache Repository Maven.

Piotr P. Karwasz 27.11.2022 18:53

К сожалению, это дает мне ошибки компилятора из-за несовместимости между версиями 2.x и 3.x. Например, github.com/apache/logging-log4j2/blob/release-2.x/log4j-core‌​/… перемещен на github.com/apache/logging-log4j2/blob/master/log4j. -plugins/s‌​rc/…

Rob Spoor 27.11.2022 19:56

Мы будем очень признательны за отзывы о версии 3.0, так как она приближается к тому моменту, когда мы хотим ее выпустить. Поскольку основной мотивацией для версии 3.0 была полная поддержка JPMS, чем раньше мы получим обратную связь, тем лучше. Плагины НЕ должны перекомпилироваться, но если вы перекомпилируете, вам придется обновить исходный код.

rgoers 27.11.2022 23:40

@rgoers Теперь я вижу, что плагины были выделены в отдельный модуль. Однако с переименованием пакета это означает, что любые существующие плагины (вероятно) не будут работать. Это проверялось?

Rob Spoor 28.11.2022 09:15

Я нашел решение, смотрите ниже. Не знаю, почему мне пришлось делать это для Log4j и logback, но не для reload4j, SLF4J или java.logging.

Rob Spoor 28.11.2022 17:47

@RobSpoor Да, это было протестировано, но вполне возможно, что со всеми изменениями, происходящими в 3.0, что-то не работает. Если вы столкнетесь с какими-либо проблемами, будет приятно, если вы предоставите команде Log4j тест, иллюстрирующий это.

rgoers 29.11.2022 20:03

@rgoers Я проверил это и создал Issues.apache.org/jira/browse/LOG4J2-3640 с моими выводами.

Rob Spoor 03.12.2022 14:58
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
7
300
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я решил проблему, добавив --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>

Да, вам придется открывать свои пакеты для других модулей, которым необходим к ним доступ.

rgoers 29.11.2022 20:04

В этом случае нужно только позволить фреймворкам ведения журналов создавать экземпляры моих классов приложений. Фактический код использует их общедоступные API только в качестве потребителя.

Rob Spoor 29.11.2022 20:22

Другие вопросы по теме