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


Attachment: smime.p7s
Description: S/MIME cryptographic signature



Reply via email to