You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by "Inger, Matthew" <In...@Synygy.com> on 2004/05/10 22:35:53 UTC

RE: [logging] eliminate dependencies on commons-logging [was[bean utils] PROPOSAL: eliminate core dependency on collections

Why not a service locator pattern for hooking into the logging
implementations?

Make a commons-logging-api.jar  which has all the core pieces.
Then, say a commons-logging-log4j.jar which has strictly the
log4j classes, a description file, which the LogFactory searches
for at runtime to find implementation classes.

I'd be happy to code this up.


-----Original Message-----
From: Stephen Colebourne [mailto:scolebourne@btopenworld.com]
Sent: Monday, May 10, 2004 4:26 PM
To: Jakarta Commons Developers List
Subject: Re: [logging] eliminate dependencies on commons-logging
[was[beanutils] PROPOSAL: eliminate core dependency on collections


This looks like a very neat solution to the problem to me. The Class.forName
worries me a little though, as I believe that its not too happy in class
loaders.

Stephen

----- Original Message -----
From: "Simon Kitching" <si...@ecnetwork.co.nz>
To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
Sent: Monday, May 10, 2004 6:37 AM
Subject: Re: [logging] eliminate dependencies on commons-logging
[was[beanutils] PROPOSAL: eliminate core dependency on collections


> On Sun, 2004-05-09 at 06:16, matthew.hawthorne wrote:
> > robert burrell donkin wrote:
> > > funnily enough, if commons logging was to be created again, i'd (with
> > > hindsight) consider something along those lines. the bridging
> > > implementations would be in a separate, optional jar and the two
classes
> > > required in the public logging API would be copied over into each
> > > component (as part of the build). if the implementation jar is not
> > > present, error and fatal levels (only) would log to system.err. those
> > > users wanting logging would have to grab and drop in the
implementation
> > > jar.
>
> Doh! Can I vote +2 on this :-)
>
> In fact I liked the idea so much, that attached is a proposed
> implementation.
>
> I suggest that the attached LogSource class, together with o.a.c.l.Log,
> be copied into every project. Of course all the LogFactory.getLog calls
> would need to be changed to LogSource.getLog calls too.
>
> The effect would be that users do not need to download commons-logging
> in order to use the libraries. If they want to enable logging, they just
> place commons-logging.jar in the classpath and then configure it as
> normal. Price: disk space for 1 interface and 1 trivial class, plus a
> trivial performance hit in the getLog method if they do enable logging.
>
> As BeanUtils and Digester are winding up for releases, I would love to
> get this in if people are happy with the idea. And the nice thing is, we
> wouldn't need to wait for a logging release to do this!
>
> The code deliberately discards all logging rather than writing to
> stderr; if output is being generated then there must be a configuration
> system to enable/disable it, which leads back towards commons-logging
> functionality. The point here is to provide something *so* simple that
> it *never* needs to change, and hence it is safe to copy the code into
> multiple places. By discarding log output, we behave exactly as if
> logging had never been used in the first place which I think is
> appropriate for an *optional logging* library.
>
> Note that this code doesn't try to do anything clever with classloaders.
> Any mucking about with context class loader, etc. is handled by
> LogFactory, *not* this class whose responsibility is only to hand off to
> commons-logging or do nothing.
>
> The mechanism Robert suggests for the build (auto copy from the logging
> jar or dir as part of the build) is nice, but the point is that Log and
> LogSource should never need updating, so just committing copies of them
> into the CVS repo for each project should also work, and be simpler.
>
> Does copying of classes sound scary? The comments in the LogSource.java
> file describe why I think this is not a problem. But here's another
> angle on it. If you compile an app with version 1.0.0 of a lib, then try
> to run with a version that has a different binary API, what happens?
> Boom - and you expect it. And if you run with multiple copies of a class
> and they are identical, what happens? Nothing - because they are all the
> same. So a problem only occurs when the ABI is the same, but the
> implementation is different (eg one lib has a bugfixed version, the
> other doesn't). And because LogSource is trivial this shouldn't occur. I
> certainly wouldn't recommend copying the complete commons-logging into
> each project because that code is not trivial.
>
> Question: what about situations where multiple libraries are running
> with different security policies? Might this cause problems when each
> lib contains its own copy of o.a.c.l.Log ? Would this be worse than if
> they didn't have their own copy?
>
> >
> > Here's my opinion on the best approach to logging for each component:
> >
> > Each component creates a simple interface for logging (which could just
> > be a
> > copy of o.a.c.l.Log copied into the components namespace, becoming, for
> > example,
> > o.a.c.beanutils.Log)
> >
> > The component also creates a LogFactory, which checks if commons logging
> > is in
> > the classpath.  If it is, it returns an implementation which delegates
> > to commons-logging.
> > If it isn't, it just sends messages of the appropriate level to
> > system.err (just like robert suggests).
> >
> > This may sound a bit complicated, but it's really not.  To me, this is a
> > good example of how to
> > deal with optional dependencies.  In this example, [beanutils] functions
> > fine without
> > commons-logging, but adding commons-logging to the classpath enhances
> > the logging capabilities.
> >
> > The only problem would be that beanutils would have to invoke the
> > commons-logging methods
> > through reflection, since making the calls directly would result in a
> > compile-time dependency
> > on commons-logging.  This would slow things down a bit.
> >
> > Is this reasonable, or too much work?
>
> Unfortunately, I think the delegation step is just too much overhead.
> The log4j docs describe how much effort they went to to make calls fast
> in the case where the message is not logged. But commons-logging adds
> overhead to every call, and as far as I can see this approach would add
> another level of calls, including **reflection** which has significant
> overheads.
>
> The approach I suggest only uses Method.invoke within the getLog method.
>
> This solution is definitely "cleaner", as it avoids having multiple
> copies of the Log and LogSource class in multiple libraries. However by
> hiding the o.a.c.l.Log interface behing a {component}.Log interface I
> believe this forces indirect invocation (Method.invoke) on every
> debug/info/warn/error call (filtered or not) which seems unacceptable to
> me. If I've misunderstood you, please set me straight..
>
> Maybe a bytecode generation implementation of this idea would work, ie
> have a factory that generates custom classes to bridge between the local
> component's Log interface and the commons-logging Log interface. But
> that's a serious project!
>
> I seem to remember sun introducing a class recently into the std
> libraries which uses bytecode generation to create classes on the fly; I
> think it was intended for use in swing apps to avoid too many anonymous
> inner class declarations. Anyone remember what it was? [I'm not thinking
> of java.lang.reflect.Proxy].
>
>
>
>
>
> I look forward to comments....
>
> Cheers,
>
> Simon
>


----------------------------------------------------------------------------
----


> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [logging] eliminate dependencies on commons-logging [was[bean utils] PROPOSAL: eliminate core dependency on collections

Posted by "matthew.hawthorne" <ma...@apache.org>.
Inger, Matthew wrote:
> Why not a service locator pattern for hooking into the logging
> implementations?
> 
> Make a commons-logging-api.jar  which has all the core pieces.
> Then, say a commons-logging-log4j.jar which has strictly the
> log4j classes, a description file, which the LogFactory searches
> for at runtime to find implementation classes.
> 
> I'd be happy to code this up.

But this solution seems like it would still require a logging jar for 
beanutils, even if a beanutils
user didn't care about logging.  The point of this discussion seems to 
be how to make
commons-logging a truly optional dependency.


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org