As I'm one of the people who did pick up the "container challenge"
(twice now, first with Avalon, and now with my take on the Cocoon
Kernel), I ought to give an answer...
There are two core problems that "real blocks" are trying to solve, and
both of them are not rocket science.
The first problem is to define a structure for blocks, so that
"agglomerates" of code and/or resources could be accessed not by their
operational aspect, but by an abstraction of their functionality.
The second is to allow each single block to be hot-deployed and
hot-swapped in a container (and this is, right now, the whole big can
of worms).
Issue 1: block structures
-------------------------
Let's start with defining what kinds of block we can have: Interface
and Implementation blocks.
Interface blocks are much like interfaces in Java: no code, only a
skeleton of the functional aspects of all its implementations.
An example of an interface block might be (for example) the "Forrest
Skin" block. This block might be empty, but in itself define that any
block implementing it must contain one (or more) resources which can be
used by Forrest to represent a skin (for example an implementation of
this interface should contain the XSLT for rendering pages, the
furniture images to put on pages, and so on and so forth).
Another example of interface block might be the "Generator" block. This
block should contain the o.a.c.g.Generator interface, and by virtue of
its definition, components generated by this block must implement the
given interface.
So, for example, the FileGenerator block will return instances of
o.a.c.g.FileGenerator which by itself, implements the o.a.c.g.Generator
interface...
Not much new here, right now we rely on java interfaces to do this, we
simply add another layer on top of this one by introducing formal block
definitions which can be parsed and processed and allow us to take the
concept of "interfaces" one step further: interface blocks can
represent (as in Java) code components, or (as in the case of the
"Forrest Skin" block) collections of resources following a certain
standard, or a combination of both...
Easy... It works already on the kernel I wrote, and it's quite a nice
concept (I'm using the kernel in another application, and it's pretty
funky once you get used to it! :-P)
Issue 2: Hot deployment
-----------------------
The second issue that "real blocks" trying to solve is hot swapping and
deployment. What does it mean? Quite simple: if (for example) I want to
change the look-and-feel of my Forrest-generated site, I can "rewire"
the implementation of the "Forrest Skin" block to another
implementation, and VOILA`, my site changes...
And this should be done live, while Cocoon is running.
Now, it's pretty easy to do this when we're talking about resources
(XSLTs and so on) as they don't impact the ClassLoader, but how can we
do it when we're talking about code?
For example, how can we replace (at runtime) Xalan with SAXON? Or how
can we upgrade FOP from 1.2.3 to 1.2.4 without shutting down the whole
of Cocoon?
Again the problem is quite simple, by designing the stack of class
loaders correctly (and not having the whole shabang to use one class
loader), and by using proxy "Wire" instances to manage components
between blocks.
Separate class loaders allow us to reload code, proxy instances allow
us to "isolate" wired blocks from one another so that when a block is
reloaded, a new wire can be independently created and there are no
object references lying around preventing us to garbage collect stuff.
The problems
------------
Now, this all seems quite simple, and partly it is already implemented
on the kernel I wrote.
Now, the problem lies in the fact that before declaring the kernel as
"stable" I wanted to use it for one internal project here at VNU.
Our backend is built entirely on the kernel, it is made up of roughly
20-or-so blocks, but during its development I faced one major issue
that right now I address as "blocker".
I'm talking about event handling: basically, events always require a
two-way linking in the kernel: the event listener must register itself
in the event dispatcher, and the event dispatcher must have an instance
of the listener to send events....
The problem lies when either the listener or the dispatcher gets
reloaded... In theory when this happens the registration should be
re-performed, and the old one interrupted, but this would involve
having blocks to listen to kernel events themselves, and blocks to be
notified of reloads, destructions and so on and so forth... A MESS!!!!
I want to try to solve this problem before calling the kernel API
stable (at least from my point of view), and hopefully I'll have some
time to think about it next week while on vacation...
There is another non trivial problem, which is related to component
selection. This is more tied to Cocoon itself, as I can't find any
other case in which it would happen.
Let's imagine that we have our Cocoon instance with K generators blocks
deployed. At runtime the sitemap processor (which in my view should be
a block in itself) needs to "select" on one of those K generators,
depending on its own configuration (not the configuration of the
kernel).
But (of course) the kernel allows only single wirings, no component
selection at all, blocks are independent and they don't know each
other's existence, and blocks are only given what they require (so, a
block is not aware of all Generator implementations).
Stefano suggested to solve this problem by embedding the kernel itself
in Cocoon, so, to make Cocoon not a "user" of the kernel, but a
"provider" of the kernel to its own blocks...
The sitemap processor, then, would be able to access EVERY single
Generator block deployed, and do its job nicely...
I'm quite positive about this solution, but I would like to explore the
possibility of a different approach...
- - - - - - -
This is more or less the status at the moment, so as you can see, there
is _still_ a lot of stuff to be done and thought of...
I'm using VNU's project as a guinea pig, to figure out all logical bugs
that might lie in the kernel, but as for now, given that ECM and
Fortress seem to be living a new life on their own (God bless the
Apache spirit) those are not all sorted out yet, and the road ahead is
long and unfortunately difficult...
Pier
On 3 Jun 2004, at 06:31, Antonio Gallardo wrote:
> Hi:
>
> I need to accept I am lost in the component containers.
>
> Cocoon is migrating to a new container architecture. The question
> remaining in my mind is: How to develop components right now? In the
> sense
> that we don't want to write components for ECM, because it is almost
> dead.
> How to avoid to rewrite when the new component container in Cocoon will
> raise?
>
> People wanting to write new components now, hope they will be
> deployable
> in the next Cocoon container or with less changes will be full deployed
> outside a legacy container as it was promised. Where is the path to
> that?
> Exists it at all?
>
> I am facing the above question now and I decided to make this post,
> because i think other people have the same problem. Or it is only me?
>
> Need we to wait until the new Cocoon container get life? Am I missing
> something?
>
> The things are even worse: some people suggest Web services as the
> right
> path, others said that Flow with Javascript is a nowhere path. Don't
> miss
> the pressure of EJB vs. lightweight containers, etc.
>
> WDYT?
>
> Best Regards,
>
> Antonio Gallardo
>
>
|