The evils of commons-logging.jar and its ilk

Almost everyone nowadays will eagerly extoll the virtues of commons-logging.jar and what a modern day miracle it is. How it makes logging so easy and enjoyable, how pluggable logging subsystems is just what they fantasised about when they were little boys.

To all these people, I say ‘fools!’

Commons-logging brings to Java the wonderful technology that Windows lovers everywhere affectionately refer to as dllhell. The presence of multiple versions of a particular library, and the ensuing fun in determining exactly what version your app in picking up, and from where.

This pesky little problem is wonderfully brought into focus if you do any J2EE work. Witness the endless hours of joy you’ll experience if you try to ship your own commons-logging.jar into Tomcat, or a rival log4j into JBoss. Even the mighty Weblogic has the same problem, in the shape of an innocuous looking bsh jar.

Stupid people everywhere will insist on what a wonderful thing this is, that you have one logging library and if all apps conform to it, you can control all their logging.

This argument is particularly offensive as those who make it clearly aren’t interested in making life easy for developers or end users. When I deploy into an app server, I can’t think of a single situation whereby I’d want my logging output to be mixed in with the appserver’s messages. Realistically, an appserver’s info/debug messages are more likely than not to be gibberish and of absolutely no interest to me.

Sure, I could configure a host of appenders (which of course, is log4j specific, not commons-jar, so you in fact do need to know about the actual implementation used). Really though, isn’t that a little bit cruel, forcing me to figure out what categories JBoss uses so that I may send them to an appropriate final resting place?

Even more fun is the joy of reconfiguration. With a few measly lines of code and a cunningly placed configuration file, you’re able to gleefully (or accidentally, depending on your mental state at the time) hijack the application server’s entire logging. No more error messages for you! As things start up, you see a bevy of debug messages, and then suddenly it’s radio silence, as your own configuration that happens to be set to just show ERROR messages kicks in.

In practice, the least painful deployment experience has always been with appservers that use almost no popular components, and that use their own internal logging system and other services, rather than a bunch of opensource products cobbled together by bits of frayed string.

Of course, there are some novel solutions to this situation. Jive software for example ship one big jar for any given product of theirs (or used to, I don’t know if they still do or not). This jar includes absolutely everything you might need, from JDBC drivers to jakarta’s oro package. The trick they employ though is to repackage it all to be under a com.jivesoftware package. Thus for all intents and purposes it’s an internally used set of classes that they can guarantee nobody else will hijack or abuse.

16 Responses to “The evils of commons-logging.jar and its ilk”

  1. lowem Says:

    Ah, this brings back memories of the good old weblogic.jar. Ah yes. “DLL Hell”, say hello to “JAR Hell”.

  2. martin Says:

    More remedies please?

  3. Keith Lea Says:

    Why doesn’t anyone use the JDK’s logging facilities? Is it not a standard, pluggable API? (I’m really asking; I’m not being sarcastic or hostile.)

  4. Daryl Oidy Says:

    Well, it’s only in JDK 1.4, so it doesn’t help you if you need to run on older JVMs. And some people would just rather stick with the logging classes they already know and love.

  5. Craig Heighton Says:

    Why should the host application e.g. tomcat provide access to it’s own logging mechanism. It should be down the people doing the deployments to manage whether they want a shared commons jar or one per web-app. the apps should not have access to the hosts apps Classloader in this way. And as for versions ALL jars should have a obvious version number and standard perfix. e.g commons-logging-1.0.jar. This allows you to search your classpath for the prefix and find out what versions are around at a glance.

    Dll hell comes from badly named libs and enormous search paths. NOT from shared common access code as you suggest.

  6. Jason Carreira Says:

    Craig, that’s well and good in theory, but unless you move your classes to something like com.foo.mypackage.v1.MyClass you get the problem of the app server having the same class in the class path (package and class name remain the same) from different versions. Then you access the added classes in v2.0 and it breaks, because the v2.0 class it uses is not found, because the v1.0 class was found first.

  7. Cameron Purdy Says:

    Jive has other dependencies, such as Coherence for clustering, but they package it all in a way that is friendly for the IT pro that is installing their software. (We use Jive extensively, and we love it, and we would still love it even if they weren’t a Tangosol OEM.)

    It takes a lot of work to make software usable, and it takes ten times that much work to make it easily installable, configurable and manageable (and in Jive’s case: customizable too). Companies like Jive build their reputation on that ease, and that’s why people buy their software instead of using the free open source equivalents.

  8. Nick Minutello Says:

    Crikey, a technical discussion at bileBlog??

    |
    | I can’t think of a single situation whereby I’d
    | want my logging output to be mixed in with the
    | appserver’s messages.
    |

    Except when you want WebLogic’s “WARNING : JDBC Connection leak” messages interleaved with your application debug logging, so you can work out where you are leaking….

    -Nick

  9. Aleksander Slominski Says:

    One possible solution to this is to have easy to embed into your package structure logger class. i have written such utility called MicroLogger freely available so you can tweak it to your logging needs: http://freshmeat.net/releases/131068/

    Addressing comment by Daryl Oidy: i agree that requiring use JDK 1.4+ sometimes is not possible so i made sure that MicroLoggers works very well in JDK 1.2+ and has API as similar to JDK 1.4 as possible to facilitate migration.

    BTW: for some reasons that i am yet to grasp commons logging jar is shipped with Java source code that can confuse some IDEs: http://forum.omnicore.com/showthread.php?s=&threadid=1341 - one would anybody on earth put .java files with .class files in JAR?! or it is just me unlucky enough to get this “special” JAR?

    thanks,

    alek

  10. Anonymous Says:

    IMHO you are blaming the wrong kid in this case. The logging mess in all the app servers out there is because they are not able to separate server/container and application classloaders in a way not causing conflicts with different versions of the same library.

  11. Anonymous Says:

    Version management is one of the most lacking aspects of Java. If Java is going to copy anything from .NET, please add some competent version management before tackling things like “foreach” syntax sugar.

    Every jar should have a set of formal and *required* version attributes, as well as a required set of declared jar+version dependencies. The runtime should enforce versioning requirements. This should allow multiple versions of the same jars to co-exist in a single classpath and classloader. Until this happens we will have to resort to a combination of finger-crossing/hail-Mary’s and/or kludges (like re-writing the dependent package names) to have a deployment free of versioning bugs.

  12. Bruce Snyder Says:

    ClassWorlds (http://classworlds.codehaus.org/) is one solution to this jar hell. I’m not sure why vendors don’t at least take the ClassWorlds approach of setting up separate realms or zones that each use its own ClassLoader.

  13. Costin Manolache Says:

    The reasons commons-logging exists are: JDK logging API is tied into JDK1.4 ( and not very good, but it’s not the only half-bad/half-good API ), there are already plenty of logging implementations ( log4j, logkit, jdk logging, proprietary/custom loggers). What we want is a common API, to use across jakarta libraries and projects - and unfortunately the Sun API doesn’t fit.

    Tomcat for example may be embedded in various app servers - like Sun reference impl, jboss, etc. Each uses it’s own logging. Just like we don’t want tomcat to have it’s own configuration ( and in 5.0 it uses JMX - so it can use whatever the host is using instead of server.xml ) - we don’t want tomcat to have it’s own logging.

    There are also some implications on sandboxed env, where the webapps don’t actually have the rights to log wherever they want, instead the admin controls all the logging.

    Keep in mind commons-logging is an API, and it is supposed to be a “platform” API ( like JDK1.4 logging ). It’s unfortunate JDK1.4 logging didn’t
    work and we had to do commons-logging, but it is IMO the right solution. Version management and DLL hell is a valid concern, however commons-logging has been pretty stable and backward compatible, and I don’t think it creates major problems by its own.

  14. Eric Bloch Says:

    Here here. commons-logging has caused me days of time at this point. I hope to see it die soon.

    -Eric

  15. Bill Schneider Says:

    no kidding. I’ve also suffered because of commons-logging. I recorded some potential solutions on my blog.

  16. Roberto Lo Giacco Says:

    I don’t agree with you: logging configuration depends on deployment team, not on development. What commons loggin achieve is abstracting you (the developer) from the deployment logging framework. It isn’t the solution for ALL problems, but it solves many development problems.

Leave a Reply

You must be logged in to post a comment.