What is the issue with the runtime discovery algorithm of Apache Commons Logging

Why? What is the issue with its runtime discovery algorithm? Performance?

No, it's not performance, it's classloader pain. JCL discovery process relies on classloader hacks to find the logging framework at runtime but this mechanism leads to numerous problems including unexpected behavior, hard to debug classloading problems resulting in increased complexity. This is nicely captured by Ceki (the author of Log4J, SLF4J and Logback) in Think again before adopting the commons-logging API (which also mentions memory leaks problems observed with JCL).

And this is why SLF4J, which uses static bindings, has been created.

Ceki being the author of SLF4J, you might think his articles are biased but, believe me, they are not and he is providing lots of references (evidences) to prove his point.

To sum up:

  • Yes, JCL is known to be broken, better stay away from it.
  • If you want to use a logging facade (not all projects need that), use SLF4J.
  • SLF4J provides a JCL-to-SLF4J bridge for frameworks still using JCL like Spring :(
  • I find Logback, Log4J's successor, to be a superior logging implementation.
  • Logback natively implements the SLF4J API. This means that if you are using Logback, you are actually using the SLF4J API.

See also

  • Commons Logging was my fault
  • Think again before adopting the commons-logging API
  • SLF4J Vs JCL / Dynamic Binding Vs Static Binding

Commons logging is a light weight logging facade which is placed on top of the heavy weight logging API be that log4j, java.util.logging or another supported logging API.

The discovery algorithm is what commons logging uses to determine what logging API you use at runtime so it can direct log calls through its API to the underlying logging API. The benefit of this is that if you wanted to create a library that does logging, you do not want to tie down users of your library to any particular heavy weight logging system. Callers of your code can configure logging via log4j, java.util.logging etc. and commons logging will forward to that API at runtime.

Common gripes for commons logging:

  • Even though you don't use it, a library you depend on might so you have to include it in your classpath anyway.
  • Runs the discovery algorithm for each classloader you want to do logging in, which can produce unwanted results so make sure you put commons-logging.jar in the right classloader.
  • Greater complexity than the underlying logging framework.
  • Less features that underlying logging framework.

A perceived greater complexity as well as unpredictability in complex classpath hierarchies without any perceived benefits make users of commons-logging agitated. Given also that this choice may be forced on you does not make users sympathetic. See this article for a compelling argument against using commons-logging.


I can't speak about the "believed unpopular" aspect, I can only speak for myself:

Commons Logging is a facade over top of whatever your "real" logging framework may be: Log4j, Logback or whatever.

The idea of a logging facade is that your app gains the flexibility to decide at runtime which logging implementation it wants to work with. The facades are clever enough to find logging implementations at runtime.

My older Java apps use Log4j, directly. Works fine, I see no need to change them. My newer Java apps will probably use Logback. I think the ability to dynamically choose a logging framework is something none of my apps will ever need. Of course, other peoples' mileage may vary.


EDIT: Looks like I was wrong about the rationale for Commons Logging. The links given by @Pascal Thivent, especially the first one, explain this far better.


Commons Logging contains logic to determine at runtime whether to use log4j or java.util.logging.*.

That code used to be seriously broken, essentially only working with JUL.

Based on the experiences with this, slf4j was written which uses static binding (or used to, Im not sure with version 1.6) to choose the appropriate framework to use of log4j, JUL or the log4j fork logback (and more), and it includes a bridge to allow existing Commons Logging code to use slf4j transparently.

If you can, then go for slf4j.