WebSphere Portal & Log4j Hell

I am still getting acquainted with WebSphere Portal, and to make things more difficult, I do not have a debug-able server to test on (yet).  This is very disappointing because I think debugging is a great way to become more familiar with a new technology.

Anyway, due to the lack of a debugger, I am constantly having to use logging as a means to debug my code base.  It did not take long before I became quite disappointed with the WebSphere provided logging capabilities, and desired to integrate log4j within my Portlet.  However, this was much more difficult then it should have been.

I setup JCL (Jakarta Commons Logging) like I have used on any other project in my past (web.xml listener, log4j.xml, include the proper .jars, etc.), but I saw some very odd functionality: when my portlet was deployed, the MyPortlet.log file was created, but nothing was logged into the file.

My first thoughts were that I had improperly configured my log4j.xml, so I swapped out an even simpler log4j.properties file with a new file name (MyPortlet_2.log) just to see if that file would be created as well.  I then deployed my portlet, and again it created the log file (MyPortlet_2.log) but nothing was logged there.

I then checked SystemOut.log, SystemError.log, and trace.log, and none of them had my log messages.  This was very odd, so I then decided to see what the implementation was returned by the code:

private Log log = LogFactory.getLog(MyPortletClass.class);

I saw that log was an instance of Jdk14Logger, instead of the JCL version I was expecting. I then looked at the server to see what libraries were in the classpath above my portlet, and discovered that the “ws-commons-logging.jar” contains a file named “commons-logging.properties”, and low and behold, it had:

org.apache.commons.logging.LogFactory = org.apache.commons.logging.impl.Jdk14Factory org.apache.commons.logging.Log = org.apache.commons.logging.impl.Jdk14Logger

Not at all what I was expecting.  I then realized the problem: there was a commons-logging.properties higher in the classpath then the one I was providing.

After many hours of Google searches and Websphere Portal research, I finally figured discovered a few options to elegantly solve this problem: http://www-01.ibm.com/support/docview.wss?uid=swg27010153&aid=1
However, I did not want to go down any of these paths. So, I simply just used the Log4j interfaces instead of using the Commons-Logging (JCL) interfaces, and it worked like a charm.

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class Foo {

private Log log = LogFactory.getLog(Foo.class);

}

***** My version

import org.apache.log4j.Logger;
public class blah{

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

}