Spent half the day fighting with Tomcat 5.5, trying to get log messages out of my application. I need to rant a bit here.
I’m deploying a vanilla webapp with its own log4j.xml in WEB-INF/classes. Why does this not just work out of the box? Because, hey, maybe you’d want to use some other logging library. Not that there are any out there that don’t suck, but y’know, maybe someday. So we need to leave this all open-ended and configurable.
You see, once upon a time, we had Log4J. It was good. In fact, it was perfectly sufficient. It solved the problem. It did just about everything you could want.
Unfortunately, Sun was also developing their java.util.logging (JUL) around that time. They went through the whole JSR community process, so they started earlier and finished later. It sucked, but Sun owns Java in a very literal sense, so we were pretty much stuck with it. Not in the sense of actually having to use it, thank god, but any poor bastard writing logging tools had to accommodate it.
So then we got Apache Commons Logging. It’s a diplomatic facade that stands in front of either of them so your code can be agnostic about whether you’re using Log4J or JUL under the hood. In practice, anyone who doesn’t have a paycheck from Sun and a gun to their head uses Log4J. Java Developer’s Journal did a comparison of the two. They tried to give a “fair and balanced” report, as in, “there are situations in which JUL might be the better choice.” If you read between the lines, those situations were essentially if you’re writing a toy application that would probably be fine with System.out.println().
There’s something of the paradox of choice here. Trying to leave all your options open is ultimately less effective. Your code has to be way more complex to support everything, and you almost always have some sort of mismatch that forces you into a limited-functionality common denominator. It’s not worth it. Pick something that works and go with it.
So today’s pain came about because rather than doing that, Tomcat 5.5 seems to have slapped yet another layer of indirection and indecision on things. It seems that one of the ways in which java.util.logging sucks is that you can’t have multiple configurations within an application. Why on earth would you want to do that? Well, if your application is a web application server, it needs to run a bunch of java libraries as if they were standalone applications. Kinda killer flaw there, huh? But who can pass up the challenge of hacking around something that thoroughly broken? And hey, it’ll make it standards-compliant.
So you end up with these gems from the Tomcat 5.5 logging page:
the default Tomcat configuration will use java.util.logging.
And a bit later on:
The default implementation of java.util.logging provided in the JDK is too limited to be useful.
How can you say that and still build in support for it? Grow a spine, people! How much simpler would this world be if you just followed that up with, “…so Tomcat uses Log4J exclusively. Don’t like it? Write your own app server.”
But no, what did they do? They hacked together their own implementation of the java.util.logging API. Apparently, it’s not “too limited to be useful,” but it “is not intended to be a fully-featured logging library.” Why bother? You’ve had a fully-featured logging library for the last 6 years. Why would you make the default logging configuration one which by your own admission is really not adequate? Why not make Log4J the default? If you really have to, then you can provide instructions on how to plug in your half-assed substitute.