简体   繁体   English

JPMS是否支持META-INF /自动模块服务?

[英]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: 所以我的问题:

  1. does JPMS support services in META-INF/services of automatic modules? JPMS是否支持META-INF /自动模块服务?
  2. if yes, then how to explain such behavior? 如果是,那么如何解释这种行为呢?

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.jarMETA-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.jarmodule-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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM