qos-ch / slf4j

Simple Logging Facade for Java
http://www.slf4j.org
MIT License
2.32k stars 980 forks source link

org.slf4j.LoggerFactory (in module org.slf4j) cannot access class org.slf4j.impl.StaticLoggerBinder (JPMS APPLICATION) #415

Open xiz2008shy opened 4 months ago

xiz2008shy commented 4 months ago
       <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.23.1</version>
        </dependency>

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.23.1</version>
        </dependency>

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.23.1</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>2.0.13</version>
        </dependency>

log4j2.xml

<Properties>
        <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss,SSS} %highlight{%-5level} [%t] %highlight{%c{1.}.%M(%L)}: %msg%n" />
        <property name="FILE_PATH" value="${sys:LogHomeRoot}" />
</Properties>
...
    public static void main(String[] args){
          String runLogDir = STR."\{System.getProperty("user.dir")}\{File.separator}log";
          System.setProperty("LogHomeRoot", runLogDir);
          ....
    }

In the scenario described, I attempted to dynamically specify the log path at runtime. Since the project ultimately needs to be packaged using jlink/jpackage, I added a module-info.class for SLF4J. However, an exception was still thrown at runtime. Eventually, I had to add the Java option --add-reads org.slf4j=org.apache.logging.log4j.slf4j.impl to start the application, this is quite troublesome... Can this issue be resolved in a future version?

I added the module-info file to the JAR using the following commands:

jdeps --ignore-missing-deps --generate-module-info . slf4j-api-1.7.36.jar
javac --patch-module org.slf4j=slf4j-api-1.7.36.jar org.slf4j/module-info.java
jar uf slf4j-api-1.7.36.jar -C org.slf4j module-info.class

stackTrace Caused by: java.lang.IllegalAccessError: class org.slf4j.LoggerFactory (in module org.slf4j) cannot access class org.slf4j.impl.StaticLoggerBinder (in module org.apache.logging.log4j.slf4j.impl) because module org.slf4j does not read module org.apache.logging.log4j.slf4j.impl at org.slf4j/org.slf4j.LoggerFactory.bind(LoggerFactory.java:150) at org.slf4j/org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:124) at org.slf4j/org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:417) at org.slf4j/org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:362) at org.slf4j/org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:388) at my_driver/com.tom.controller.MyDriverPaneController.(MyDriverPaneController.java:16) at my_driver/com.tom.FXMLVersionApp.start(FXMLVersionApp.java:23) at javafx.graphics@22/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:839) at javafx.graphics@22/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:483) at javafx.graphics@22/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:456) at java.base/java.security.AccessController.doPrivileged(AccessController.java:400) at javafx.graphics@22/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:455) at javafx.graphics@22/com.sun.glass.ui.InvokeLaterDispatcher$Future.run$$$capture(InvokeLaterDispatcher.java:95)

ceki commented 4 months ago

@xiz2008shy There is absolutely no need to access org.slf4j.impl.StaticLoggerBinder when using slf4j-api version 2.0.0 or later. This is not an slf4j issue.

The following links might shed some light onto the matter:

https://www.slf4j.org/codes.html#StaticLoggerBinder https://www.slf4j.org/faq.html#changesInVersion200

It looks like the problem stems from the fact that you are depending on org.apache.logging.log4j:log4j-slf4j-impl and not org.apache.logging.log4j:log4j-slf4j2-impl. Please note the difference between log4j-slf4j2-impl and log4j-slf4j-impl.

xiz2008shy commented 4 months ago

It turns out that the issue was indeed what you described, and after switching to log4j-slf4j2-impl, the problem was resolved. Thank you so much!