Thursday, November 19, 2009

Signs your recommendations could use some work

Facebook likes to recommend friends for you, and recently it started recommending actions as well. Quite often it's recommending I poke someone, but yesterday I got this:

A recommendation for Facebook: you probably don't need to remind people to catch up with their partner.

Sunday, November 1, 2009

Log4J Null Pointers

Sometimes you may get a strange error message in your logs coming from Log4J. Depending on what version you're using, you may get odd messages like
LogMananger.repositorySelector was null likely due to error in class reloading, using NOPLoggerRepository

If you're using an older version, you may get a NullPointerException somewhere in the Log4J bowels.

So what's happening? Basically, it's Tomcat being helpful. When you redeploy a webapp to Tomcat (perhaps by using Eclipse in debug mode, or by using the Manager webapp), Tomcat goes and clears out any static fields by setting them to null before reloading. This helps to prevents memory leaks in your webapp.

However, the order in which it does this can't be specified, and if it happens to Log4J before it does another class which uses Log4J somewhere, you can run into the situation where Log4J is essentially broken but other classes are still trying to use it. This can happen on a shutdown hook, but more commonly it'll happen because Tomcat has to use reflection to find out about fields. The associated bug for this issue has more information.

So, what can you do about it? It's actually quite easy to solve: ensure your Log4J jars aren't in your webapp's lib folder -- you could either move them to tomcat/shared/lib, or if you want Tomcat to use Log4J too, move them into tomcat/common/lib. If you're using commons-logging, move that in there too.

The issue is supposedly resolved (ie you could put Log4J in along with your webapp) with Tomcat 5.5.25+ and Log4J 1.2.15+, but I could still reproduce it with 5.5.27 and 1.2.15. I'd recommend you move them into tomcat/common/lib, if only because then you can control Tomcat's logging with Log4j.

NOTE: when you move the jar files, you'll also have to move your or log4j.xml. This has the (possibly welcome) side effect of having one central configuration file, rather than one per webapp.