簡體   English   中英

JPMS是否支持META-INF /自動模塊服務?

[英]Does JPMS support services from META-INF/services for automatic modules?

在這里您可以找到有關自動模塊的以下內容:

模塊系統還掃描META-INF /服務並使自動模塊提供其中命名的服務。 假設允許自動模塊使用所有服務。

但是,我有以下情況。 我想在JPMS中使用log4j2和slf4j。 為了做到這一點, log4j-slf4j-impl-2.11.1.jar必須向slf4j-api-1.8.0-beta2.jar提供JPMS服務。 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

我決定將module-info添加到log4j-slf4j-impl-2.11.1.jar並以JPMS方式導出服務,通過provides ... with.. 問題解決了 - 我沒有得到任何NoClassDefFoundError 這是該問題的鏈接

所以我的問題:

  1. JPMS是否支持META-INF /自動模塊服務?
  2. 如果是,那么如何解釋這種行為呢?

編輯共有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.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如果我運行--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

在變體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 ,一切都OK。 我們在VARIANT 2的輸出中看到有一條線

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

在VARIANT 1中沒有這樣的一行。問題在於此嗎? 但如果兩個模塊是自動的,它們是不是可以自動解決?

SLF4J 1.8需要將org.slf4j.spi.SLF4JServiceProvider實現為公開服務。 它在log4j-slf4j18-impl jar中找到了。 但是,Log4j SLF4J橋需要Log4J API(模塊org.apache.logging.log4j)。 即使這是一個顯式的Java模塊,因為它只是從一個自動模塊引用它沒有被加載,導致ClassNotFoundException。

對此的簡單解決方案是在啟動應用程序時在命令行中包含--addmodules = org.apache.logging.log4j。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM