2

I have a Spring MVC Web App (4.0) with log4j2. This webapp uses no web.xml and takes care of configuration through Java Config. Log4j2 configuration needs to take place in an external config file, not on the classpath.

In a previous incarnation with web.xml we had

<context-param>
    <param-name>log4jConfiguration</param-name>
    <param-value>file:///path/to/log4j2.xml</param-value>
</context-param> 

and this worked.

In the new web.xml-less world, I tried this:

public class WebappInitializer 
extends AbstractAnnotationConfigDispatcherServletInitializer 
{

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        System.out.println("WebappInitializer.onStartup()");
        servletContext.setAttribute("log4jConfiguration", "file:///path/to/log4j2.xml");

This does not work. It seems to happen too late and in any event doesn't work. The logs show:

ERROR StatusLogger No Log4j context configuration provided. This is very unusual.
WebappInitializer.onStartup()

and no log4j logging occurs.

What is the right way to replace this context-param declaration with web.xml in a web.xml-less Spring MVC app?

UPDATE:

I can make this problem go away by adding the following web.xml:

<?xml version="1.0"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
          http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
          version="3.0">

    <context-param>
        <param-name>log4jConfiguration</param-name>
        <param-value>file:///path/to/log4j2.xml</param-value>
    </context-param> 

</web-app>

Surely, there must be a better way!

Steve Cohen
  • 4,679
  • 9
  • 51
  • 89

3 Answers3

4

I believe you can reconfigure log4j2 to a new config file during runtime like this.

     LoggerContext context = (LoggerContext)LogManager.getContext(false);
     context.setConfigLocation(URI.create("path to file"));
     context.reconfigure();

Could just add this to your onStartup.

alan7678
  • 2,223
  • 17
  • 29
1

Probably this is a little too late, but you can do the following to set the log4j2 configuration to an external path:

public class ApplicationInitializer implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext servletContext)
        throws ServletException {
        servletContext.setInitParameter(Log4jWebSupport.LOG4J_CONFIG_LOCATION, "file:///path/to/log4j2.xml");
Andy Ng
  • 41
  • 5
0

I haven’t tested it but the following should be worth a try; replace your servletContext.setAttribute(…) call in the onStartup(…) method with the following Log4jConfigurer call:

Log4jConfigurer.initLogging("file:///path/to/log4j2.xml")

This is basically what happens under the hood when you use log4jConfigLocation in the <context-param> of a web.xml file (via Log4jWebConfigurer, see code).

I’m only wondering if this will also work with log4j2, although I wouldn’t expect the <context-param> way to work with it either. Did you also use log4j2 when you were still using the web.xml file?

Chriki
  • 15,638
  • 3
  • 51
  • 66
  • Since reverting to my workaround of using the minimalist web.xml shown above, another problem has also gone away - when there was no web.xml, every other time or so hot-deploying a new version of the app resulted in crashing Tomcat with OutOfMemoryError. Putting in the minimalist web.xml, caused this to go away. – Steve Cohen Jul 02 '15 at 19:32
  • Have you tried my suggestion with the `Log4jConfigurer`? I’m wondering if it works :-) For that `OutOfMemoryError` you should create a separate SO question. – Chriki Jul 03 '15 at 09:02
  • Haven't had a chance yet. I needed to go with something workable to make progress on the meat of the application. Having done so, I will give it a look. And I will write a separate issue for the OutOfMemoryError too, unless your approach also makes that go away. – Steve Cohen Jul 03 '15 at 12:55
  • Sorry, your solution fails because Log4jConfigurer depends on DomConfigurator, which does not exist in log4j2. However the solution of @alan7678 which is more generic, does work with log4j2. Not sure if it works with log4j1. However, the OutOfMemoryError persists when there is no web.xml. As said before will write another question on this, unless I can find info about it. – Steve Cohen Jul 03 '15 at 16:50
  • see http://stackoverflow.com/questions/31211868/outofmemoryerror-when-hot-deploying-springmvc-app-to-tomcat7-possible-relation for the new question about OutOfMemory. – Steve Cohen Jul 03 '15 at 17:33