Log4j2 Unable to log shutdown because JVM shutdown

I am trying to use log4j2 in a tomcat based web application, so I added the log4j web module along with other important jars. However, when stopping this web application, I get the following exception.

FATAL Unable to register shutdown hook because JVM is shutting down

      

Why am I getting this error and what can I do to prevent this error?

Thank!

+3


source to share


2 answers


As explained in Puria's answer, you are probably trying to use Log4j2 when your application is already halting without properly shutting down. Since you are talking about Tomcat web application, I will assume you are using Servlets. (If you don't, see the second part below). Then you have to declare this in your ContextListener:

public class ContextListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent evt) {
        String appenderName = evt.getServletContext().getInitParameter("log4jContextName");
        File file = new File(evt.getServletContext().getInitParameter("log4jConfiguration"));
        if(!file.exists()){
            logger = LogManager.getRootLogger();
        } else{
            logger = LogManager.getLogger(appenderName);
        }
    }
}

@Override
public void contextDestroyed(ServletContextEvent evt) {
    // You don't really need to do anything here, about the logger.
    // The log4j2 JAR will handle it properly.
}

      

As usual in web applications, the Log4J2 configuration file must be referenced in the web.xml file like:

<?xml version="1.0" encoding="UTF-8"?>
<web-app ... >
    <context-param>
        <param-name>log4jContextName</param-name>
        <param-value>myApplication</param-value>
    </context-param>

    <context-param>
        <param-name>log4jConfiguration</param-name>
        <param-value>/the/path/to/your/log4j.properties.file</param-value>
    </context-param>
</web-app>

      


If you are using a regular application instead, you need to explicitly add your disconnect hook:

public static void main( String[] args ) {

    ...

    File file = new File(logFileName);
    if(!file.exists()){
        logger = LogManager.getRootLogger();
    } else {
        System.setProperty("log4j.configurationFile", file.toURI().toURL().toString());
        logger = LogManager.getLogger("yourProgramName");
    }

    Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() {
            logger.info("Shutting down - closing application");
            // Shut down everything (e.g. threads) that you need to.

            // then shut down log4j
            if( LogManager.getContext() instanceof LoggerContext ) {
                logger.debug("Shutting down log4j2");
                Configurator.shutdown((LoggerContext)LogManager.getContext());
            } else
                logger.warn("Unable to shutdown log4j2");

            // logger not usable anymore
            System.out.println("Done.");
        }
    });
}

      

The shutdown key will be called when your application is terminated (i.e. when you call System.exit(0)

.



You also need to add this to your Log4J2 config file:

XML version:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration shutdownHook="disable">
...
</Configuration>

      

Json version:

{"configuration":
    {
        "shutdownHook":"disable",
        ....
    }
}

      

This will tell Log4j2 that you are handling the Logger shutdown yourself.

(Since in a normal application you don't have a web.xml file, you must restore the config file somehow).

+6


source


If you get this error while stopping the web application, it means that your hook was not registered at the correct time. By definition, it had to be registered before it could be called during shutdown.



+1


source







All Articles