« Best Disclaimer Ever | Main | Scenes from a Job Spec »

Java Logging Frameworks Must Die

Last week I performed a release of some client software, the change was small and discrete: a move from Torque v3.2 to Torque v3.3, and a small database schema change. That was it.

Then I get the call: their archive isn't working, can I investigate. Their archive is a web application frontend to an IMAP server storing archived email data. Simple, effective, and as of last week, broken.

Dig, dig, Google, dig.

Eventually I find the culprit: Torque was depending on an obscure logging framework, which was in turn depending transitively on an obscure incomplete implementation of javamail called geronimo-spec-javamail. This was pulled in alongside javamail as shipped by Sun.

Two competing incompatible implementations of javamail in the same application in the world of Java == fail.

Fast forward a week. Another application that is up and running fine is suddenly reported as not working. All the application does is create an email with a velocity template, and send the mail. That's it. But Velocity depends transitively on an obscure logging framework, which recently decided for no clear reason would not longer work from within a web application.

When you spend more time tracking down obscure sudden failure cases than you do producing actual code, you know you've reached the tipping point of failure.

Java logging frameworks must die.

*Froth* *seeth* but... but... we need logging frameworks! We need to log data. We need to be able to log from this code and not that code, we need deeply buried libraries to send out emailed error messages! We need to know what's going on!

No, you don't.

Your code needs to throw properly formatted, meaningful exceptions. And your code needs to catch these exceptions as appropriate, and act properly on the failure cases. And that is it.

Yes, there are reasons to log. If you need to log each hit to a webserver, a log makes perfect sense. If you are saving performance related data at regular intervals, that makes sense. But if you are spitting out random obscure unintelligible data at points buried within your code, your logs make no sense, and you're wasting your time, and your client's money.

Intertwined with the misguided need for logging is the typical Java practice of keeping unstructured property files. What's wrong with unstructured property files? Try make a spelling mistake in one.

It doesn't work. It should work. But it doesn't. Desperately you enable every bit of logging you can possibly find, looking for a clue in the reams and reams of unintelligible rubbish streaming past as to what you did wrong. Time ticks past, deadline pressure looms, manhours are burned, all for a spelling mistake that made your setting cease to exist.

There is an irony in that a language with such a rich history of structure should have so much code layered on top of it whose sole purpose is to rip out that structure. Unstructured property files. Unstructured beans produced by Spring. Unstructured logging.

All of this ill-discipline is like attaching a bungee cord around one's waist and attempting to run. You get going quickly, but each step becomes harder and harder. Eventually you stumble and fall backwards, and you are doomed to never get anywhere.

The architects of Java have spent a decade and a half relentlessly adding, adding, adding to Java. Java needs a brutal spring clean if it is to survive as a language, and I believe that the java logging frameworks should go first.

TrackBack

TrackBack URL for this entry:
https://blog.pier29.net/mt/mt-tb.cgi/2006

Comments

So, so true.

Seemingly minor upgrade to Hibernate EM revealed that they COMPLETELY SWITCHED THE LOGGING TO A DIFFERENT LIBRARY between the minor versions. Imagine dozens of projects that had to have their dependencies re-analyzed and updated.

Dear framework and utility library writers:

Leave logging to application developers. We almost never need it and we HATE resolving logging dependencies and figuring out where to put all of the logging configuration files. As the writer says, throw exceptions when you encounter a problem. We'll all end up with better code in the end.

And here's an idea: if you absolutely, positively need put logging code somewhere deep down, use java.util.logging.Logger (we don't mind if your latest-and-greatest doesn't support Java 1.3) Performance? If your service code depends on the performance of the logging framework, I suggest your code needs a re-think.

-g


Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)