commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "V. Karthik Kumar" <>
Subject Re: [logging] JCL2.0 design - API
Date Mon, 20 Feb 2006 10:06:05 GMT

Could we defer the mechanism of classloading to static or dynamic 
loaders, to make it comply with the existing architecture as well? Isn't 
that simpler?

Simon Kitching wrote:
> Hi,
> I'd like to kick off discussions on what a Jakarta Commons Logging 2.x
> release might look like. This thread is on the topic of the JCL API.
> Is the current core JCL api ok, or should we change it?
> == LogFactory as factory for Log instances
> Currently, JCL uses a LogFactory to create Log instances:
>   Log log = LogFactory.getLog("fff");
> By contrast, Log4j has the factory method on the Log class:   
>   Logger log = Logger.getLog("fff");
> Having one less class is a *little* nicer for users I think. However it
> does reduce the flexibility of the system a little and changing this is
> a major difference from JCL 1.x.
> My choice would be: keep LogFactory and LogFactory.getLog as the
> mechanism for obtaining Log instances.
> == LogFactory getAttributeNames/[get|set|remove]Attribute
> Currently, "attributes" can be set on a LogFactory instance. Some
> attributes control the behaviour of the LogFactory class, some are used
> by concrete LogFactory implementations.
> I'd be interested in trying to do away with these methods. I don't
> believe that a logging bridge like JCL should be configurable from the
> application code; that effectively destroys the point of a logging
> bridge.
> == LogFactory.getFactory
> I'd be keen on getting rid of this method completely (at least from the
> public API); I don't see why applications should have any need to access
> the factory instance.
> == LogFactory.getInstance
> Calling LogFactory.getFactory().getInstance(param) is equivalent to
> LogFactory.getLog(param).
> I'd like to do away with the getInstance methods.
> == LogFactory release/releaseAll
> I would tentatively like to keep release, but change its meaning
> somewhat. Currently, it is used to delete any commons-logging-specific
> resources, but not clean up the underlying library. There are corner
> cases where explicitly releasing resources is still necessary so I think
> we need to keep this method. In addition, there are logging libraries
> that really need to be explicitly shut down before app exit; I'd like to
> expand the LogFactory.release method to have that responsibility. That
> would of course need new APIs to the underlying logging-lib-specific
> code.
> I think the releaseAll method should *definitely* go. It's extremely
> dangerous to allow one webapp to release logging resources for all
> webapps. Right now, with JCL in a shared classpath, a call to this
> method can stuff up logging for all webapps in that container.
> == Per-library LogFactory implementation
> Originally, JCL had multiple LogFactory subclasses. In later releases
> things moved to having just one (LogFactoryImpl) which used reflection
> and various other tricks to handle all possible logging
> implementations. 
> I would like to move back to having a separate LogFactory implementation
> per concrete logging library. A bridge to a particular library is
> therefore a (LogFactory, Log) implementation pair. A LogFactory
> implementation that performs "discovery" could be implemented as a
> "decorator" over whatever LogFactory implementation it "discovers".
> == Log class methods
> Log provides *test* methods and *output* methods:
> Log.isDebugEnabled()
> Log.debug(msg)
> Log.debug(msg, throwable)
> I don't see anything wrong with this API, and would like to keep it
> exactly as is.
> SLF4J uses a different approach for the log message. While JCL users
> need to build a string, SLF4j allows parameterised messages:
>   slf4jlog.debug("Event {0} occurred at {1}", eventType, eventPlace);
> This is nice in some ways; the final message string doesn't need to be
> composed until after the logging threshold is tested, so "code guards"
> become unnecessary. However it does mean an ugly set of API declarations
> where java1.5 varargs aren't supported:
>   Log.debug(String template);
>   Log.debug(String template, Object arg1);
>   Log.debug(String template, Object arg1, Object arg2);
>   Log.debug(String template, Object arg1, Object arg2, Object arg3);
> A variant like this:
>   Log.debug(String template, Object[] args);
> is possible, but the creating and building of an Object[] parameter
> probably means a "code guard" is now needed anyway.
> And finally, all this is *different* from the existing 1.x api. I think
> any benefits are marginal, and so would prefer to just stay with the
> existing API.
> Note that there is a bytecode-modification tool that can be run on code
> to automatically insert the necessary JCL code guards into .class files
> anyway, so they don't need to be explicitly present in the source if
> people prefer not to.
> == Package name
> Currently, JCL code is in "org.apache.commons.logging". Should we keep
> this package name for JCL2 or use something like
> "org.apache.commons.logging2"?
> For the digester2 project I've been fiddling with, I've been convinced
> that "o.a.c.digester2" is the appropriate package name, because the API
> has significant changes; the new code is nowhere near a "drop in
> replacement" for the prior version.
> However in this case, if we agree to keep the Log API intact, and only
> remove rarely-used methods from the LogFactory interface then the result
> will be that 99% or more of existing code that uses JCL1.x could use
> JCL2.x without even needing recompilation. I'd therefore suggest that we
> keep the same package name.
> == Final Notes
> One alternative to removing methods from the LogFactory interface is
> instead to define them as no-ops, or to have them throw
> UnsupportedOperationException. The cost is some extra baggage, but we
> could put clear comments saying that all implementations of LogFactory
> should simply ignore the method. It might be worth doing this for the
> sake of backwards compatibility...
> Cheers,
> Simon

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message