Поддерживает ли JPMS сервисы от META-INF / сервисы для автоматических модулей? - PullRequest
0 голосов
/ 05 ноября 2018

Здесь вы можете найти следующие сведения об автоматических модулях:

Модульная система также сканирует META-INF / services и выполняет автоматическую Модуль предоставления названных в нем услуг. Автоматический модуль Предполагается, что разрешено использовать все услуги.

Однако у меня следующая ситуация. Я хочу использовать log4j2 с slf4j в JPMS. Для этого log4j-slf4j-impl-2.11.1.jar должен предоставить услугу JPMS slf4j-api-1.8.0-beta2.jar. Разработчики log4j сделали log4j-slf4j-impl-2.11.1.jar автоматическим модулем и предоставили сервис через META-INF / services. Однако, это не работает, это дает следующее:

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/logging/log4j/Logger
    at org.apache.logging.log4j.slf4j@2.11.1/org.apache.logging.slf4j.SLF4JServiceProvider.initialize(SLF4JServiceProvider.java:53)
    at org.slf4j/org.slf4j.LoggerFactory.bind(LoggerFactory.java:153)
    at org.slf4j/org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:141)
    at org.slf4j/org.slf4j.LoggerFactory.getProvider(LoggerFactory.java:419)
    at org.slf4j/org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:405)
    at org.slf4j/org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:354)
    at org.slf4j/org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:380)
    at Log4j2Slf4jJdk11/com.temp.NewMain.<clinit>(NewMain.java:12)
Caused by: java.lang.ClassNotFoundException: org.apache.logging.log4j.Logger
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    ... 8 more

Я решил добавить информацию о модуле в log4j-slf4j-impl-2.11.1.jar и экспортировать сервис в формате JPMS через provides ... with... И проблема была решена - я не получаю NoClassDefFoundError. Это ссылка на проблему.

Итак, мои вопросы:

  1. Службы поддержки JPMS в META-INF / службы автоматических модулей?
  2. если да, то как объяснить такое поведение?

EDIT Всего 5 модулей:

slf4j-api-1.8.0-beta2.jar  // name: org.slf4j
log4j-slf4j18-impl-2.11.1.jar // name: org.apache.logging.log4j.slf4j
log4j-core-2.11.1.jar // name: org.apache.logging.log4j.core
log4j-api-2.11.1.jar // name: org.apache.logging.log4j
log4j2-slf4j-jdk11-1.0-SNAPSHOT.jar // name: Log4j2Slf4jJdk11

VARIANT 1 Если я запускаю --show-module-resolution, когда log4j-slf4j18-impl-2.11.1.jar имеет META-INF/services, я получаю следующий фрагмент (я заменил полный путь на ...):

...
root Log4j2Slf4jJdk11 file:.../log4j2-slf4j-jdk11-1.0-SNAPSHOT.jar
Log4j2Slf4jJdk11 requires org.slf4j file:.../slf4j-api-1.8.0-beta2.jar
jdk.compiler binds org.apache.logging.log4j.core file:.../log4j-core-2.11.1.jar automatic
org.slf4j binds org.apache.logging.log4j.slf4j file:.../log4j-slf4j18-impl-2.11.1.jar automatic

VARIANT 2 Если я запускаю --show-module-resolution, когда log4j-slf4j18-impl-2.11.1.jar имеет module-info, я получаю следующий фрагмент:

...
root Log4j2Slf4jJdk11 file:.../log4j2-slf4j-jdk11-1.0-SNAPSHOT.jar
Log4j2Slf4jJdk11 requires org.slf4j file:.../slf4j-api-1.8.0-beta2.jar
jdk.compiler binds org.apache.logging.log4j.core file:.../log4j-core-2.11.1.jar automatic
org.slf4j binds org.apache.logging.log4j.slf4j file:.../log4j-slf4j18-impl-2.11.1.jar
org.apache.logging.log4j.slf4j requires org.slf4j file:.../slf4j-api-1.8.0-beta2.jar
org.apache.logging.log4j.slf4j requires org.apache.logging.log4j.core file:.../log4j-core-2.11.1.jar automatic
org.apache.logging.log4j.slf4j requires org.apache.logging.log4j file:.../log4j-api-2.11.1.jar
org.apache.logging.log4j binds org.apache.logging.log4j.core file:.../log4j-core-2.11.1.jar automatic

В VARIANT 1 служба из org.apache.logging.log4j.slf4j не может загрузить класс (org.apache.logging.log4j.Logger) из org.apache.logging.log4j.core. В VARIANT 2 служба из org.apache.logging.log4j.slf4j загружает все классы из org.apache.logging.log4j.core и все в порядке. Мы видим в выходе VARIANT 2, что есть строка

org.apache.logging.log4j.slf4j requires org.apache.logging.log4j.core

а в VARIANT 1 такой строки нет. Проблема в этом? Но если два модуля являются автоматическими, они не могут быть разрешены автоматически?

1 Ответ

0 голосов
/ 05 ноября 2018

SLF4J 1.8 требует реализации org.slf4j.spi.SLF4JServiceProvider в качестве открытой службы. Обнаружено, что в банке log4j-slf4j18-impl. Однако для моста Log4j SLF4J требуется API Log4J (модуль org.apache.logging.log4j). Несмотря на то, что это явный модуль Java, поскольку на него ссылаются только из автоматического модуля, он не загружается, что приводит к исключению ClassNotFoundException.

Простым решением этого является включение --addmodules = org.apache.logging.log4j в командной строке при запуске приложения.

...