java - Java 模块化应用程序中的 Logback 不起作用

标签 java logback java-module java-platform-module-system

我刚刚开始掌握模块化应用程序,但我在 logback 方面遇到了问题。

在项目中引入模块化之前,Logback 成功地使用了相同的设置。

一旦我开始使用 LoggerContext 并将 requires ch.qos.logback.classic 行添加到 module-info.java 中,应用程序就会崩溃。

接收记录器的线路发生崩溃:

private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);

话虽这么说,使用 LoggerContext 的代码工作得很好。 一旦我删除所有提及 LoggerContext 的内容,应用程序就会开始正常工作。

Failed to instantiate [ch.qos.logback.classic.LoggerContext]
Reported exception:
java.lang.NullPointerException: Cannot invoke "ch.qos.logback.core.model.processor.ModelHandlerBase.isSupportedModelType(ch.qos.logback.core.model.Model)" because "handler" is null
    at ch.qos.logback.core/ch.qos.logback.core.model.processor.DefaultProcessor.traverse(DefaultProcessor.java:114)
    at ch.qos.logback.core/ch.qos.logback.core.model.processor.DefaultProcessor.traversalLoop(DefaultProcessor.java:39)
    at ch.qos.logback.core/ch.qos.logback.core.model.processor.DefaultProcessor.process(DefaultProcessor.java:54)
    at ch.qos.logback.core/ch.qos.logback.core.joran.GenericConfigurator.processModel(GenericConfigurator.java:178)
    at ch.qos.logback.core/ch.qos.logback.core.joran.GenericConfigurator.playEventsAndProcessModel(GenericConfigurator.java:165)
    at ch.qos.logback.core/ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:151)
    at ch.qos.logback.core/ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:115)
    at ch.qos.logback.core/ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:58)
    at ch.qos.logback.classic/ch.qos.logback.classic.util.ContextInitializer.configureByResource(ContextInitializer.java:82)
    at ch.qos.logback.classic/ch.qos.logback.classic.util.ContextInitializer.autoConfig(ContextInitializer.java:157)
    at ch.qos.logback.classic/ch.qos.logback.classic.spi.LogbackServiceProvider.initializeLoggerContext(LogbackServiceProvider.java:49)
    at ch.qos.logback.classic/ch.qos.logback.classic.spi.LogbackServiceProvider.initialize(LogbackServiceProvider.java:40)
    at org.slf4j/org.slf4j.LoggerFactory.bind(LoggerFactory.java:152)
    at org.slf4j/org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:139)
    at org.slf4j/org.slf4j.LoggerFactory.getProvider(LoggerFactory.java:418)
    at org.slf4j/org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:404)
    at org.slf4j/org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:353)
    at takil/com.company.Main.<init>(Main.java:23)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:64)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$8(LauncherImpl.java:802)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
    at java.base/java.lang.Thread.run(Thread.java:832)

如果删除该行,则应用程序可以正常工作。

我的模块信息文件

module elements {
    requires com.jfoenix;
    requires javafx.graphics;
    requires javafx.base;
    requires javafx.controls;
    requires ModbusLibrary;
    requires de.gsi.chartfx.dataset;
    requires de.gsi.chartfx.chart;
    requires ch.qos.logback.classic;
    requires org.slf4j;
    requires org.apache.commons.io;
    requires eu.hansolo.medusa;
    requires org.kordamp.iconli.core;
    requires org.kordamp.ikonli.javafx;
    requires org.kordamp.ikonli.fontawesome;

    exports com.company.elements;
    exports com.company.elements.messageTable;
    exports com.company.elements.gauge;
    exports com.company.elements.chart;
    exports com.company.elements.log;
    exports com.company.elements.materialDesign;
}

我的pom依赖:

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.3.0-alpha5</version>
    <exclusions>
        <exclusion>
            <artifactId>slf4j-api</artifactId>
            <groupId>org.slf4j</groupId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>2.0.0-alpha1</version>
</dependency>

使用 LoggerContext 的方法:

public static String getPathLog() {
    LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
    String folder = context.getProperty("LOG_PATH");
    String file = context.getProperty("FILE_NAME");
    return folder + "/" + file;
}

我的logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property scope="context" name="LOG_PATH" value="${user.home}/log"/>
    <property scope="context" name="FILE_NAME" value="last.log"/>
    <property scope="context" name="APS_MESSAGE_FILE_NAME" value="msg.log"/>
    <property scope="context" name="SEPARATOR" value=";"/>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- encoders are assigned the type
             ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
        <encoder>
            <!--  <pattern>%d{dd.MM.yyyy HH:mm:ss.SSS} [%thread] %-5level %logger{20} ebobo- %msg%n</pattern>-->
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - %msg%n</pattern>
        </encoder>
    </appender>
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_PATH}/${FILE_NAME}</file>
        <rollingPolicy
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- daily rollover -->
            <fileNamePattern>${LOG_PATH}/archived/%d{yyyy-MM-dd}.%i.zip</fileNamePattern>

            <maxFileSize>100MB</maxFileSize>
            <!-- Храним файлы логов 10 дней -->
            <maxHistory>360</maxHistory>
            <!-- Максимальный размер файлов лога 30 гигабайт -->
            <totalSizeCap>20GB</totalSizeCap>

        </rollingPolicy>
        <encoder>
            <pattern>%d{dd.MM.yyyy HH:mm:ss.SSS};%msg%n</pattern>
        </encoder>
    </appender>
    <appender name="MSG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_PATH}/${APS_MESSAGE_FILE_NAME}</file>
        <rollingPolicy
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- daily rollover -->
            <fileNamePattern>${LOG_PATH}/archivedMsg/%d{yyyy-MM-dd}.%i.zip</fileNamePattern>

            <maxFileSize>100MB</maxFileSize>
            <!-- Храним файлы логов 10 дней -->
            <maxHistory>360</maxHistory>
            <!-- Максимальный размер файлов лога 30 гигабайт -->
            <totalSizeCap>20GB</totalSizeCap>

        </rollingPolicy>
        <encoder>
            <pattern>%d{dd.MM.yyyy HH:mm:ss.SSS};%msg%n</pattern>
        </encoder>
    </appender>


    <logger name="com.company.elements.baseElement.Registerable" level="WARN">
        <appender-ref ref="console"/>
    </logger>
    <logger name="com.company.elements.log.LogWriter" level="INFO" additivity="false">
        <appender-ref ref="FILE"/>
    </logger>
    <logger name="com.company.elements.messageTable.MessageTable" level="INFO" additivity="false">
        <appender-ref ref="MSG"/>
    </logger>
    <root level="WARN">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

抱歉我的谷歌英语:)

最佳答案

这是logback 1.3.0-alpha5中的一个错误
添加

--add-exports ch.qos.logback.classic/ch.qos.logback.classic.model.processor=ch.qos.logback.core

首先使用 java VM 参数作为解决方法,或尝试其他版本。
实际问题发生在 DefaultProcessor#instantiateHandler

内部
    ModelHandlerBase instantiateHandler(Class<? extends ModelHandlerBase> handlerClass) {
        try {
            Constructor<? extends ModelHandlerBase> commonConstructor = getWithContextConstructor(handlerClass);
            if (commonConstructor != null) {
                return commonConstructor.newInstance(context);
            }
            Constructor<? extends ModelHandlerBase> constructorWithBDC = getWithContextAndBDCConstructor(handlerClass);
            if (constructorWithBDC != null) {
                return constructorWithBDC.newInstance(context, interpretationContext.getBeanDescriptionCache());
            }
            addError("Failed to find suitable constructor for class [" + handlerClass + "]");
            return null;
        } catch (InstantiationException | IllegalAccessException | SecurityException | IllegalArgumentException
                | InvocationTargetException e1) {
            addError("Failed to instantiate " + handlerClass);
            return null;
        }
    }

InstantiationException 抛出时返回 null

java.lang.IllegalAccessException: class ch.qos.logback.core.model.processor.DefaultProcessor (in module ch.qos.logback.core) cannot access class ch.qos.logback.classic.model.processor.ConfigurationModelHandler (in module ch.qos.logback.classic) because module ch.qos.logback.classic does not export ch.qos.logback.classic.model.processor to module ch.qos.logback.core

关于java - Java 模块化应用程序中的 Logback 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67092557/

相关文章:

java - 如何使用 Java 11 运行已编译的 Java 8 JavaFX 应用程序 jar?

java.lang.NoSuchMethodError 仅适用于树莓派

java - 在 Java 中实现 Bean 类时遇到问题 - ClassCastException

java - 如何停止登录jetty应用程序

java - 在 Logback 将 c3po 登录转发到文件

eclipse - SLF4J:无法加载类 "org.slf4j.impl.StaticLoggerBinder"。错误

java - 是否可以跨 Java 模块使用 SharedSecrets?

java - undefined reference 试图从 C++ 调用 Java

java - 在 Jenkins 中使用 Eclipse Compiler 获取编译器警告/错误

java - 循环模块依赖在 Java 9 中是否可行?