directory-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alex Karasulu <aok...@bellsouth.net>
Subject Re: [seda] API & IMPL project/jar consolidation
Date Mon, 20 Sep 2004 04:51:47 GMT
On Sun, 2004-09-19 at 22:06, Niclas Hedhman wrote:
> On Monday 20 September 2004 08:24, Noel J. Bergman wrote:
> > Stephen McConnell wrote:
> > > If I understand correctly you are including a reference to a
> > > version of commons-logging in classes that would not be
> > > isolated behind an api.
> >
> > Commons Logging is intended to be an API.  The implementations are supposed
> > to be decoupled.  If you have issues with how Commons is structured, you
> > should probably raise them (there).
> 
> The problems associated with c-loggings are subtle, but by now well-known.
> http://radio.weblogs.com/0122027/2003/08/15.html
> http://www.qos.ch/logging/thinkAgain.html

Just finished reading these.  Wow I'm so shocked yet again by how much
of a problem this can be.

> You are right that this is not the forum for discussing whether c-logging has 
> the right structure or not, and how it can be improved. BUT it is the right 
> place to discuss whether c-loggings should be used at all.
> 
> Alex has previously proudly declared that the NoLoggingStrategy has been 
> employed, and I shortly wonder why this is not the case any more or for the 
> particular case of SEDA.

Hold up Niclas I' still doing the NoLoggingStrategy thingy!  Yeah I just
happen to have some monitor implementations that use commons logging. 
It does not need to be used as the default.  In fact it is not used as
the default - adapters for monitors are used even for the POJO
implementations.

I just got tired of having so many people complain about too many
projects.  Vince, Alan, Jeff, Trustin have all wanted things to be in a
single jar.  The NoLogging strategy still works even though we have
commons-logging dependent classes here.  These classes are optional
implementations of monitor interfaces for the various components.

Take for example the service interface BufferPool.  It has a monitor
interface called BufferPoolMonitor.  There is a do nothing adapter
BufferPoolMonitorAdapter and there is the optional LoggingPoolMonitor
implementation which depends on commons-logging (CL).  When BufferPool
implementations are created the adapter without deps is used.  The
monitor must be replaced with the CL dependent monitor to impose the CL
dependency.

If the LoggingPoolMonitor is not used, the commons-logging dependency
jar does NOT need to be accessible in any classloader ancestor.  So
we're still cool.  It's a very subtle thing here so its easy to loose
track if you're not in the code the day the conversation comes up :-).

> Furthermore, I urge us to maintain a API, (SPI) & Impl separation for the SEDA 
> package itself, in good IoC manner, which will enable powerful solutions in 
> the future, without any runtime performance hit.

You know I'm getting torn thinking about this over and over again. 
Steve's pretty damn right about his CL strategies.  However people don't
want a gazzillion jars even if he's right.  Noel actually had
recommended making it one project with two possible distros and I
thought about that too.  

Then I just cleared my mind.  I stopped thinking about everyone's
recommendations and just tried to think this through.  Here are some of
the conclusions that I came to:

1). The SEDA framework as a framework is intended to be reused.  Meaning
the plumbing will be shared by all network protocol servers.  The
framework is designed like UNIX xinetd to run multiple services from the
same daemon.  The analogy does not go any further but we reuse the same
frontend plumbing for any protocol that pops up.  So we're going to need
a nice ClassLoader strategy for ourselves for protocol provider
implementations.  Bottom line we don't expect to create a new frontend
instance for every protocol server running in the vm.  

2). Component reuse is not as much of an integral issue nor is component
reuse in other frameworks.  We go the distance to be able to integrate
via wrappers into other frameworks like Avalon but past this we're not
trying to write generic components for other people to use.  We want to
write a SEDA based protocol server framework.  

3). Our goal is to make it as easy as possible for someone to implement
and run their network protocol using our framework.  If that means less
projects and a single distribution jar then we need to rethink breaking
things up.

4). The SEDA framework is not an implementation.  It's an API.  Yes it
contains POJO based implementations of various service interfaces
however these POJO do not need to be used.  Perhaps most importantly
they have no dependencies on anything else - its the optional stuff that
comes packaged that has the deps on CL for example.  I personally
removed deps on commons-lang and commons-codec for this reason and even
forked a handful of useless classes that will disappear by the time we
move to jdk1.5.  Our POJO's have ZERO runtime dependencies.  If you opt
to use the LoggingXxxxxMonitors well then you're introducing the runtime
dep on CL.  That's the user's call not ours.  We just make life easy if
that's what they want to do by putting the optional stuff in the distro
jar.

5). The true implementation jar with respect to a target framework such
as Avalon or Spring, or an app server like Geronimo will be the jar
containing the wrappers around these default POJO implementations. 
These wrappers as you know adapter the POJO to the lifecycles of the
framework and implement the service interface.  It's up to the wrapper
to implement its own monitor or use the one with the CL dependency that
comes out of the box.  We don't force anything upon the implementor. 

As part (b) of 5 consider the wrapper for the BufferPool service in
Avalon Merlin.  We would have a MerlinBufferPool that implements
BufferPool and wraps a DefaultBufferPool member.  Basically all
interface calls on MerlinBufferPool just call the DefaultBufferPool
member.  Simple enough right?  No there is an AvalonBufferPoolMonitor
that comes with the wrapper jar for Merlin.  This BufferPoolMonitor
implementation uses the Avalon Logger to log monitored events.   It
depends on avalon-framework and logkit etcetera.  There is no CL
dependency during runtime since the LoggingBufferPoolMonitor that is
based on CL is never used.  During the life-cycle stages, specially the
LogEnabled stage, the AvalonBufferPoolMonitor is created and set as the
monitor in the DefaultBufferPool in the initialize stage after the
wrapped DefaultBufferPool member has been created.

Does this make sense? I know it was lengthy but I think I have finally
found the middle ground between so many correct viewpoints.

> Bad organization should not be the result of inadequate and hard to maintain 
> build system tools.

After reading my 5 reasons for the consolidation, do you still feel a
single API jar is dangerous for the SEDA framework in terms of the
ClassLoader issues discussion?  

I'm hoping I mentioned a few things that others might not have
considered while making their points clear on this trail.  Most of the
points made were right on and applicable under most situations.  These
subtle 5 points however make this case more than just the standard
situation.  That is why I have chosen this path: one seda.jar as the API
artifact.

Alex




Mime
View raw message