Hi,
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: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]