Optional JCL

Overview

Most programs now days does use logging. This utility is meant for those programs that use Apache Commons Logging (JCL).
Mostly you someone will use logging to display runtime information but usually your program can run without any logging package being present (such as Pax Logging). Optional JCL scope is to facilitate optional usage of logging.

To have logging as optional you start by marking the org.apache.commons.logging as optional in the manifest file such as:

Import-Package: org.apache.commons.logging; version="1.0.4"; resolution:=optional

This will allow your bundle to be resolved and eventually started but this will not be enough as your code will fail in runtime with a ClassNotFoundException. You can resolve this further in at least four ways:

  • Remove logging — not a viable option
  • Guard each logging related instruction(s) with a try/catch — a lot of boiler plate code not related to your domain
  • Do your own logging framework that acts as a wrapper over JCL and do the logging calls if a logging package is present otherwise do nothing
  • Add a logging package — best option

It may also be the case that your bundle is required to not have any dependency and be deployed as a stand alone bundle.

Optional JCL tries to solve this recurring problem by exposing (exporting) the org.apache.commons.logging package but actually doing nothing at runtime (no logging message) acting as when your logging would be off and you can use it in two ways:

Deploy as standalone bundle

You can deploy the optional JCL bundle (see #usage instructions) and in this case your bundle will be wired by OSGi framework to optional JCL. It is not very common to use it this way but can be useful in cases you do not need logging at runtime and the Optional JCL bundle is very "lite" (as it does nothing) fact that can diminish the usual logging costs.

Embed in your bundle

Most common you will embed Optional JCL in your bundle in combination with an optional import (as shown above). What will happen is that due to the optional import you can run into the following situations:

  • The logging package gets resolved and your bundle will be wired to a "real" logging implementation such as Pax Logging and then the internal Optional JCL will not play any role.
  • The logging package does not get resolved so the internal Optional JCL will be used.

Note that you can embed it both as a jar and set Bundle-ClassPath or inline (exploded). Take a look at Felix maven bundle plugin for easy ways to archive this.

Downsides

The downsides of using the embed approach can be:

  • Few Kb more added to your bundle
  • There is no dynamically re-wiring meaning that if a logging package become available during the lifetime of your bundle the logging messages will still not appear at least not until you restart or update your bundle. It may be an option that Optional JCL will be changed in the future to discover the logging packages becoming available/unavailable and act as a proxy to the logging package.

Examples

The embed option is used by some of Pax projects such as Pax Runner, Pax URL and Pax Web. Browse the source code of these projects for details.