GWT Hosted Mode and Log4j

This is a short tutorial on getting log4j to run in the embedded Tomcat included with GWT.  Before I go on I need to say that log4j will only work on the server-side. GWT doesn’t support logging with log4j on the client side (yet…maybe). To log on the client side you’ll still have to use GWT.log()

There are four things we’ll need to accomplish:
1. Place the log4j.properties file
2. Write a servlet that will initialize the logger.
3. Modify the web.xml file.
4. Modify the GWT -shell and -compile scripts.

1. Place the log4j.properties file

Under <gwt-project>/tomcat/webapps/ROOT/WEB-INF/ create a “classes” dir.  The “classes” dir is where you put the log4j.properties file.  Here’s the log4j.properties file I’m using:
log4j.rootCategory=DEBUG, dest1, dest3

! Log to the console
log4j.appender.dest1=org.apache.log4j.ConsoleAppender
log4j.appender.dest1.layout=org.apache.log4j.PatternLayout
log4j.appender.dest1.layout.ConversionPattern=%-5p %d{HH:mm:ss.SSS} [%-15.15t] [%-25.25c{1}] %m%n

! LOG TO A FILE
log4j.appender.dest3=org.apache.log4j.RollingFileAppender
log4j.appender.dest3.layout=org.apache.log4j.PatternLayout
log4j.appender.dest3.layout.ConversionPattern=%-5p %d{EEE MMM dd HH:mm:ss.SSS zzz yyyy} [%-15.15t] [%-25.25c{1}] %m%n

! Specify the file name
log4j.appender.dest3.File=./logs/hosted-log4j.log

! Control the maximum log file size
log4j.appender.dest3.MaxFileSize=3000KB
log4j.appender.dest3.MaxBackupIndex=3

2. Write a servlet that will initialize the logger.

Next you’ll want to have a servlet that will load the properties file and init the logger. This file (Log4JInitServlet.java) will go in the <gwt-project>/src/ dir.

package com.nick.example.server;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
/**
* Log4JInitServlet
*
* This class should get loaded first (based on the web.xml),
* so it can init the logger.
*
* @author Nick
*/
public class Log4JInitServlet extends HttpServlet {
  static final Logger logger = Logger.getLogger(Log4JInitServlet.class);
 
  public void init() throws ServletException {
    System.out.println("Log4JInitServlet init() starting.");
    String log4jfile = getInitParameter("log4j-properties");
    System.out.println("log4jfile: "+log4jfile);
    if (log4jfile != null) {
      String propertiesFilename = getServletContext().getRealPath(log4jfile);
      PropertyConfigurator.configure(propertiesFilename);
      logger.info("logger configured.");
    }else{
      System.out.println("Error setting up logger.");
    }
      System.out.println("Log4JInitServlet init() done.");
  }
}

This servlet should be loaded first, which can be accomplished by modifying the web.xml file.

3. Modify the web.xml file.

This file is located in <gwt-project>/tomcat/webapps/ROOT/WEB-INF/
My web.xml file looks like:

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
  <servlet>
    <servlet-name>Log4JInitServlet</servlet-name>
    <servlet-class>com.nick.example.server.Log4JInitServlet</servlet-class>
    <init-param>
      <param-name>log4j-properties</param-name>
      <param-value>/WEB-INF/classes/log4j.properties</param-value>
     </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet>
    <servlet-name>shell</servlet-name>
    <servlet-class>com.google.gwt.dev.shell.GWTShellServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>shell</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
</web-app>

Notice the line <load-on-startup>1</load-on-startup>, which tells tomcat to load the Log4JInitServlet first.

4. Modify the GWT -shell and -compile scripts.

Modify your gwt –shell and –compile files to add the log4j jar into the class path. Here’s my <project>-shell.cmd file. Take note of the log4j jar that I added.

[Windows]
@java -Xmx256M -cp “%~dp0\src;%~dp0\bin;C:/lib/gwt-windows-1.5.3/gwt-user.jar;C:/lib/gwt-windows-1.5.3/gwt-dev-windows.jar;C:/lib/gwt-windows-1.5.3/log4j-1.2.12.jar” com.google.gwt.dev.GWTShell -out “%~dp0\www” %* com.nick.example.HostedLog4j/HostedLog4j.html

[linux]
#!/bin/sh
APPDIR=`dirname $0`;
java -Xmx256M -cp “$APPDIR/src:$APPDIR/bin:$HOME/projects/gwt-linux-1.5.3/gwt-user.jar:$HOME/projects/gwt-linux-1.5.3/gwt-dev-linux.jar:$HOME/projects/lib/log4j-1.2.15.jar” com.google.gwt.dev.GWTShell -out “$APPDIR/www” “$@” com.nick.example.HostedLog4j/HostedLog4j.html;

Make sure to change the <project>-compile.cmd in the same way.
You can then run your <gwt-project>-shell.cmd and the logger should work. It will create a log directory in under <gwt-project> and place your log file inside there.


4 Comments

  1. Pepe says:

    You can also create a lib folder under the WEB-ROOT folder and put the jar file there.

  2. Stefan Zobel says:

    Wow, this looks way to complicated for me!

    We’re using Apache commons-logging with Log4J underneath. All we had to do was to put the log4j.properties and a further “commons-logging.properties” on the classpath (and the two jars, of course) and it works.

    In the commons-logging.properties we have this line:

    org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger

  3. yzs says:

    this article says GWT Hosted Mode can’t print the log in console,you need put the log4j.properties Under /tomcat/webapps/ROOT/WEB-INF/ create a “classes” dir,just ok.

  4. GwtQA says:

    Great job . pretty good documentation saved me a lot of time

Leave a Reply