cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Brett McLaughlin <>
Subject [Proposal] Shared Objects & Services Architecture
Date Thu, 13 Jan 2000 03:11:40 GMT
Disclaimer: Much of the following proposal is tangential to Cocoon. 
However, because it, similar to Avalon, is ahead of its time, the list
here would seem to be the most logical and receptive group for feedback
and input.

Problem: Applications today are too tightly coupled.  As application
assemblers combine useful components, these components become dependent
on the specific framework they are used within.  In effect, for
components A, B, and C, and framework D, the combination becomes a new
unit, which we will call an application.  This application is completely
proprietary, as is appropriate for any given application.  However, in
the process, components A, B, and C become proprietary as well.  This
means an upgrade to any of these components causes changed in the
framework D, and possible other components.  In addition, any component
E with the same methods as component A should be interchangeable at an
implementation level.  In the situation outlined here, common in many
companies and organizaions, this exchange of components is impossible.

Goal: To design an interface layer, which in turn implements design
patters from Avalon (re: newest versions, including modifications in
James), that provide a loosely coupled architecture for using
components, particularly in regards to the Java Apache and XML Apache
efforts.  This model should be applicable, but not limited, to Apache
Tomcat, Apache Cocoon, Apache Turbine, and the EJB Server being
developed at Exolabs.  In addition, this same model should provide
mechanisms for using common Java services, such as JDBC connection
pooling, JNDI context management, XML-RPC, and other tasks that span
more than a specific component.

Requirements & Assumptions:
    (1) Components in isolation are not necessarily useful.  While
Cocoon serves as a standalone offering, JDBC connection pooling
certainly does not.
    (2) An application developed by an application assembler or
developer will be critical for the combining of components into a
business purpose.
    (3) These application control structures must not be forced to
conform to an API.  For example, a servlet control is not appropriate as
it removes the ability for a component or framework to generate
filtering and piping of the output.  This closely adheres to the
Producer design pattern in Cocoon today.
    (4) Generality should be strived for over specificity.  In other
words, general interfaces with little casting are always preferable over
more specific interfaces causing more casting.  This improves the
ability of disjoint components to remain interchangeable.  For example,
interchanging a JDBC connection pool with a JNDI contexts component.

The Implementation:

	Curiously, the implementation of this proposal involves almost no
non-interface or non-abstract classes.  A loosely coupled framework
should and will allow implementors to add advances as much as they want,
provided the interface definition and the spirit of that definition is
not modified.

Avalon Extensions
	The basic component design should be fueled by the Block pattern in
Avalon.  From this we devise org.apache.?.Component.  Note that we are
using Component to denote both projects (such as the org.apache.*
family) as well as what are traditionally considered application
services.  This is to facilitate the thinning line between those two. 
For example, treatment of a procedure over XML-RPC, traditionally
considered a service, is close to the behavior of treatment of a
function through the Cocoon sitemap.  In both cases, an arbitray input
and output is defined, and the application assembler should not have to
know the intricacies of the interaction.
	For any given component, the component must be able to accept a
singular Object as input and return a singular Object as output.  This
is an additional requirement that originally in Avalon.  This provides
for runtime handling of objects while maintaining a generic interface
across Components.  For example:

package org.apache.?.Component;

import org.apache.avalon.Block;

public interface Component extends Block {

	public void set(Object ob);

	public Object get();


	By providing these accessors and mutators, it is possible to pipe
output from one component into the input of another.  The object being
passed can then be runtime discovered and casted as appropriate.  This
is critical to flexibility in implementation.  Consider a ConnectionPool
component.  The object returned may be a java.sql.Connection.  However,
it may be a java.sql.PooledConnection, or my.package.PooledConnection. 
By not forcing syntax into the interfaces, developers are able to be as
clever in implementation as they choose.  In addition, as I pointed out
earlier, the introduction of proxying from other components, say an
XML-RPC component that behind the scenes handles network communication,
becomes possible without assemblers needing to know the details.
	In addition, some mechanism for execution is needed.  This method
should _never_ require the passing in of additional parameters, and
should always somply return a boolean indicating if it succeeded
(executing, not success as in "login successful").  This allows a
generic execute, and if input is needed, it should be provided via the
set(Object ob) mechanism.  I am still working on my ideas for this, so I
do not include it here.  Certainly the obvious idea is:

  public boolean execute() throws AppException;

Current Cocoon Structures

	As a test bed, we should retrofit existing Cocoon constructs into
Components (Processors, Producers).  Then we use
org.apache.cocoon.Cocoon as a framework, and a producer becomes the
control structure.  This describes our original model.  Interchanging
processors (DCP, SQL, etc.) is a sufficient test.  Additionally,
introducing components that are of neither Processor or Producer flavor
(the JDBC connection pooling requested, for example) will extend our
understanding of this model.  As each component is introduced, at least
two varying implementations should be provided and tested for inclusion
as a new Component implementation, and a successful test of the design.
	I also propose we add a org.apache.cocoon.Sitemap which begins to use
these components.  While this may not initially exactly match the
sitemap proposal, it merges these two ideas.  The ultimate end is that
org.apache.cocoon.Cocoon and org.apache.cocoon.Sitemap can work hand in
hand.  At this point we have reached the maturity for tackling larger
integration efforts with products such as Turbine, etc.

XML/XSP/Data Model

	For each component, sufficient design of interfaces to allow use from
an XSP tag library is required.  This ensures that our components are
not Java-centric, but purpose-centric.  If an XSP page (radically
different in architecture than a servlet) can readily use a given
component, that is significant in the components' evolution.

This is an initial model, partially realized in my mind.  It is based
heavily on Avalon, personal frameworks, and a dissatisfaction with the
time spent to uncouple applications, or force users into _one_ (and only
one) solution.  Right now, Cocoon and Turbine are two good solutions
that are close to mutually exclusive; they certainly do not fit together
well.  My experiences here intergrating the two (and rolling out a
production application on Cocoon and a similar framework) are shown
here.  Certainly it is not foolproof though, and I welcome all feedback.

Have at it, tear it up...


View raw message