commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From robert burrell donkin <>
Subject Re: [logging] requirements and static binding
Date Wed, 04 May 2005 21:28:03 GMT
On Mon, 2005-05-02 at 22:45 +1200, Simon Kitching wrote:
> On Sun, 2005-05-01 at 11:57 +0100, robert burrell donkin wrote:
> > On Sat, 2005-04-30 at 00:35 +1200, Simon Kitching wrote:
> > 
> > <snip>
> > 
> > > Analysis of the effectiveness of static in the demonstration scenarios:
> > > 
> > > 1-4: static fails, but that's expected. When using the static approach,
> > >    you simply must deploy the static adaptor and the target library
> > >    via the same classloader. I don't see that this causes any
> > >    conflict with the requirements listed above.
> > 
> > this is the whole point :)
> > 
> > with the compile time static approach you have to deploy the libraries
> > correctly. that's the same with dynamic classloading. both static and
> > dynamic approaches work when they are deployed in perfect conditions.
> > the real question is how many of the difficult conditions are also
> > covered. static binding (in theory) covers far fewer of the possible
> > imperfect permutations than dynamic binding could. given an impl jar, it
> > would be possible for dynamic binding to (in theory) cover every case
> > with conventional context classloaders which static binding can and some
> > that static binding cannot.
> What "imperfect" conditions are you referring to here?

the deployment conditions: how the libraries are deployed through the
various classloaders. perfect conditions means that 

> As I said, I *did* feel a little uneasy about how simple the static
> binding approach is. It provides only one way of doing things.
> But on the other hand, it is *predictable*, clearly *bug-free* and as
> far as I can see there is no situation in which it cannot meet the
> requirements.
> There simply *is* no requirement to be able to deploy the static adaptor
> lib via one classloader but deploy the actual logging library via
> another. This isn't something that anyone needs to do.

LOL! i've spent hours and hours trying to persuade users that deployment
configurations are unreasonable. 

> (a) if child-first loading is in operation, then the static adaptor and
> the logging library can both be deployed via WEB-INF/lib.
> (b) if parent-first loading is in operation and no static adaptor is
> present in the parent, then the static adaptor and the logging library
> can both be deployed via WEB-INF/lib.
> (c) if parent-first loading is in operation, and a static adaptor +
> logging library are deployed via the parent, then the webapp has no
> control. If they want control, they should use child-first [see scenario
> (a)].

it's equally easy to come up with a similar simple set of recipes where
the current JCL works well. stick to a set of reasonable deployment
configurations and everything's ok.

the problem is that this isn't what users demand. even ceki came up with
a number of examples in his critique where static calling would not work
but JCL was expected to. he was right that JCL wasn't performing up to
it's theoretic limits and needed fixing but it's unfair to advocate
static binding using examples where static binding fails.

the demonstration indicates that static binding trades reliability for
flexibility: dynamic binding can be made to function in a larger number
of possible permutations. 

> Having looked at SLF4J I'm feeling very unfavourable towards the the
> amount and hairiness of the code present in JCL - and even less
> favourably to making it more complex as recent proposals would do. If we
> can show that there is a reasonable setup where static binding doesn't
> work then fine - but I can't think of one, and the scenarios listed in
> the "demonstration" branch don't show one.

the key part of your proposition is the phrase reasonable setup. this is
pretty much what i meant by perfect deployment conditions. 

static binding has real problems when it is referenced high in a parent
first classloader hierarchy. the particular bridged implementation will
then be fixed for all children. this configuration may be considered
unreasonable by some but it is encountered in the wild.

> > it's all a big circle but hopefully now after this long journey, things
> > can be seen more clearly. we have reached again the original point of
> > departure and disagreement: does having to change your deployment in
> > some cases (by adding log4j to the classloader containing the JCL
> > implementation) count as a fatal flaw or is it simply a pragmatic way of
> > dealing with a difficult corner case?
> Yes, it has been a long journey. But not a wasted one for me anyway; I'm
> now much more aware of what logging needs to do. Sometimes creating a
> simple system requires more knowledge than creating a complex one :-)

don't steal my quotes ;)

> I see selecting child-first classloading for a deployed app as the
> universal, obvious and immediate solution to all the problems. Select
> child-first and deploy your libs from WEB-INF/lib. And in that case
> static binding works fine. The deployer then never needs to change the
> jars in the classpath - the webapp bundles what it wants, and the
> child-first loading policy delivers those.
> What about when a webapp calls a method on an object passed to it by the
> container, and that method logs stuff? Well, in that case there's no
> guarantee that the called object uses JCL anyway, so catching logging
> from such objects really relies upon the container providing
> container-specific hooks to redirect logging. And in that case logging
> calls will end up in webapp-specific code that will statically bind via
> the webapp classloader. So no problem.

ah but it's not just web applications. bricks are used in many different
kinds of application with lots of different kinds. many of these employ

static binding is definitely better for parent-last (mike's new name for
child-first) classloaders. dynamic has definite advantages for parent

> > i like static binding. it's clean and easier to understand than dynamic.
> > for child-first classloaders, the deployment configurations required are
> > much easier. but in a parent-first environment, difficult configurations
> > are required to allow static binding to vary on a per application basis
> > in a container. each approach has different strengths and weaknesses. 
> So let's not support webapp-specific logging libraries accessed via
> wrappers loaded via parent classloaders at all. Tell the idiots
> attempting to do this to just choose the child-first option when
> deploying instead.

that would have been too easy :)

take half a dozen great and famous coders with big egos (and me ;) and
they'll shoot for the stars. i have a feeling that brian might have
proved that they didn't come up too far short...

> Right now, I'm in favour of a JCL 1.1 which keeps the current API, but
> which supports only static binding behind the scenes (ie we ship 1 jar
> per supported logging library). This means ripping out 95% of the code
> and replacing it with the UGLI/SLF4J approach. 
> I'm not so convinced by the UGLI/LOG4J API, and would rather keep the
> existing JCL one for the moment. But there's no reason we can't adopt
> the same binding approach while keeping the JCL api completely binary
> compatible for the vast majority of *callers* of JCL as far as I can
> see. All that "attribute" stuff in LogFactory would probably go,
> breaking any callers that use it - but I suspect no-one does; I've never
> seen any use for it. The getFactory/getInstance methods would also have
> to go, but I don't think people ever use those either.
> So what we would end up with is:
>   commons-logging-nop.jar
>   commons-logging-simple.jar
>   commons-logging-log4j.jar
>   commons-logging-jdk14log.jar
> all of which are extremely small and simple.
> We could of course also ship a "commons-logging-dynamic.jar" which would
> have the existing discovery mechanism intact for people who want it.
> And none of this is irreversible, because we haven't changed the API for
> callers. In the future, JCL can revise its discovery mechanism any time
> it likes, as long as it doesn't change the Log class or the main
> LogFactory.getLog methods.

indeed, i think that we've begun to arrive at the place i've been
wanting to depart from for a long while now. the good news is that this
journey has helped both me personally understand the issues in depth and
the community to bringing together the right people.

my preferred solution for a long term has long been a mixed one:
developing both dynamic and static variants (though i prefer byte code
enhancements but i can see the merit's of ceki's compile time approach).
but this cannot be done with the current LogFactory: it's too complex.
to fix that means lifting off something that can be statically bound.
that's the point of DON_QUIXOTE.

- robert

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

View raw message