commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dennis Lundberg <>
Subject Re: [logging] proposal for JCL2 implementation
Date Sun, 05 Mar 2006 00:11:35 GMT
Simon Kitching wrote:
> Hi All,


Sorry for jumping in late...

While reading through the two JCL design threads an idea struck to me, 
similar to the one you are proposing here. I was thinking in terms of 
having a file bundled in each of the jar 
files. The effect would be the same, but I think your services approach 
is better.

> As you may have seen from the recent commit, I've added some code to
>   proper/logging/contrib/simon/jcl2
> Obviously this is very much work-in-progress; I've committed this really
> to ensure I don't lose the stuff. I intend to do more testing on this
> code to see if it stands up before seriously proposing this as a JCL2
> architecture. However if anyone wishes to provide feedback at this very
> early stage I'd be happy to see it.
> ------------
> Ok, you're still reading?? Well, then, here's the basic concepts.
> This is the result of a idea that suddenly occurred to me. As far as I
> can see, it results in pretty much the same effect as "static binding",
> but needs no compilation or bytecode tricks at all.
> Instead the code is based heavily around the standard "services" pattern
> introduced in java1.3, though it should run on any version, together
> with a few basic packaging rules that must be followed.
> As always in such early code, the code and build process is a bit rough,
> but it does build and run.
> The resulting jars are:
>   core-static.jar:
>     Log  (interface)
>     LogHandler (interface)
>     LogFactory (abstract class)
>     LogFactoryStatic (concrete subclass of LogFactory)
>     Utils (static utility class)
>     META-INF/services/org.apache.commons.logging.LogFactory
>      --> points to LogFactoryStatic
>   core-dynamic.jar: [not yet implemented :-]
>     Log  (interface)
>     LogHandler (interface)
>     LogFactory (abstract class)
>     LogFactoryStatic (concrete subclass of LogFactory)
>     Utils (static utility class)
>     META-INF/services/org.apache.commons.logging.LogFactory
>      --> points to LogFactoryStatic
>   noop.jar:
>     NoOpLog
>     NoOpLogHandler
>     META-INF/services/org.apache.commons.logging.LogHandler
>      --> points to NoOpLogHandler
>   simple.jar
>     SimpleLog
>     SimpleLogHandler
>     META-INF/services/org.apache.commons.logging.LogHandler
>      --> points to SimpleLogHandler
>    etc
> A user would choose one of (core-static, core-dynamic) and then one of
> (noop.jar, simple.jar, log4j.jar, jul.jar, whatever).
> Directory "src/core" contains the traditional Log interface, almost
> unchanged. It also contains a LogFactory abstract class which provides
> the standard getLog(class) and getLog(string) methods; however rather
> than implementing any logic itself it just delegates to an underlying
> concrete subclass of LogFactory. So far, we've talked about all this
> before and I believe hava consensus.
> The interesting bit is the way that LogFactory determines which subclass
> to instantiate and delegate to. It simply looks for file
> "META-INF/services/org.apache.commons.logging.LogFactory" in the way
> recommended for standard java Service Providers. As long as the
> following files are *always* bundled together, I can't see any way to
> get cross-wiring:
>    LogFactory
>    [some LogFactory implementation]
>    [the service file]
> When a classloader is implementing "parent-first", then the LogFactory
> found will not come from classloader X unless there is no such class in
> any ancestor. Therefore when that class looks for the service file and
> the specified implementation it should get the ones out of its own
> jarfile (because they are never found without an accompanying LogFactory
> class).
> When a classloader is implementing "child-first", then when the
> LogFactory looks for the service file and the specified implementation
> then they will be served from the same classloader.
> Note that the lookup NEVER involves the TCCL; we're effectively trying
> to treat the three files above as if they had been "statically merged"
> into a single class so using the TCCL doesn't make sense. 
> I believe the result is that we (and users) can provide variants on the
> core classes simply by bundling the standard UNMODIFIED LogFactory class
> with their own subclass and the appropriate service file to effectively
> bind the two together. This makes the build process much cleaner than
> the other options we were considering; probably even compatible with
> maven2. All we do is duplicate (unmodified) classes
> LogFactory/Log/LogHandler/Utils into each jar that provides a different
> LogFactory concrete implementation.
> The LogFactoryStatic implementation of LogFactory is one that locates
> its log adapter class *without* using the TCCL, ie is suitable for apps,
> applets etc. And it in turn uses the same standard java Service Provider
> approach (META-INF/services) to locate the adapter.
> I've introduced the new interface LogHandler; in the old version the
> LogFactory class was essentially filling two purposes: implementing an
> algorithm for finding a log implementation, and acting as a
> logging-lib-specific factory for Log objects. These really need to be
> separated. For binary compatibility, the abstract class the user
> interacts with really needs to keep the LogFactory name, so I've used a
> new name for the latter role.
> And the resulting classes are much easier for users to understand; we
> don't have classes with the same names but different implementations
> floating around.
> Cheers,
> Simon
> ---------------------------------------------------------------------
> To unsubscribe, e-mail:
> For additional commands, e-mail:

Dennis Lundberg

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

View raw message