[英]Does JPMS support services from META-INF/services for automatic modules?
Here you can find the the following about automatic modules: 在这里您可以找到有关自动模块的以下内容:
The module system also scans META-INF/services and makes the automatic module provide the services named therein.
模块系统还扫描META-INF /服务并使自动模块提供其中命名的服务。 An automatic module is assumed allowed to use all services.
假设允许自动模块使用所有服务。
However, I have the following situation. 但是,我有以下情况。 I want to use log4j2 with slf4j in JPMS.
我想在JPMS中使用log4j2和slf4j。 In order to do it
log4j-slf4j-impl-2.11.1.jar
must provide JPMS service to slf4j-api-1.8.0-beta2.jar
. 为了做到这一点,
log4j-slf4j-impl-2.11.1.jar
必须向slf4j-api-1.8.0-beta2.jar
提供JPMS服务。 The developers of log4j made log4j-slf4j-impl-2.11.1.jar
as automatic module and provided service via META-INF/services. log4j的开发人员将
log4j-slf4j-impl-2.11.1.jar
作为自动模块并通过META-INF / services提供服务。 However, it doesn't work, at it gives the following: 但是,它不起作用,它给出了以下内容:
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
I decided to add module-info to log4j-slf4j-impl-2.11.1.jar
and export service in JPMS manner via provides ... with..
. 我决定将module-info添加到
log4j-slf4j-impl-2.11.1.jar
并以JPMS方式导出服务,通过provides ... with..
And the problem was solved - I don't get any NoClassDefFoundError
. 问题解决了 - 我没有得到任何
NoClassDefFoundError
。 This is link to the issue. 这是该问题的链接 。
So my questions: 所以我的问题:
EDIT There are total 5 modules: 编辑共有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 If I run --show-module-resolution when log4j-slf4j18-impl-2.11.1.jar
has META-INF/services
I get the following piece of output (I replaced full path with ...
): 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 If I run --show-module-resolution when log4j-slf4j18-impl-2.11.1.jar
has module-info
I get the following piece of output: 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
In VARIANT 1 the service from org.apache.logging.log4j.slf4j
can not load class ( org.apache.logging.log4j.Logger
) from org.apache.logging.log4j.core
. 在变体1从服务
org.apache.logging.log4j.slf4j
无法加载类( org.apache.logging.log4j.Logger
从) org.apache.logging.log4j.core
。 In VARIANT 2 the service from org.apache.logging.log4j.slf4j
loads all classes from org.apache.logging.log4j.core
and everything is ok. 在VARIANT 2从服务
org.apache.logging.log4j.slf4j
从加载的所有类org.apache.logging.log4j.core
,一切都OK。 We see in the ouput of VARIANT 2 that there is a line 我们在VARIANT 2的输出中看到有一条线
org.apache.logging.log4j.slf4j requires org.apache.logging.log4j.core
and there is no such line in VARIANT 1. Is the problem in this? 在VARIANT 1中没有这样的一行。问题在于此吗? But if two modules are automatic can't they be resolved automatically?
但如果两个模块是自动的,它们是不是可以自动解决?
SLF4J 1.8 requires an implementation of org.slf4j.spi.SLF4JServiceProvider as an exposed service. SLF4J 1.8需要将org.slf4j.spi.SLF4JServiceProvider实现为公开服务。 It is finding that in the log4j-slf4j18-impl jar.
它在log4j-slf4j18-impl jar中找到了。 However, the Log4j SLF4J bridge requires the Log4J API (module org.apache.logging.log4j).
但是,Log4j SLF4J桥需要Log4J API(模块org.apache.logging.log4j)。 Even though that is an explicit Java module, because it is only referenced from an automatic module it is not being loaded, resulting in the ClassNotFoundException.
即使这是一个显式的Java模块,因为它只是从一个自动模块引用它没有被加载,导致ClassNotFoundException。
The simple solution to this is to include --addmodules=org.apache.logging.log4j on the command line when starting the application. 对此的简单解决方案是在启动应用程序时在命令行中包含--addmodules = org.apache.logging.log4j。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.