javalogbackgraalvmgraalvm-native-image

Java 17+ Native-Image Logback


How to configure maven to compile native image with logback ?
this is my environment :

<dependencies>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.graalvm.buildtools</groupId>
                <artifactId>native-maven-plugin</artifactId>
                <configuration>
                    <imageName>output</imageName>
                    <mainClass>ir.moke.ni.MainClass</mainClass>
                    <buildArgs>
                        <buildArgs>--initialize-at-build-time=ch.qos.logback,org.slf4j</buildArgs>
                        <buildArgs>-H:ReflectionConfigurationFiles=src/main/resources/META-INF/reflection-config.json</buildArgs>
                        <buildArg>-H:IncludeResources=logback.xml</buildArg>
                        <buildArg>-H:+UnlockExperimentalVMOptions</buildArg>
                        <buildArg>-H:Log=registerResource:5</buildArg>
                        <buildArg>--initialize-at-build-time=ch.qos.logback,org.slf4j</buildArg>
                    </buildArgs>
                </configuration>
            </plugin>
        </plugins>
    </build>

logback.xml :

<configuration>
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>
                %d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n
            </Pattern>
        </layout>
    </appender>

    <logger name="ir.moke" level="debug" additivity="false">
        <appender-ref ref="CONSOLE"/>
    </logger>

    <root level="error">
        <appender-ref ref="CONSOLE"/>
    </root>
</configuration>

reflection-config.json :

[
  {
    "name": "ch.qos.logback.classic.pattern.DateConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.classic.pattern.MessageConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.classic.pattern.ThrowableProxyConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.classic.pattern.NopThrowableInformationConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.classic.pattern.ContextNameConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.core.pattern.color.BoldYellowCompositeConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.classic.pattern.LoggerConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.core.pattern.ReplacingCompositeConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.core.pattern.color.BoldBlueCompositeConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.core.pattern.color.CyanCompositeConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.core.pattern.color.RedCompositeConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.core.pattern.color.WhiteCompositeConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.classic.pattern.PropertyConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.classic.pattern.ExtendedThrowableProxyConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.classic.pattern.RootCauseFirstThrowableProxyConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.classic.pattern.MethodOfCallerConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.classic.pattern.LevelConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.core.pattern.IdentityCompositeConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.core.pattern.color.BoldWhiteCompositeConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.classic.pattern.MarkerConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.core.pattern.color.BoldCyanCompositeConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.core.pattern.color.BoldMagentaCompositeConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.classic.pattern.RelativeTimeConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.core.pattern.color.MagentaCompositeConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.classic.pattern.ClassOfCallerConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.classic.pattern.LineOfCallerConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.classic.pattern.FileOfCallerConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.core.pattern.color.BoldGreenCompositeConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.classic.pattern.LocalSequenceNumberConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.core.pattern.color.YellowCompositeConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.classic.pattern.ExtendedThrowableProxyConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.classic.pattern.color.HighlightingCompositeConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.core.pattern.color.GrayCompositeConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.classic.pattern.MDCConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.classic.pattern.ClassOfCallerConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.core.pattern.color.BoldRedCompositeConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.core.pattern.color.GreenCompositeConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.core.pattern.color.BlackCompositeConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.classic.pattern.ThreadConverter",
    "allDeclaredConstructors": true
  },
  {
    "name": "ch.qos.logback.classic.pattern.LineSeparatorConverter",
    "allDeclaredConstructors": true
  }
]

my simple main class :

package ir.moke.ni;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MainClass {
    private static final Logger logger = LoggerFactory.getLogger(MainClass.class);

    static {
        System.out.println("Application started");
    }
    public static void main(String[] args) {
        logger.info("This is INFO log");
        logger.warn("This is WARN log");
        logger.debug("This is DEBUG log");
        logger.error("This is ERROR log");
        logger.trace("This is TRACE log");
    }
}

and this is directory tree :

logback-project/
├── pom.xml
└── src
    └── main
        ├── java
        │   └── ir
        │       └── moke
        │           └── ni
        │               └── MainClass.java
        └── resources
            ├── logback.xml
            └── META-INF
                └── reflection-config.json

project generate native image without any problem but log does not work !
How to fix this problem ?
Note : I try making a series of educational projects about native image, But I can not solve this case!! Tutorial Project Repository


UPDATE:
Interesting, I implement logback programmatically (without logback.xml) , this project does work without any problem .


Solution

  • after some tests , finally fixed .
    pom.xml should be configured like this :

    <buildArg>--initialize-at-build-time=ch.qos.logback,org.slf4j.LoggerFactory,org.slf4j.MDC</buildArg>