Which Logging Facility for Swing Applications?
Just to give some context, I'm recapping how I've used logging frameworks in my projects so far:
- In the beginning, I used log4j.
- Circa 2001, if I remember well, I started using commons-logging, still configured with log4j. At the time I was mostly doing server-side applications; the limited amount of projects I was doing in Swing probably didn't have logging at all.
- In 2004, I was still using commons-logging, but being more involved in Jini made me more comfortable with java.util.logging.
- Since 2005/2006, I've only been using java.util.logging, partly because I dramatically increased the percentage of my Swing projects, partly because most of the server-side stuff I've been doing recently shares lots of components with my desktop projects.
Since a few months, blueMarine has been using a very simple customized version of java.util.logging: the only new feature is that every method accepts a varargs-style such as in PrintWriter.printf():
Logger logger = Logger.getLogger("name");
int x = ...;
String s = ...;
logger.fine(">>>> x=%d, s=%s", x, s);
Not only this is much more readable than concatenating string literals and variables with the + operator, but it's also faster when the log is disabled. In fact the implementation of the logging methods is encapsulated in a if (...) that tests for the current logging level; this means that string concatenations are only executed when the logging is needed:
public class Logger
private java.util.logging.Logger delegate = ...;
public void fine (String pattern, Object ... args)
In contrast, the direct use of java.util.logging forces passing a single message concatenated with +, which always makes use of string concatenation, even though the result will be thrown away because the related logging level is disabled. That's why, in performance critical sections, people uses to encapsulate java.util.logging in application code including the test for the level as in:
But this style introduces a lot of extra verbosity in code, making it less readable.
I don't like re-inventing the wheel, so my custom logger will be eventually replaced by SLF4J, which - among other things - offers a similar pattern-oriented logging style; furthermore, its pluggable design makes it possible to send the log data to a number of different targets. I'm not doing this immediately only because I have other priorities in blueMarine.
So, from a point of view, I would not be against the use of SLF4J in BetterBeansBinding. The only thing that worries me is that this solution introduces a dependency, while BeansBinding at the moment has got *no* dependencies. Consider that one of the constraints of BBB is to be able to work as a "drop in" replacement for BeansBinding, and with SLF4J you'd need to replace an existing jar file with TWO jar files.
So, I see the following options:
- Use java.util.logging (single jar, but verbose code)
- Copy a customized logger, similar to the one in blueMarine, to BBB (single jar, readable code, but a few classes to cut and paste, and a sensation of NIH).
- Use SLF4J and live with the dependency (multiple jars, readable code, no cut and paste).
- Use SLF4J and deliver a "OneJAR" version of BBB embedding SLF4J classes (sounds as "all pros and no cons").
Solution #4 should be compliant with the BBB and SLF4J licenses (LGPL 2.1 and MIT-like) and it's the one that I like more at the moment, but I have to check. At the moment (1.2.3-SNAPSHOT) BBB has been split in three subcomponents, so the idea of producing a "OneJAR" is already present in BBB - in addition to the capability of releasing a jar for each module, a configuration that could be used e.g. with OSGi, NetBeans Platform and in all cases when strictly replacing the original BeansBinding is not required.