Wednesday, March 15, 2006

Fiction disguised as hands-on experience

I am not a big fan of Hani Suleiman. The feeling is apparently mutual. In response to my recent post about SLF4J's first release on TSS, Hani replied with what he claims are facts based on his hands-on experience.

Don't get me wrong, criticism is OK and even welcome. Accepting criticism is part of the open development process. It's fiction disguised as fact that I object to.

First claim:
Most implementations are forks of log4j and are written by Ceki, none of which are usable.

This one is easy to debunk. JDK 1.4 logging, x4juli and Simple-Log are developed by many developers, other than myself. He also claims that none of the SLF4J implementations are usable, a claim which is in contradiction with his own writings that follow a few lines below.

Except that many apps that depend on log4j blow up with nlog4j, due to slightly different method signatures than what they expect. So you can't use nlog4j if you use any of the apps that use log4j.

This claim, as stated above, is false, except for the 6 weeks between June 28th and August 16th in 2005.

NLOG4J is a drop in replacement for log4j. Code previously compiled with log4j will run fine with NLOG4J. Moreover, the same code will compile fine against NLOG4J (without any changes). Unfortunately, due to signature changes in some important logging methods, compilation against NLOG4J is sticky. Software compiled against NLOG4J will require NLOG4J to run. Hani's claim about incompatibility with log4j-compiled code is false. However, it was valid for 6 weeks, starting with the release of NLOG4J version 1.2.14 on June 28th 2005, ending with the release of NLOG4J 1.2.16 on August 28th, when the problem was fixed.

Perhaps Hani did really try out NLOG4J during those 6 weeks. Nevertheless, as a person voicing such strident criticism, he would have been well advised to check his claims against newer versions of the software, which were available for several months at the time he wrote his comments.

Hani's comments about JDK14 indicate that he has still not assimilated the need to switch logging systems.

Hani is not sure why "Simple" differs from System.err.println(). There are few reasons. "Simple" only prints messages for levels INFO or higher. Its output also contains more information than what System.err.println() provides. Most importantly, "Simple" is just one implementation of SLF4J API. You could switch to a different implementation in a matter of seconds.

According to Hani, "SimpleLog" looks sane probably because it's not produced by yours truly. I'll let you be the judge of that assertion.

LogBack: Seems to promise much, complex and big, but development seems to have stalled. Written by....yep, you guessed it.

Big, complex, development stalled? Hani's ability to slap qualifiers on software is mystifying, especially on software he has never seen. It's like pretending to have test-driven next year's car before it is out. Trust Hani to tell you all about the 2007 models a year before everyone else.

x4juli: A port of log4j to jdk14 API. Why anyone would use slf4j api backed by x4juli which is backed by jdk14 logging instead of jdk14 logging is a mystery that I suspect no one will ever solve.

Borris Unkel offers a reasonable rebuttal on this claim. Boris is assuming that Hani actually had the courtesy to learn about what x4juli does, which I suspect was not the case.

It's also often unclear with what needs to be deployed. In some cases you need two jars (the slf4j api and the impl), in some cases the impl contains the api.

Admittedly, this is a valid observation. For the sake of consistency, it might be better to have the API and the implementation in separate jar files, at least for the non-trivial implementations. Point well-taken.

In short, do yourself a favor and avoid this stuff. Stick to log4j and you will avert much sadness.

That's not an unreasonable advice in stand-alone applications but embedded components cannot afford to impose log4j on host applications.

The emerging pattern from Hani's comments is that he fabricates stories based on his limited understanding of the subject matter under the guise of hand-on experience. Hands on experience with a product comes with using a product for more than 10 seconds, not just casually browsing through its documentation.

Thursday, March 09, 2006

SLF4J 1.0 (final) is finally out

After 11 months of gestation, SLF4J version 1.0 (final) is finally out the door. For those who have not heard of it, SLF4J (Simple Logging Facade for Java) acts as a facade for various logging APIs allowing to the end-user to plug in the desired implementation at deployment time. A gradual migration path away from Jakarta Commons Logging (JCL) is also supported.

SLF4J does not rely on any special class loader machinery. In fact, the binding between SLF4J and a given logging API implementation is performed statically at compile time. Each binding is hardwired to use one and only specific logging API implementation. Thus, SLF4J suffers from none of the class loader problems or memory leaks observed with other approaches.

SLF4J also includes support for Marker objects, a feature which hopefully will be widely used as newer logging systems become available.

Shall we go JDK 1.5?

Alex Karasulu of Apache Directory project recently floated this question in their development mailing lists. The ensuing discussion was open and interesting with many of the critical questions raised quickly and clearly. Certain users were concerned about JDK 1.5 support in Websphere, or lack thereof.
Notwithstanding my personal reservations about generics, JDK 1.5 introduces truly useful language features. The enhanced loop feature makes it much easier to write algorithmic code riddles with various loops. Covariant return types allow for more meaningful factory methods, opening the door for powerful class structures. Type safe enums, varargs and static imports can lead to more elegant code. Even the more controversial generics are not hard to use.

Probably any developer who cares about the design of his (or her) API will want to take advantage of the new JDK 1.5 language features. However, recent reports claim that only 20% of users have switched to JDK 1.5, with 20% still using JDK 1.3, and the remaining 60% JDK 1.4.

During the discussion someone mentioned retroweaver as a way to bridge the language gap. Retroweaver allows classes files compiled with JDK 1.5 to be retrofitted to run under JDK 1.4. The techniques used in bringing about this miracle are nicely described in the tool documentation. As Trustin Lee observed, retrofitting JDK 1.5 language features has no bearing to methods or classes new in JDK 1.5.

Adopting JDK 1.5 language features but not new classes or methods will force the developer to manually check for the use of disallowed methods/classes. We tried a similar approach in log4j with mixed results. Although some developers paid attention to JDK compatibility rules, others did not.

In a nutshell, aiming for JDK 1.4 compatibility while still using JDK 1.5 language features is likely to be messy, especially if the development team is composed of heterogeneous people. Besides, who could blame Apache Directory developers to want to migrate to JDK 1.5 when JDK 1.6 looms just behind the horizon?