Aquí se puede encontrar la siguiente acerca de los módulos automáticos:
El sistema de módulo también explora META-INF / servicios y hace que el módulo automático de proporcionar los servicios respectivos destinatarios. Se supone permitió un módulo automático para usar todos los servicios.
Sin embargo, tengo la siguiente situación. Quiero usar log4j2 con slf4j en JPMS. Con el fin de hacerlo log4j-slf4j-impl-2.11.1.jar
debe proporcionar el servicio a JPMS slf4j-api-1.8.0-beta2.jar
. Los desarrolladores de log4j hicieron log4j-slf4j-impl-2.11.1.jar
como módulo automático y proporciona servicio a través de META-INF / services. Sin embargo, esto no funciona, por lo que da la siguiente:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/logging/log4j/Logger
at [email protected]/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
He decidido añadir módulo de información de log4j-slf4j-impl-2.11.1.jar
y servicio de exportación en forma JPMS través provides ... with..
. Y el problema se solucionó - no consigo ninguna NoClassDefFoundError
. Se trata de enlace con el tema.
Así que mis preguntas:
- hace servicios de apoyo JPMS en META-INF / servicios de módulos automáticos?
- en caso afirmativo, ¿cómo explicar tal comportamiento?
EDITAR Hay un total de 5 módulos:
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
VARIANTE 1 Si me quedo --show-módulo de resolución cuando se log4j-slf4j18-impl-2.11.1.jar
ha META-INF/services
recibo el siguiente trozo de salida (E sustituye ruta completa con ...
):
...
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
Variante 2 Si me quedo --show-módulo de resolución cuando se log4j-slf4j18-impl-2.11.1.jar
ha module-info
recibo el siguiente trozo de salida:
...
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
En la variante 1 del servicio de org.apache.logging.log4j.slf4j
lata no cargar la clase ( org.apache.logging.log4j.Logger
) a partir de org.apache.logging.log4j.core
. En la variante 2 del servicio de org.apache.logging.log4j.slf4j
cargas de todas las clases org.apache.logging.log4j.core
y todo está bien. Vemos parte de la salida de la variante 2 que hay una línea de
org.apache.logging.log4j.slf4j requires org.apache.logging.log4j.core
y no hay tal línea en la variante 1. ¿El problema en esto? Pero si dos módulos son automáticas no pueden ser resueltos de forma automática?
SLF4J 1.8 requiere una implementación de org.slf4j.spi.SLF4JServiceProvider como un servicio expuesto. Se trata de encontrar que en el tarro de log4j-slf4j18-impl. Sin embargo, el puente Log4J SLF4J requiere la API Log4J (módulo org.apache.logging.log4j). A pesar de que esto es un módulo explícita de Java, ya que sólo se hace referencia a un módulo automático no está siendo cargado, lo que resulta en el ClassNotFoundException.
La solución simple para esto es incluir --addmodules = org.apache.logging.log4j en la línea de comandos al iniciar la aplicación.