Apache Commons Logging – Explained
Apache Commons Logging (previously known as Jakarta Commons Logging or JCL) is a thin adapter allowing configurable bridging to other, well-known logging systems like Log4J, LogKit. But through wrappers, you can use commons-logging with any other logging systems like log4j2, SLF4J, LogBack, etc.
The JCL is not a logging framework by itself. But it provides an abstraction over other logging frameworks. This makes JCL a better candidate for tooling developers. For instance, Spring Boot uses JCL under the hood and LogBack is the actual implementation for logging.
Why use Commons-Logging?
As I said earlier, JCL requires a logging implementation like Log4J or Logback to work. So If you are developing just for you, then Commons Logging may not be for you. But for those who develop a public library or framework would require their code to be logging framework agnostic. This is where commons-logging shines.
Commons Logging comes with reasonable defaults. And it can auto-detect your preferred logging system if you already have one. This way you don’t have to configure anything at all. Just add
commons-logging.jar to your classpath and you most likely don’t need any configuration.
Configuring Commons Logging
To use commons-logging, you only need the
commons-logging.jar. If you are using a maven project, you can simply add the following snippet.
<dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency>Code language: HTML, XML (xml)
By default, Apache Commons Logging will auto-detect the logging system that you use. For example, If It finds log4j in your classpath, then it will use Log4JLogger to redirect all logs to log4j. If it doesn’t find any, it will use a Jdk14Logger.
JCL looks for a logger implementation in the following order.
- Look at commons-logging.properties for org.apache.commons.logging.Log
- See if a system property is set for org.apache.commons.logging.Log
- If log4j is available in classpath use Log4JLogger wrapper class.
- If no logging system available, then use Jdk14Logger.
There used to be a SimpleLog implementation for versions below java 1.3. But it doesn’t matter anymore.
Out of all these, the easiest option is not to provide any configuration and let the clients take care of logging systems.
Also, Apache Commons Logging doesn’t provide any way to configure the underlying logging system just for this reason. The client should decide which logger they want to use. And this is a deliberate design decision from the commons-logging team.
Using JCL with logging systems
As Apache Commons Logging is based on JDK 1.4 logging APIs (JSR-47), only log4j and Logkit are supported out of the box.
To use Log4J as your logging client, simply add log4j-1.2.jar to your classpath and add log4j.properties configuration file, and you are done.
Configuring commons-logging with Logback
Logback has been the replacement for log4j1.x. But it doesn’t comply with JSR-47. So you need to use the jcl-over-slf4j dependency to bridge the gap.
<dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.7.32</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.9</version> </dependency>Code language: HTML, XML (xml)
With these dependencies, if you have a valid logback.xml, Then you have yourself a working logback system with log statements coming from commons-logging.
Working with Log4j2
Log4j2, the successor of Log4j1.x, is also not compatible out of the box with commons-logging. For this reason, you need to add a JCL bridge to make log4j2 work.
<dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-jcl</artifactId> <version>2.17.0</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.17.0</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.17.0</version> </dependency>Code language: HTML, XML (xml)
With these dependencies along with a log4j2.xml configuration, you could easily redirect all logs from apache commons into the Log4J system.
Alternatively, you could use the jcl-over-slf4j and let slf4j speak to log4j2. But as you see from the above picture, it takes too many jars/routing thus causing performance overhead.
When should I use commons-logging?
You should prefer commons-logging if,
- You are writing shared libraries. This is important, because, if you chose to write everything using log4j, then the people who use your libraries now have conflicts between their logging systems. For example, They may have been using Logback or Log4j2 or even java.util.logging(JUL). By not associating your library to a single logging framework, the people who use your libraries can benifit from the auto-detection of commons-logging.
- You are developing application that someone else will maintain. So that the person installing can choose the logging library of their choice.
- You want to keep your code Logging system agonostic. This reason is more of an optional thing. You could always refactor the entire codebase to pattern match and replace all the imports. But It is much easier to just change the pom.xml isn’t it.?
We learned more about apache commons-logging in this post and how to configure it with various logging systems.