Java Logging Frameworks
Well, it’s the end of the term, and this also happens to be the first term that I’ve had an Advanced Java track to teach, so I have kind of been looking around for good topics to cover. It always seems to be this way with Just-In-Time course development. Anyway, next week’s topics are going to include Java logging frameworks, and that is quite an interesting topic all by itself. Unfortunately, it’s far deeper than I will have time for in class…
Everyone is already familiar with Log4j. (Or log4j or Log4J, whatever the standard capitalization is on that one. Even the Log4j website has a bunch of variations.) Log4j has been the logging framework of choice for years now, and having been released around 1998, it has had quite a few years to capture mindshare in the software development community. In fact, when Java 1.4 was announced to contain a logging framework, it really seemed to strike a lot of people as being yet another example of Sun copy-catting something devised by the Java development community. “Oh yeah, that’s right - logging is really important! We should have a logging API. We’ll make it a standard!” And the creeping featuritis that Sun has become known for, continues unabated.
Which is a side rant of mine - why does the Java Standard Edition API have to include every single feature under the sun? Why can’t this API be modularized into a Java core, and a number of libraries that can be selectively included or excluded from the JVM that ships with my application? I would like to be able to include or exclude big components in the JVM, like these:
- The Java core - threads, IO, networking, utility classes, etc.
(Well, this is always included.) - The AWT
- The Swing API
- RMI and CORBA
(In my eleven years of Java development, exactly one project I have worked on has required a CORBA ORB. But I’m sure glad it’s there, just in case…) - XML and XSLT capabilities
- The NIO facilities
- SSL, Crypto and Certs.
Call me crazy (and you’d better provide reasons if you do, or I’ll just ignore you), but that just makes sense to me.
Instead, we have statements like this on Sun’s Java website:
Exclusive for the embedded market, we’ve reduced the footprint of Java SE 5.0 for x86 Linux to 30MB.
Thirty megabytes. You don’t say. I’d love to see half a megabyte. It should be no surprise that I am really becoming attracted to the idea of using the Java Micro Edition for application development. Except that now ME is getting pretty bloated too.
Okay, back to logging.
So, Log4j is one of the most popular logging APIs out there, but now there is also Sun’s Java 1.4 logging API. Less features, but it’s part of Java now, which I guess to some people is a Good Thing. Then there are a few other logging APIs used here and there. So this leads to the big question: Which one do you use?
The good part of this question is that if you are writing your own application, you get to choose whatever you want to use; whatever logging framework actually provides the features that your application really needs. (Yes, a shockingly deep concept.) Log4j seems like a great choice to me personally; I don’t think it’s going away anytime soon. The same is true with the Java 1.4 Logging APIs; even though they don’t provide quite as many features as Log4j, they sure aren’t going away anytime soon.
But the question is a little more tricky if you are providing an embeddable software component, like Tomcat or Jetty. Then what do you do for logging? You have no idea what the host application is going to use for logging, so you really don’t want to pick something specific; the application developers might pick a different logging framework, and then they’d have two frameworks to configure and manage. That would just be aggravating to people.
So, a lot of these embeddable components use configurable logging wrappers that let developers plug in whatever logging framework they are interested in using. And I like that idea; it makes sense, as long as you don’t make your logging horrendously inefficient by doing so. (Cache stuff, people!)
Then there’s the Jakarta Commons Logging framework. This is what Tomcat uses, and a few other projects use Commons Logging, too. It’s a generic wrapper, and it attempts to be clever about managing things so that your embeddable component really doesn’t care at all about what actual logging framework is used.
Now, the first thing that you’ll notice when you read the Commons Logging documentation is that it really isn’t so much about logging as it is about class-loaders. And this is kind of odd at first. “How come I need to know about class-loaders to use Commons Logging?” Well, turns out that Commons Logging really does a lot of its management stuff with class-loaders, and that can make things pretty tricky to deal with, especially if your application also does its thing with class-loaders. And, as Java applications get more sophisticated with providing pluggable architectures, and as they start providing dynamic upgrading and reloading of plugin components, this starts to really become an important issue to watch out for. So you really do have to take care of what you are doing if you are going to use Commons Logging in your software component.
This has really ticked some people off, too. I think this is funny - software that makes people angry! You see web pages like these:
- Think again before adopting the commons-logging API (by Ceki Gülcü, creator of Log4j)
- Commons-logging revisited
And, of course, the Commons Logging team has its own response to these pages:
The Commons Logging page is correct when it identifies the common theme on these anti-CL pages as being class-loader management issues. Sure, that stuff ain’t fun to deal with, but most of these applications that are embedding components like Tomcat already have to deal with class-loaders, so this really shouldn’t be anything new.
Here is an excerpt from the “Think again” article that irritated me (emphasis theirs):
If you opt for the commons-logging API, then the behavior of your system will depend on external circumstances which you as a developer cannot control. In general, all solutions based on class loading hacks are brittle and result in painful bugs. Moreover, these bugs can only be fixed by displacing jar files more or less at random.
I feel like this statement is a bit of a cop-out, and it belies a bigger problem: a lack of understanding the tool that one is trying to use. This is most clearly indicated in the final statement that the “fix” is “[to displace] jar files more or less at random.” No, not at random. This stuff is deterministic, people. There are specific places that things can go, based on what class-loaders are being used and where they pull their JAR files from. Understand that arrangement first, then figure out where things should go. Don’t just shuffle around things at random until you find something that works. What does that buy you? What happens next time it breaks?
I see students do this with their code, and it’s the same thing - their goal is to get the beast to work, not so much to understand what is going on. At the end, maybe it works, but they don’t know why! So I think that’s why this little excerpt was so particularly irritating to me.
The Commons Logging FUD page really puts everything into perspective, and I really recommend that people read the last part of it, because it really clarifies the whole point of Commons Logging in the first place. It’s important to keep that stuff in mind.
Anyway, who knew that people could get so stirred up about logging! I think that for the majority of my projects, I’ll probably just use Log4j directly, or in one or two special cases I’ll wrap it with something else (probably something simple). I think I’d rather teach the students Log4j too, since that is the most likely thing they will encounter on software projects. Plus, logging is logging; it’s not brain surgery. Once you get the basic idea, the rest is just details.
June 5th, 2006 at 7:06 pm
Preach on brother! I couldn’t agree more with the bloatware known as the Standard Edition. And it’s not just CORBA now, don’t forget all that web services crap too.
On the subject of commons logging, or Clogging as it’s known in certain circles, check this out. It’s hilarious!
So my advice is teach log4j and don’t concern the kids with class loaders just yet. It’s simple and easy to use and everybody loves it.
June 18th, 2006 at 12:17 am
I agree with Luckyspin, except that I think understanding classloaders, reflection, and other related features to be critical for any Java course purporting to be “advanced.” In fact, I use classloader interview questions as a quick and easy filter for the continuous stream of “Java experts” I talk to.