简体   繁体   中英

Logback in a Java modular application not working

I am just starting to master modular applications and I have a problem with the logback.

Before modularity was introduced into the project, Logback successfully worked with the same settings.

As soon as I start working with the LoggerContext and add the line requires ch.qos.logback.classic to the module-info.java , the application crashes.

Crash occurs in the line receiving the logger:

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

That being said, the code using the LoggerContext works fine. And as soon as I remove all mention of the LoggerContext, the application starts working normally.

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)

If you remove the line, then the application works fine.

My module-info file

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;
}

My pom dependency:

<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>

Method using 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;
}

My 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>

Sorry for my google english:)

It is a bug in logback 1.3.0-alpha5
Add

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

to the java VM argument as a workaround first, or try other version.
The actual problem occur inside 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;
        }
    }

Which return null when InstantiationException is thrown due to

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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