Hello all,
Given that log4j is such a low-level library, most organizations are suspicious to tie their code to log4j, especially considering the new logging API in JDK 1.4. Before going forward, it is appropriate to mention that these two APIs are very similar. The classical usage pattern for log4j is: --------------------------------------------------------------- import org.apache.log4j.Logger; public class MyClass { final static Logger logger = Logger.getLogger("some.name"); public void foo1() { logger.debug("Hello world."); } public void foo2() { logger.info("Another message."); logger.error("Stop that!", new Exception("The earth is getting warmer.")); } } --------------------------------------------------------------- As you are well aware by now, one of the important benefits of log4j is that it can be configured at run time using configuration scripts. You can have hundreds or thousands of log statement but only one or two lines of code to configure log4j. The usage pattern for the JDK 1.4 logging API is: --------------------------------------------------------------- import java.util.logging.Logger; public class MyClass { final static Logger logger = Logger.getLogger("test"); public void foo1() { logger.debug("Hello world."); } public void foo2() { logger.info("Another message."); logger.error("Stop that!", new Exception("The earth is getting warmer.")); } } --------------------------------------------------------------- Do you notice anything similar? The JDK 1.4 logging API also admits configuration scripts. Being part of the JDK, the common guess that this API will supplant log4j some time in the future. It is not so easy to write a complete logging API. Users come to realize they need the features present in log4j but absent in JDK 1.4 logging API. Moreover, log4j runs with JDK 1.1 or later whereas the JDK 1.4 logging API, requires, well, JDK 1.4. Most users can't afford to tie their code to JDK 1.4. But they need logging and they need it now. A common strategy for protecting against future changes and at the same time to benefit from existing log4j features is to *wrap* log4j with a custom logging API. Log4j actually has support to facilitate such wrappers. It turns out that such wrappers are not that trivial to write. I frequently receive email where a user runs into a problem with their wrapper and requests help. More often than not, these wrappers are of poor quality such that the cost of inactive (or disabled) logging statements is multiplied by a factor of 1'000. Of course, not all wrappers are of poor quality. For example, the commons-logging API is rather well implemented. Obviously, there is still a cost for the wrapping but it won't be of a huge factor. The commons-logging API will try to use the JDK 1.4 API if present, or the log4j API. The *current* preference is log4j I believe. Neat! Now, it just happens that the part where most users have difficulty is the initialization of the log4j API. Where should the log4j.jar go? Where do I put the log4j.properties files? Can I have different web-applications have different log4j configurations? How do I initialize log4j in an application server? Although there is ample literature on the subject, much confusion remains. The commons-logging API as it wraps multiple logging APIs such as Avalon's LogKit, log4j, JDK 1.4 has its own "discovery process". Things were confusing before, they will be even more when commons-logging API enters "common" usage. With some effort, it might start making sense to you. However, your users will not show the same perseverance nor enthusiasm. There will be also unexpected interactions between log4j and the commons-logging API. For example, log4j 1.2alpha1 through alpha4 had a very subtle bug which caused client code compiled with log4j version 1.1.3 to throw exceptions when ran with log4j 1.2alpha. Inversely, code compiled with 1.2alpha would crash when ran using log4j 1.1.3. This problem was fixed in log4j beta. It is now sufficient for client code to be compiled with 1.1.x and to run with 1.2 beta without problems and vice versa. Of course if commons-logging compiled with log4j 1.2alpha the problem would be sticky. It would not go away by compiling client code but only by replacing the commons-logging API. In the recent weeks I have also started to receive disturbing bug reports where components using commons-logging API behave strangely. http://nagoya.apache.org/bugzilla/show_bug.cgi?id=7484 http://nagoya.apache.org/bugzilla/show_bug.cgi?id=6764 I suspect that these problems will only worsen in the future. The commons-logging developers will suspect a log4j bug and we will suspect a commons-logging API bug. By increasing the number of components required for logging you have doubled the probability of bugs while the difficulty of resolving them has increased by a higher multiple. Remember that the initial goal of introducing a wrapper API was to protect our coding investment. If for whatever reason you decide to drop log4j in favor of JDK 1.4 (or the other way around) a simple string search-and-replace operation will do. Most IDEs support search-and-replace operations on multiple files. All you have to do is to replace "import org.apache.log4j.Logger" with "import java.util.logging.Logger". I believe the saying is "a penny today is worth a promise of a nickel tomorrow." By adopting a wrapper API, you are trading "a nickel of today for a promise of a penny tomorrow." As long as you are aware that the supposedly free-lunch may turn out to be an expensive and not so tasty meal after all... -- Ceki My link of the month: http://java.sun.com/aboutJava/standardization/ -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>