cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Pier Fumagalli <>
Subject Re: Directory structure of blocks
Date Wed, 13 Apr 2005 11:23:46 GMT

On 12 Apr 2005, at 15:46, Stefano Mazzocchi wrote:

> Pier Fumagalli wrote:
>> On 11 Apr 2005, at 15:50, Reinhard Poetz wrote:
>>> Daniel Fagerstrom wrote:
>>>> Ok, I had some remembrance that we had decided to have a particular 
>>>> directory structure on the COBs, but I couldn't find any 
>>>> documentation on that, do you have any link or example?
>>> no. But AFAIK there aren't many rules. Those that I know of are:
>>> Blocks have a block.xml descriptor and a COB-INF directory, that can 
>>> contain a directory "classes" and "lib".
>>> The block's root sitemap (if there exists any) is defined by the 
>>> block.xml.
>>> I don't know why we named it "COB-INF" but there was (still is?) a 
>>> good reason for this because I remember some long discussion. Apart 
>>> from this I'm not sure where to put "block.xml". In analogy to WAR 
>>> files it should be "COB-INF/block.xml".
>>> If the reasons for COB-INF vanished in the meantime, I propose 
>>> following directory structure:
>>> --------------------------------------------------------------
>>> [cocoon block] [DIR]
>>>  |
>>>  +-- BLOCK-INF [DIR]
>>>       +-- block.xml
>>>       +-- classes [DIR]
>>>       +-- lib [DIR]
>>> --------------------------------------------------------------
>>> WDYT?
>> Again, to sound stupid, but why in the world a cocoon block would 
>> contain classes and libraries?
> A block defines both services (thru its sitemap) and components (thru 
> the classloader).
> Presence of either is optional. If a block has only classes and 
> libraries (or files in the class paths), it only works as a component 
> provider.
> If it has only a sitemap, it will require components from another 
> block.
> If it has both, it can expose services that use its own components and 
> expose these components to the outside.
> The 'components' to expose will be declared in the block descriptor, 
> this allows us to avoid 'public' classes of the libraries shipped with 
> the block to be misconsidered as components.
>> Those should be external "components" _required_ by the block, 
>> right???
> see above: blocks brings components with them.
> Also note that an 'interface' block is very likely to contain the 
> component interfaces (and the remaining classes that these interfaces 
> need to function).
> So, for the sitemap, the block interface is just a URI, but for the 
> component part, the block interface *contains* the interfaces.
> this will require some more complex build systems as even compile time 
> will require discovery and installation of components (this is the 
> same problem that Merlin had and solved with Magic).

Ok, here is where I don't agree...

By adding to blocks the capability of "bringing components" with them, 
we enter a quite big minefield, imposed by the restrictions of the Java 
VM. The complexity escalates at this point as now blocks must be aware 
of their class-loading mechanism, and the component manager must be 
aware of blocks and interfaces.

For example, classes and libraries included in an interface block must 
be loaded by the parent ClassLoader of the blocks using (implementing, 
extending, requiring) them to avoid ClassCastException(s).

So, alongside blocks and their deployment graph (block A extends B, 
implements C, ... blabla ...) we need to start keep tracking also the 
classes included in those blocks, and create a completely different 
tree based on the class loading structure that those represent.

And then you get into the minefield of versioning... If it's easy to 
determine that two versions of the same block can co-exist (by using 
two separate class loaders children of the same parent) without 
creating too many problems, what happens in the case of two interfaces 
with different versions? The class loading tree should (at this point) 
become very fine-grained and start building multiple class-loaders for 
multiple versions of the same interface, and then build as children of 
those class loaders for the individual blocks "using" them, ...

I can go on for hours.

This, of course, ties in Cocoon with its component manager, and if 
today we're using ECM+++ (great work Carsten), if we ever decide to use 
(or integrate) another container, well, I can see how we'll end up 
having to rewrite 3/4 of the dependancy calculation and object 
instantiation code (which, BTW, works _right now_).

If on the other hand we separate entirely components and java code from 
blocks, the implementation becomes _much_ more easy...

My idea would be that a block (for example, our ForrestSkin 
implementation) _requires_ a component (not a block) that performs XSLT 

Requiring this, it will expose (for example) a "Virtual Transformer" 
called "document2html" which will be implemented as XSLT Transformer + 

Another skin for forrest could (at the same time), implement the same 
interface and provide the same "document2html" transformer by requiring 
the STX transformer and "joining it up" with "document2html.stx".

 From outside, the two blocks _both_ provide a transformer, which does 
exactly the same job, but rely on the component manager underneath to 
solve the class loading problem of providing a component with a given 
role, add their value to it (the XSLT, STX, ... stylesheet) and expose 
it to the users of the implemented interface.

And this frees up the blocks implementation from the underlying 
component management, java, class loaders and so on... I feel this a 
lot more cleaner in terms of separating the concerns of cocoon and 
blocks versus the concerns of the Java platform and its classloading 


View raw message