logging-log4j2 icon indicating copy to clipboard operation
logging-log4j2 copied to clipboard

Log4j2 starts again after LogManager.shutdown()

Open PavelTurk opened this issue 1 year ago • 6 comments

The problem occurs when Log4j2 is used with JUL + when it is necessary to use shutdownHook in an application. So, this is java code:

import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;

public class Mavenproject10 {

    static {
        try (InputStream is = Mavenproject10.class.getClassLoader().
                getResourceAsStream("logging.properties")) {
            LogManager.getLogManager().readConfiguration(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static final Logger logger = Logger.getLogger(Mavenproject10.class.getName());

    public static void main(String[] args) {
        org.apache.logging.log4j.jul.LogManager weNeedThisClass = null;
        logger.log(Level.SEVERE, "That is very bad");
        org.apache.logging.log4j.LogManager.shutdown();
        System.exit(0);
    }
}

This is logging.properties:

handlers= java.util.logging.ConsoleHandler
.level= ALL
java.util.logging.ConsoleHandler.level = ALL
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.SimpleFormatter.format=%4$s: %5$s [%1$tc]%n

This is log4j2.xml:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="trace" shutdownHook="disable">
    <Appenders>
	<Console name="Console" target="SYSTEM_OUT">
	    <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %highlight{[%level]}{FATAL=red blink, ERROR=red bold, WARN=yellow bold, INFO=magenta bold, DEBUG=green bold, TRACE=blue bold} %logger{36} - %msg%n" disableAnsi="false"/>
        </Console>
        <File name="File" fileName="/home/pavel/Temp/mavenproject10.log" immediateFlush="true" append="false">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight{[%level]}{FATAL=bright_red bold, ERROR=red bold, WARN=yellow bold, INFO=blue bold, DEBUG=green bold, TRACE=magenta bold} [%t] %logger{36} - %msg%n" disableAnsi="false"/>
        </File>
    </Appenders>

    <Loggers>
        <Root level="debug">
            <AppenderRef ref="File"/>
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

This is how we run program:

java -Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager -jar mavenproject10-1.0.0.jar

This is the output:

DEBUG StatusConsoleListener null null initializing configuration XmlConfiguration[location=jar:file:/home/pavel/Temp/TestBin/mavenproject10-1.0.0.jar!/log4j2.xml]
DEBUG StatusConsoleListener PluginManager 'Core' found 131 plugins
DEBUG StatusConsoleListener PluginManager 'Level' found 0 plugins
DEBUG StatusConsoleListener PluginManager 'Lookup' found 16 plugins
DEBUG StatusConsoleListener Building Plugin[name=layout, class=org.apache.logging.log4j.core.layout.PatternLayout].
TRACE StatusConsoleListener TypeConverterRegistry initializing.
DEBUG StatusConsoleListener PluginManager 'TypeConverter' found 26 plugins
DEBUG StatusConsoleListener PatternLayout$Builder(pattern="%d{HH:mm:ss.SSS} [%t] %highlight{[%level]}{FATAL=red blink, ERROR=red bold, WARN=yellow bold, INFO=magenta bold, DEBUG=green bold, TRACE=blue bold} %logger{36} - %msg%n", PatternSelector=null, Configuration(jar:file:/home/pavel/Temp/TestBin/mavenproject10-1.0.0.jar!/log4j2.xml), Replace=null, charset="null", alwaysWriteExceptions="null", disableAnsi="false", noConsoleNoAnsi="null", header="null", footer="null")
DEBUG StatusConsoleListener PluginManager 'Converter' found 45 plugins
DEBUG StatusConsoleListener Building Plugin[name=appender, class=org.apache.logging.log4j.core.appender.ConsoleAppender].
DEBUG StatusConsoleListener ConsoleAppender$Builder(target="SYSTEM_OUT", follow="null", direct="null", bufferedIo="null", bufferSize="null", immediateFlush="null", ignoreExceptions="null", PatternLayout(%d{HH:mm:ss.SSS} [%t] %highlight{[%level]}{FATAL=red blink, ERROR=red bold, WARN=yellow bold, INFO=magenta bold, DEBUG=green bold, TRACE=blue bold} %logger{36} - %msg%n), name="Console", Configuration(jar:file:/home/pavel/Temp/TestBin/mavenproject10-1.0.0.jar!/log4j2.xml), Filter=null, ={})
DEBUG StatusConsoleListener Starting OutputStreamManager SYSTEM_OUT.false.false
DEBUG StatusConsoleListener Building Plugin[name=layout, class=org.apache.logging.log4j.core.layout.PatternLayout].
DEBUG StatusConsoleListener PatternLayout$Builder(pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight{[%level]}{FATAL=bright_red bold, ERROR=red bold, WARN=yellow bold, INFO=blue bold, DEBUG=green bold, TRACE=magenta bold} [%t] %logger{36} - %msg%n", PatternSelector=null, Configuration(jar:file:/home/pavel/Temp/TestBin/mavenproject10-1.0.0.jar!/log4j2.xml), Replace=null, charset="null", alwaysWriteExceptions="null", disableAnsi="false", noConsoleNoAnsi="null", header="null", footer="null")
DEBUG StatusConsoleListener Building Plugin[name=appender, class=org.apache.logging.log4j.core.appender.FileAppender].
DEBUG StatusConsoleListener FileAppender$Builder(fileName="/home/pavel/Temp/mavenproject10.log", append="false", locking="null", advertise="null", advertiseUri="null", createOnDemand="null", filePermissions="null", fileOwner="null", fileGroup="null", bufferedIo="null", bufferSize="null", immediateFlush="true", ignoreExceptions="null", PatternLayout(%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight{[%level]}{FATAL=bright_red bold, ERROR=red bold, WARN=yellow bold, INFO=blue bold, DEBUG=green bold, TRACE=magenta bold} [%t] %logger{36} - %msg%n), name="File", Configuration(jar:file:/home/pavel/Temp/TestBin/mavenproject10-1.0.0.jar!/log4j2.xml), Filter=null, ={})
DEBUG StatusConsoleListener Starting FileManager /home/pavel/Temp/mavenproject10.log
DEBUG StatusConsoleListener Building Plugin[name=appenders, class=org.apache.logging.log4j.core.config.AppendersPlugin].
DEBUG StatusConsoleListener createAppenders(={Console, File})
DEBUG StatusConsoleListener Building Plugin[name=AppenderRef, class=org.apache.logging.log4j.core.config.AppenderRef].
DEBUG StatusConsoleListener createAppenderRef(ref="File", level="null", Filter=null)
DEBUG StatusConsoleListener Building Plugin[name=AppenderRef, class=org.apache.logging.log4j.core.config.AppenderRef].
DEBUG StatusConsoleListener createAppenderRef(ref="Console", level="null", Filter=null)
DEBUG StatusConsoleListener Building Plugin[name=root, class=org.apache.logging.log4j.core.config.LoggerConfig$RootLogger].
DEBUG StatusConsoleListener LoggerConfig$RootLogger$Builder(additivity="null", level="DEBUG", levelAndRefs="null", includeLocation="null", ={File, Console}, ={}, Configuration(jar:file:/home/pavel/Temp/TestBin/mavenproject10-1.0.0.jar!/log4j2.xml), Filter=null)
DEBUG StatusConsoleListener Building Plugin[name=loggers, class=org.apache.logging.log4j.core.config.LoggersPlugin].
DEBUG StatusConsoleListener createLoggers(={root})
DEBUG StatusConsoleListener Configuration XmlConfiguration[location=jar:file:/home/pavel/Temp/TestBin/mavenproject10-1.0.0.jar!/log4j2.xml] initialized
DEBUG StatusConsoleListener Starting configuration XmlConfiguration[location=jar:file:/home/pavel/Temp/TestBin/mavenproject10-1.0.0.jar!/log4j2.xml]
DEBUG StatusConsoleListener Started configuration XmlConfiguration[location=jar:file:/home/pavel/Temp/TestBin/mavenproject10-1.0.0.jar!/log4j2.xml] OK.
TRACE StatusConsoleListener Stopping org.apache.logging.log4j.core.config.DefaultConfiguration@cb51256...
TRACE StatusConsoleListener DefaultConfiguration notified 1 ReliabilityStrategies that config will be stopped.
TRACE StatusConsoleListener DefaultConfiguration stopping root LoggerConfig.
TRACE StatusConsoleListener DefaultConfiguration notifying ReliabilityStrategies that appenders will be stopped.
TRACE StatusConsoleListener DefaultConfiguration stopping remaining Appenders.
DEBUG StatusConsoleListener Shutting down OutputStreamManager SYSTEM_OUT.false.false-1
DEBUG StatusConsoleListener OutputStream closed
DEBUG StatusConsoleListener Shut down OutputStreamManager SYSTEM_OUT.false.false-1, all resources released: true
DEBUG StatusConsoleListener Appender DefaultConsole-1 stopped with status true
TRACE StatusConsoleListener DefaultConfiguration stopped 1 remaining Appenders.
TRACE StatusConsoleListener DefaultConfiguration cleaning Appenders from 1 LoggerConfigs.
DEBUG StatusConsoleListener Stopped org.apache.logging.log4j.core.config.DefaultConfiguration@cb51256 OK
TRACE StatusConsoleListener Call to LogManager.getLogger(javax.management)
TRACE StatusConsoleListener Call to LogManager.getLogger(javax.management.mbeanserver)
TRACE StatusConsoleListener Call to LogManager.getLogger(javax.management.mlet)
TRACE StatusConsoleListener Call to LogManager.getLogger(javax.management.monitor)
TRACE StatusConsoleListener Call to LogManager.getLogger(javax.management.timer)
TRACE StatusConsoleListener Call to LogManager.getLogger(javax.management.notification)
TRACE StatusConsoleListener Call to LogManager.getLogger(javax.management.relation)
TRACE StatusConsoleListener Call to LogManager.getLogger(javax.management.modelmbean)
TRACE StatusConsoleListener Call to LogManager.getLogger(javax.management.misc)
TRACE StatusConsoleListener Reregistering MBeans after reconfigure. Selector=org.apache.logging.log4j.core.selector.ClassLoaderContextSelector@1e683a3e
TRACE StatusConsoleListener Reregistering context (1/1): '4f2410ac' org.apache.logging.log4j.core.LoggerContext@7f3b84b8
TRACE StatusConsoleListener Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=4f2410ac'
TRACE StatusConsoleListener Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=4f2410ac,component=StatusLogger'
TRACE StatusConsoleListener Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=4f2410ac,component=ContextSelector'
TRACE StatusConsoleListener Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=4f2410ac,component=Loggers,name=*'
TRACE StatusConsoleListener Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=4f2410ac,component=Appenders,name=*'
TRACE StatusConsoleListener Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=4f2410ac,component=AsyncAppenders,name=*'
TRACE StatusConsoleListener Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=4f2410ac,component=AsyncLoggerRingBuffer'
TRACE StatusConsoleListener Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=4f2410ac,component=Loggers,name=*,subtype=RingBuffer'
DEBUG StatusConsoleListener Registering MBean org.apache.logging.log4j2:type=4f2410ac
DEBUG StatusConsoleListener Registering MBean org.apache.logging.log4j2:type=4f2410ac,component=StatusLogger
DEBUG StatusConsoleListener Registering MBean org.apache.logging.log4j2:type=4f2410ac,component=ContextSelector
DEBUG StatusConsoleListener Registering MBean org.apache.logging.log4j2:type=4f2410ac,component=Loggers,name=
DEBUG StatusConsoleListener Registering MBean org.apache.logging.log4j2:type=4f2410ac,component=Appenders,name=Console
DEBUG StatusConsoleListener Registering MBean org.apache.logging.log4j2:type=4f2410ac,component=Appenders,name=File
TRACE StatusConsoleListener Using default SystemClock for timestamps.
DEBUG StatusConsoleListener org.apache.logging.log4j.core.util.SystemClock supports precise timestamps.
TRACE StatusConsoleListener Using DummyNanoClock for nanosecond timestamps.
DEBUG StatusConsoleListener Reconfiguration complete for context[name=4f2410ac] at URI jar:file:/home/pavel/Temp/TestBin/mavenproject10-1.0.0.jar!/log4j2.xml (org.apache.logging.log4j.core.LoggerContext@7f3b84b8) with optional ClassLoader: null
DEBUG StatusConsoleListener LoggerContext[name=4f2410ac, org.apache.logging.log4j.core.LoggerContext@7f3b84b8] started OK.
02:22:40.245 [main] [ERROR] com.foo.mavenproject10.Mavenproject10 - That is very bad
DEBUG StatusConsoleListener Stopping LoggerContext[name=4f2410ac, org.apache.logging.log4j.core.LoggerContext@7f3b84b8]...
TRACE StatusConsoleListener Unregistering 1 MBeans: [org.apache.logging.log4j2:type=4f2410ac]
TRACE StatusConsoleListener Unregistering 1 MBeans: [org.apache.logging.log4j2:type=4f2410ac,component=StatusLogger]
TRACE StatusConsoleListener Unregistering 1 MBeans: [org.apache.logging.log4j2:type=4f2410ac,component=ContextSelector]
TRACE StatusConsoleListener Unregistering 1 MBeans: [org.apache.logging.log4j2:type=4f2410ac,component=Loggers,name=]
TRACE StatusConsoleListener Unregistering 2 MBeans: [org.apache.logging.log4j2:type=4f2410ac,component=Appenders,name=Console, org.apache.logging.log4j2:type=4f2410ac,component=Appenders,name=File]
TRACE StatusConsoleListener Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=4f2410ac,component=AsyncAppenders,name=*'
TRACE StatusConsoleListener Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=4f2410ac,component=AsyncLoggerRingBuffer'
TRACE StatusConsoleListener Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=4f2410ac,component=Loggers,name=*,subtype=RingBuffer'
TRACE StatusConsoleListener Stopping XmlConfiguration[location=jar:file:/home/pavel/Temp/TestBin/mavenproject10-1.0.0.jar!/log4j2.xml]...
TRACE StatusConsoleListener XmlConfiguration notified 2 ReliabilityStrategies that config will be stopped.
TRACE StatusConsoleListener XmlConfiguration stopping 1 LoggerConfigs.
TRACE StatusConsoleListener XmlConfiguration stopping root LoggerConfig.
TRACE StatusConsoleListener XmlConfiguration notifying ReliabilityStrategies that appenders will be stopped.
TRACE StatusConsoleListener XmlConfiguration stopping remaining Appenders.
DEBUG StatusConsoleListener Shutting down FileManager /home/pavel/Temp/mavenproject10.log
DEBUG StatusConsoleListener OutputStream closed
DEBUG StatusConsoleListener Shut down FileManager /home/pavel/Temp/mavenproject10.log, all resources released: true
DEBUG StatusConsoleListener Appender File stopped with status true
DEBUG StatusConsoleListener Shutting down OutputStreamManager SYSTEM_OUT.false.false
DEBUG StatusConsoleListener OutputStream closed
DEBUG StatusConsoleListener Shut down OutputStreamManager SYSTEM_OUT.false.false, all resources released: true
DEBUG StatusConsoleListener Appender Console stopped with status true
TRACE StatusConsoleListener XmlConfiguration stopped 2 remaining Appenders.
TRACE StatusConsoleListener XmlConfiguration cleaning Appenders from 2 LoggerConfigs.
DEBUG StatusConsoleListener Stopped XmlConfiguration[location=jar:file:/home/pavel/Temp/TestBin/mavenproject10-1.0.0.jar!/log4j2.xml] OK
DEBUG StatusConsoleListener Stopped LoggerContext[name=4f2410ac, org.apache.logging.log4j.core.LoggerContext@7f3b84b8] with status true
TRACE StatusConsoleListener Call to LogManager.getLogger(java.lang.Runtime)
DEBUG StatusConsoleListener PluginManager 'Lookup' found 16 plugins
DEBUG StatusConsoleListener PluginManager 'Converter' found 45 plugins
DEBUG StatusConsoleListener Starting OutputStreamManager SYSTEM_OUT.false.false-2
DEBUG StatusConsoleListener Starting LoggerContext[name=4f2410ac, org.apache.logging.log4j.core.LoggerContext@d5b810e]...
DEBUG StatusConsoleListener Reconfiguration started for context[name=4f2410ac] at URI null (org.apache.logging.log4j.core.LoggerContext@d5b810e) with optional ClassLoader: null
DEBUG StatusConsoleListener Using configurationFactory org.apache.logging.log4j.core.config.ConfigurationFactory$Factory@43dac38f
TRACE StatusConsoleListener Trying to find [log4j2-test4f2410ac.properties] using context class loader jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac.
TRACE StatusConsoleListener Trying to find [log4j2-test4f2410ac.properties] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2-test4f2410ac.properties] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2-test4f2410ac.properties] using ClassLoader.getSystemResource().
TRACE StatusConsoleListener Trying to find [log4j2-test4f2410ac.yml] using context class loader jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac.
TRACE StatusConsoleListener Trying to find [log4j2-test4f2410ac.yml] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2-test4f2410ac.yml] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2-test4f2410ac.yml] using ClassLoader.getSystemResource().
TRACE StatusConsoleListener Trying to find [log4j2-test4f2410ac.yaml] using context class loader jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac.
TRACE StatusConsoleListener Trying to find [log4j2-test4f2410ac.yaml] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2-test4f2410ac.yaml] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2-test4f2410ac.yaml] using ClassLoader.getSystemResource().
TRACE StatusConsoleListener Trying to find [log4j2-test4f2410ac.json] using context class loader jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac.
TRACE StatusConsoleListener Trying to find [log4j2-test4f2410ac.json] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2-test4f2410ac.json] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2-test4f2410ac.json] using ClassLoader.getSystemResource().
TRACE StatusConsoleListener Trying to find [log4j2-test4f2410ac.jsn] using context class loader jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac.
TRACE StatusConsoleListener Trying to find [log4j2-test4f2410ac.jsn] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2-test4f2410ac.jsn] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2-test4f2410ac.jsn] using ClassLoader.getSystemResource().
TRACE StatusConsoleListener Trying to find [log4j2-test4f2410ac.xml] using context class loader jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac.
TRACE StatusConsoleListener Trying to find [log4j2-test4f2410ac.xml] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2-test4f2410ac.xml] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2-test4f2410ac.xml] using ClassLoader.getSystemResource().
TRACE StatusConsoleListener Trying to find [log4j2-test.properties] using context class loader jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac.
TRACE StatusConsoleListener Trying to find [log4j2-test.properties] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2-test.properties] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2-test.properties] using ClassLoader.getSystemResource().
TRACE StatusConsoleListener Trying to find [log4j2-test.yml] using context class loader jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac.
TRACE StatusConsoleListener Trying to find [log4j2-test.yml] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2-test.yml] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2-test.yml] using ClassLoader.getSystemResource().
TRACE StatusConsoleListener Trying to find [log4j2-test.yaml] using context class loader jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac.
TRACE StatusConsoleListener Trying to find [log4j2-test.yaml] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2-test.yaml] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2-test.yaml] using ClassLoader.getSystemResource().
TRACE StatusConsoleListener Trying to find [log4j2-test.json] using context class loader jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac.
TRACE StatusConsoleListener Trying to find [log4j2-test.json] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2-test.json] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2-test.json] using ClassLoader.getSystemResource().
TRACE StatusConsoleListener Trying to find [log4j2-test.jsn] using context class loader jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac.
TRACE StatusConsoleListener Trying to find [log4j2-test.jsn] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2-test.jsn] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2-test.jsn] using ClassLoader.getSystemResource().
TRACE StatusConsoleListener Trying to find [log4j2-test.xml] using context class loader jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac.
TRACE StatusConsoleListener Trying to find [log4j2-test.xml] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2-test.xml] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2-test.xml] using ClassLoader.getSystemResource().
TRACE StatusConsoleListener Trying to find [log4j24f2410ac.properties] using context class loader jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac.
TRACE StatusConsoleListener Trying to find [log4j24f2410ac.properties] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j24f2410ac.properties] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j24f2410ac.properties] using ClassLoader.getSystemResource().
TRACE StatusConsoleListener Trying to find [log4j24f2410ac.yml] using context class loader jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac.
TRACE StatusConsoleListener Trying to find [log4j24f2410ac.yml] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j24f2410ac.yml] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j24f2410ac.yml] using ClassLoader.getSystemResource().
TRACE StatusConsoleListener Trying to find [log4j24f2410ac.yaml] using context class loader jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac.
TRACE StatusConsoleListener Trying to find [log4j24f2410ac.yaml] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j24f2410ac.yaml] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j24f2410ac.yaml] using ClassLoader.getSystemResource().
TRACE StatusConsoleListener Trying to find [log4j24f2410ac.json] using context class loader jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac.
TRACE StatusConsoleListener Trying to find [log4j24f2410ac.json] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j24f2410ac.json] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j24f2410ac.json] using ClassLoader.getSystemResource().
TRACE StatusConsoleListener Trying to find [log4j24f2410ac.jsn] using context class loader jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac.
TRACE StatusConsoleListener Trying to find [log4j24f2410ac.jsn] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j24f2410ac.jsn] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j24f2410ac.jsn] using ClassLoader.getSystemResource().
TRACE StatusConsoleListener Trying to find [log4j24f2410ac.xml] using context class loader jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac.
TRACE StatusConsoleListener Trying to find [log4j24f2410ac.xml] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j24f2410ac.xml] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j24f2410ac.xml] using ClassLoader.getSystemResource().
TRACE StatusConsoleListener Trying to find [log4j2.properties] using context class loader jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac.
TRACE StatusConsoleListener Trying to find [log4j2.properties] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2.properties] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2.properties] using ClassLoader.getSystemResource().
TRACE StatusConsoleListener Trying to find [log4j2.yml] using context class loader jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac.
TRACE StatusConsoleListener Trying to find [log4j2.yml] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2.yml] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2.yml] using ClassLoader.getSystemResource().
TRACE StatusConsoleListener Trying to find [log4j2.yaml] using context class loader jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac.
TRACE StatusConsoleListener Trying to find [log4j2.yaml] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2.yaml] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2.yaml] using ClassLoader.getSystemResource().
TRACE StatusConsoleListener Trying to find [log4j2.json] using context class loader jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac.
TRACE StatusConsoleListener Trying to find [log4j2.json] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2.json] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2.json] using ClassLoader.getSystemResource().
TRACE StatusConsoleListener Trying to find [log4j2.jsn] using context class loader jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac.
TRACE StatusConsoleListener Trying to find [log4j2.jsn] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2.jsn] using jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac class loader.
TRACE StatusConsoleListener Trying to find [log4j2.jsn] using ClassLoader.getSystemResource().
TRACE StatusConsoleListener Trying to find [log4j2.xml] using context class loader jdk.internal.loader.ClassLoaders$AppClassLoader@4f2410ac.
DEBUG StatusConsoleListener uri does not represent a local file: jar:file:/home/pavel/Temp/TestBin/mavenproject10-1.0.0.jar!/log4j2.xml
DEBUG StatusConsoleListener PluginManager 'Lookup' found 16 plugins
DEBUG StatusConsoleListener Closing JarURLInputStream sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream@54bff557
DEBUG StatusConsoleListener null null initializing configuration XmlConfiguration[location=jar:file:/home/pavel/Temp/TestBin/mavenproject10-1.0.0.jar!/log4j2.xml]
DEBUG StatusConsoleListener PluginManager 'Core' found 131 plugins
DEBUG StatusConsoleListener PluginManager 'Level' found 0 plugins
DEBUG StatusConsoleListener PluginManager 'Lookup' found 16 plugins
DEBUG StatusConsoleListener Building Plugin[name=layout, class=org.apache.logging.log4j.core.layout.PatternLayout].
DEBUG StatusConsoleListener PatternLayout$Builder(pattern="%d{HH:mm:ss.SSS} [%t] %highlight{[%level]}{FATAL=red blink, ERROR=red bold, WARN=yellow bold, INFO=magenta bold, DEBUG=green bold, TRACE=blue bold} %logger{36} - %msg%n", PatternSelector=null, Configuration(jar:file:/home/pavel/Temp/TestBin/mavenproject10-1.0.0.jar!/log4j2.xml), Replace=null, charset="null", alwaysWriteExceptions="null", disableAnsi="false", noConsoleNoAnsi="null", header="null", footer="null")
DEBUG StatusConsoleListener PluginManager 'Converter' found 45 plugins
DEBUG StatusConsoleListener Building Plugin[name=appender, class=org.apache.logging.log4j.core.appender.ConsoleAppender].
DEBUG StatusConsoleListener ConsoleAppender$Builder(target="SYSTEM_OUT", follow="null", direct="null", bufferedIo="null", bufferSize="null", immediateFlush="null", ignoreExceptions="null", PatternLayout(%d{HH:mm:ss.SSS} [%t] %highlight{[%level]}{FATAL=red blink, ERROR=red bold, WARN=yellow bold, INFO=magenta bold, DEBUG=green bold, TRACE=blue bold} %logger{36} - %msg%n), name="Console", Configuration(jar:file:/home/pavel/Temp/TestBin/mavenproject10-1.0.0.jar!/log4j2.xml), Filter=null, ={})
DEBUG StatusConsoleListener Starting OutputStreamManager SYSTEM_OUT.false.false
DEBUG StatusConsoleListener Building Plugin[name=layout, class=org.apache.logging.log4j.core.layout.PatternLayout].
DEBUG StatusConsoleListener PatternLayout$Builder(pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight{[%level]}{FATAL=bright_red bold, ERROR=red bold, WARN=yellow bold, INFO=blue bold, DEBUG=green bold, TRACE=magenta bold} [%t] %logger{36} - %msg%n", PatternSelector=null, Configuration(jar:file:/home/pavel/Temp/TestBin/mavenproject10-1.0.0.jar!/log4j2.xml), Replace=null, charset="null", alwaysWriteExceptions="null", disableAnsi="false", noConsoleNoAnsi="null", header="null", footer="null")
DEBUG StatusConsoleListener Building Plugin[name=appender, class=org.apache.logging.log4j.core.appender.FileAppender].
DEBUG StatusConsoleListener FileAppender$Builder(fileName="/home/pavel/Temp/mavenproject10.log", append="false", locking="null", advertise="null", advertiseUri="null", createOnDemand="null", filePermissions="null", fileOwner="null", fileGroup="null", bufferedIo="null", bufferSize="null", immediateFlush="true", ignoreExceptions="null", PatternLayout(%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight{[%level]}{FATAL=bright_red bold, ERROR=red bold, WARN=yellow bold, INFO=blue bold, DEBUG=green bold, TRACE=magenta bold} [%t] %logger{36} - %msg%n), name="File", Configuration(jar:file:/home/pavel/Temp/TestBin/mavenproject10-1.0.0.jar!/log4j2.xml), Filter=null, ={})
DEBUG StatusConsoleListener Starting FileManager /home/pavel/Temp/mavenproject10.log
DEBUG StatusConsoleListener Building Plugin[name=appenders, class=org.apache.logging.log4j.core.config.AppendersPlugin].
DEBUG StatusConsoleListener createAppenders(={Console, File})
DEBUG StatusConsoleListener Building Plugin[name=AppenderRef, class=org.apache.logging.log4j.core.config.AppenderRef].
DEBUG StatusConsoleListener createAppenderRef(ref="File", level="null", Filter=null)
DEBUG StatusConsoleListener Building Plugin[name=AppenderRef, class=org.apache.logging.log4j.core.config.AppenderRef].
DEBUG StatusConsoleListener createAppenderRef(ref="Console", level="null", Filter=null)
DEBUG StatusConsoleListener Building Plugin[name=root, class=org.apache.logging.log4j.core.config.LoggerConfig$RootLogger].
DEBUG StatusConsoleListener LoggerConfig$RootLogger$Builder(additivity="null", level="DEBUG", levelAndRefs="null", includeLocation="null", ={File, Console}, ={}, Configuration(jar:file:/home/pavel/Temp/TestBin/mavenproject10-1.0.0.jar!/log4j2.xml), Filter=null)
DEBUG StatusConsoleListener Building Plugin[name=loggers, class=org.apache.logging.log4j.core.config.LoggersPlugin].
DEBUG StatusConsoleListener createLoggers(={root})
DEBUG StatusConsoleListener Configuration XmlConfiguration[location=jar:file:/home/pavel/Temp/TestBin/mavenproject10-1.0.0.jar!/log4j2.xml] initialized
DEBUG StatusConsoleListener Starting configuration XmlConfiguration[location=jar:file:/home/pavel/Temp/TestBin/mavenproject10-1.0.0.jar!/log4j2.xml]
DEBUG StatusConsoleListener Started configuration XmlConfiguration[location=jar:file:/home/pavel/Temp/TestBin/mavenproject10-1.0.0.jar!/log4j2.xml] OK.
TRACE StatusConsoleListener Stopping org.apache.logging.log4j.core.config.DefaultConfiguration@2ed2d9cb...
TRACE StatusConsoleListener DefaultConfiguration notified 1 ReliabilityStrategies that config will be stopped.
TRACE StatusConsoleListener DefaultConfiguration stopping root LoggerConfig.
TRACE StatusConsoleListener DefaultConfiguration notifying ReliabilityStrategies that appenders will be stopped.
TRACE StatusConsoleListener DefaultConfiguration stopping remaining Appenders.
DEBUG StatusConsoleListener Shutting down OutputStreamManager SYSTEM_OUT.false.false-2
DEBUG StatusConsoleListener OutputStream closed
DEBUG StatusConsoleListener Shut down OutputStreamManager SYSTEM_OUT.false.false-2, all resources released: true
DEBUG StatusConsoleListener Appender DefaultConsole-2 stopped with status true
TRACE StatusConsoleListener DefaultConfiguration stopped 1 remaining Appenders.
TRACE StatusConsoleListener DefaultConfiguration cleaning Appenders from 1 LoggerConfigs.
DEBUG StatusConsoleListener Stopped org.apache.logging.log4j.core.config.DefaultConfiguration@2ed2d9cb OK
TRACE StatusConsoleListener Reregistering MBeans after reconfigure. Selector=org.apache.logging.log4j.core.selector.ClassLoaderContextSelector@1e683a3e
TRACE StatusConsoleListener Reregistering context (1/1): '4f2410ac' org.apache.logging.log4j.core.LoggerContext@d5b810e
TRACE StatusConsoleListener Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=4f2410ac'
TRACE StatusConsoleListener Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=4f2410ac,component=StatusLogger'
TRACE StatusConsoleListener Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=4f2410ac,component=ContextSelector'
TRACE StatusConsoleListener Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=4f2410ac,component=Loggers,name=*'
TRACE StatusConsoleListener Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=4f2410ac,component=Appenders,name=*'
TRACE StatusConsoleListener Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=4f2410ac,component=AsyncAppenders,name=*'
TRACE StatusConsoleListener Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=4f2410ac,component=AsyncLoggerRingBuffer'
TRACE StatusConsoleListener Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=4f2410ac,component=Loggers,name=*,subtype=RingBuffer'
DEBUG StatusConsoleListener Registering MBean org.apache.logging.log4j2:type=4f2410ac
DEBUG StatusConsoleListener Registering MBean org.apache.logging.log4j2:type=4f2410ac,component=StatusLogger
DEBUG StatusConsoleListener Registering MBean org.apache.logging.log4j2:type=4f2410ac,component=ContextSelector
DEBUG StatusConsoleListener Registering MBean org.apache.logging.log4j2:type=4f2410ac,component=Loggers,name=
DEBUG StatusConsoleListener Registering MBean org.apache.logging.log4j2:type=4f2410ac,component=Appenders,name=Console
DEBUG StatusConsoleListener Registering MBean org.apache.logging.log4j2:type=4f2410ac,component=Appenders,name=File
TRACE StatusConsoleListener Using DummyNanoClock for nanosecond timestamps.
DEBUG StatusConsoleListener Reconfiguration complete for context[name=4f2410ac] at URI jar:file:/home/pavel/Temp/TestBin/mavenproject10-1.0.0.jar!/log4j2.xml (org.apache.logging.log4j.core.LoggerContext@d5b810e) with optional ClassLoader: null
DEBUG StatusConsoleListener LoggerContext[name=4f2410ac, org.apache.logging.log4j.core.LoggerContext@d5b810e] started OK.
FINE: Runtime.exit() called with status: 0 [Mon Nov 20 02:22:40 EET 2023]

Please, note the following piece:

DEBUG StatusConsoleListener Shutting down FileManager /home/pavel/Temp/mavenproject10.log
DEBUG StatusConsoleListener OutputStream closed
DEBUG StatusConsoleListener Shut down FileManager /home/pavel/Temp/mavenproject10.log, all resources released: true
DEBUG StatusConsoleListener Appender File stopped with status true
DEBUG StatusConsoleListener Shutting down OutputStreamManager SYSTEM_OUT.false.false
DEBUG StatusConsoleListener OutputStream closed
DEBUG StatusConsoleListener Shut down OutputStreamManager SYSTEM_OUT.false.false, all resources released: true
DEBUG StatusConsoleListener Appender Console stopped with status true
TRACE StatusConsoleListener XmlConfiguration stopped 2 remaining Appenders.
TRACE StatusConsoleListener XmlConfiguration cleaning Appenders from 2 LoggerConfigs.
DEBUG StatusConsoleListener Stopped XmlConfiguration[location=jar:file:/home/pavel/Temp/TestBin/mavenproject10-1.0.0.jar!/log4j2.xml] OK
DEBUG StatusConsoleListener Stopped LoggerContext[name=4f2410ac, org.apache.logging.log4j.core.LoggerContext@7f3b84b8] with status true
TRACE StatusConsoleListener Call to LogManager.getLogger(java.lang.Runtime)
DEBUG StatusConsoleListener PluginManager 'Lookup' found 16 plugins
DEBUG StatusConsoleListener PluginManager 'Converter' found 45 plugins
DEBUG StatusConsoleListener Starting OutputStreamManager SYSTEM_OUT.false.false-2
DEBUG StatusConsoleListener Starting LoggerContext[name=4f2410ac, org.apache.logging.log4j.core.LoggerContext@d5b810e]...
DEBUG StatusConsoleListener Reconfiguration started for context[name=4f2410ac] at URI null (org.apache.logging.log4j.core.LoggerContext@d5b810e) with optional ClassLoader: null
DEBUG StatusConsoleListener Using configurationFactory org.apache.logging.log4j.core.config.ConfigurationFactory$Factory@43dac38f

As you see log4j2 closes log file but later it starts it again. In the result log file length is 0 - it is empty. The reason of the problem shows this stack:

LoggerContext.reconfigure:688	
LoggerContext.reconfigure:711	
LoggerContext.start:253	
Log4jContextFactory.getContext:155	
Log4jContextFactory.getContext:47	
LogManager.getContext:196	
AbstractLoggerAdapter.getContext:137	
Hidden Source Calls	
AbstractLoggerAdapter.getLogger:47	
Hidden Source Calls	
LogManager.getLogger:95	
LogManager.demandSystemLogger:574	
LogManager$LoggingProviderAccess.demandLoggerFor:2727	
LoggingProviderImpl.demandJULLoggerFor:412	
LoggingProviderImpl.demandLoggerFor:438	
DefaultLoggerFinder.getLogger:159	
LazyLoggers.getLoggerFromFinder:391	
LazyLoggers.getLazyLogger:446	
LazyLoggers.getLogger:416	
System.getLogger:1822	
Shutdown.logRuntimeExit:177	
Shutdown.exit:160	
Runtime.exit:188	
System.exit:1916

PavelTurk avatar Nov 27 '23 08:11 PavelTurk

@PavelTurk,

The main problem in your code is that you are calling LogManager#shutdown in your main method, instead of using a shutdown hook. Somewhere between Java 17 and Java 21 (cf. source code) a Shutdown#logRuntimeExit method was introduced that runs after your explicit LogManager#shutdown call, but before any proper shutdown hooks.

Therefore you need:

  • remove the LogManager#shutdown call and use a proper shutdown hook. Log4j Core does automatically install one, unless it detects a servlet environment. In the latter case you can force a shutdown hook by setting the property log4j2.shutdownHookEnabled to true (cf. documentation). The easiest way to do it is through a log4j2.component.properties file.

Remark: Instead of using a logging.properties file to configure System.Logger, consider using log4j-jpl. In order to do so just add:

<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-jpl</artifactId>
  <scope>runtime</scope>
</dependency>

and enjoy a full Log4j Core experience.

ppkarwasz avatar Nov 27 '23 10:11 ppkarwasz

@ppkarwasz , thank you very much for your answer.

What you suggest is not a solution for me. I need to use my own shutdownHook in my application. This shutdownHook must do some logic to close application correctly AND only in the very end I can shutdown log4j2.

So, I need to set log4j2.shutdownHookEnabled to false because otherwise log4j2 can easily stop BEFORE my shutdownHook completes. From javadoc:

A shutdown hook is simply an initialized but unstarted thread. When the virtual machine begins its shutdown sequence it will start all registered shutdown hooks in some unspecified order and let them run concurrently. When all the hooks have finished it will then halt. Note that daemon threads will continue to run during the shutdown sequence, as will non-daemon threads if shutdown was initiated by invoking the exit method.

If I understand everything correctly we have two types of application that uses log4j2. The first ones doesn't have own shutdownHooks the second ones have. So, for the second type applications log4j2.shutdownHookEnabled must be set to false. And log4j2 must support this type of applications.

I still think that this is a bug in log4j2. It doesn't matter what java version is used - there is always possibility that JRE will log some messages after LogManager.shutdown(), so log4j2 should support such cases.

PavelTurk avatar Nov 27 '23 10:11 PavelTurk

@PavelTurk,

What you suggest is not a solution for me. I need to use my own shutdownHook in my application. This shutdownHook must do some logic to close application correctly AND only in the very end I can shutdown log4j2.

What about something like this:

    public static void main(String[] args) {
        logger.info("Hello JUL world!");
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                // Do some shutdown stuff
                // ...
                // Stop the logging backend.
                LogManager.shutdown();
            }
        });
        System.exit(0);
    }

I still think that this is a bug in log4j2. It doesn't matter what java version is used - there is always possibility that JRE will log some messages after LogManager.shutdown(), so log4j2 should support such cases.

This issue is very similar to #1782: as explained in the Javadoc you cited, there is no way to influence the order of execution of JVM shutdown hooks. We can only document this fact and explain that LogManager#shutdown() is a method for advanced users and should:

  1. only be called in a shutdown hook or equivalent (e.g. ServletContextListener for web applications),
  2. the other shutdown hooks should not use logging (e.g. they can use System.err) or the system must guarantee that the shutdown hook is executed last.

AFAIK the only way for Log4j JUL to detect that the application is shutting down is to use Runtime#addShutdownHook, but this works only after Shutdown#runHooks has been invoked. The Shutdown#logRuntimeExit method that causes the reinitialisation problem in your application happens before the Shutdown#runHooks call.

ppkarwasz avatar Nov 27 '23 11:11 ppkarwasz

@ppkarwasz ,

I totally agree with your last post. You suggest to use LogManager.shutdown(); at the end of my own shutdown hook - this is exactly what I am doing now. You say:

AFAIK the only way for Log4j JUL to detect that the application is shutting down is to use Runtime#addShutdownHook, but this works only after Shutdown#runHooks has been invoked. The Shutdown#logRuntimeExit method that causes the reinitialisation problem in your application happens before the Shutdown#runHooks call.

I also agree with that.

There are two reasons why I opened this issue:

  1. Please, consider this code XXX.shutdown(). Will you expect that XXX will work after executing the code? I won't. That's why I spent several hours trying to understand why my log files are empty. Imagine, that XXX is your computer. What will you say if it works after you shutdown it?
  2. As I understand (I may be wrong here!) JRE specs doesn't say where JRE writes last log message. If I am right then Log4j2 should support all possible cases. For example, if in Java 22+ they will add log message AFTER Shutdown#runHooks then all log files of all log4j2 users will be empty. That's it.

PavelTurk avatar Nov 27 '23 12:11 PavelTurk

There are two reasons why I opened this issue:

1. Please, consider this code `XXX.shutdown()`. Will you expect that `XXX` will work after executing the code? I won't. That's why I spent several hours trying to understand why my log files are empty. Imagine, that XXX is your computer. What will you say if it works after you shutdown it?

I see your point, thanks for explaining it. IMHO the main problem is a misunderstanding of what LogManager#shutdown does. The Javadoc says:

Shutdown using the LoggerContext appropriate for the caller of this method.

which does not say much. ;-) What in reality happens is that only the logger context appropriate for the caller shuts down and is unregistered. This does not prevent the LoggerContextFactory from creating new logger contexts if LogManager.getLogger() is called again, which happens in your case.

2. As I understand (I may be wrong here!) JRE specs doesn't say where JRE writes last log message. If I am right then Log4j2 should support all possible cases. For example, if in Java 22+ they will add log message AFTER  `Shutdown#runHooks` then all log files of all `log4j2` users will be empty. That's it.

Your logs are empty, because you specified append="false" in your configuration file. This is not the default value and is not the value I'd recommend: on most systems opening files in append mode allows multiple applications to write to the same file at the same time; for reasonable sizes of the messages the write calls are even atomic and log lines are not broken in half.

Although there is no guarantee, I find it very unlikely future JREs will log anything after the shutdown hooks started: logging must also stop at a certain point.

ppkarwasz avatar Nov 27 '23 14:11 ppkarwasz

@ppkarwasz ,

Thank you for detailed explanation. I have nothing to add but I am still sure that self restarting after shutdown() is a serious flaw which definitely should be fixed. So, this is up to you and other Log4j2 developers.

PavelTurk avatar Nov 27 '23 15:11 PavelTurk