Pier Fumagalli wrote:On 13 Apr 2005, at 18:08, Vadim Gritsenko wrote:Pier Fumagalli wrote:
I'm just saying that the concerns are separate: a block provides generators, transformers, serializers, ... to other blocks, but those are de-coupled from the real java components (if any) doing the job.
But *real* blocks, IIUC, *are* the only way to bring new (java) components into the system, because Cocoon core lacks all the optional components, and, at the minimum, consists only of environment, treeprocessor, and block manager.
So in extreme case xslt processor component itself is optional and provided by the xslt real block.
I think that we're mixing again the idea behind a Cocoon block and an Avalon block.
As far as I've understood Cocoon blocks (and I might be _ENTIRELY_ wrong here) Cocoon blocks do not expose (for example) an XSLT Java transformer, but expose a transformer converting a specified format into another.
AFAIU, you are entirely wrong ;)
Ha... I read this differently, then... (Subject: Re: Planning Cocoon's future)
On 23 Nov 2004, at 19:32, Stefano Mazzocchi wrote:
Are there any reasons not to make Pier's kernel the official base of Cocoon 2.3? If not, Pier should have the "permission" to move its kernel into an offical 2.3 directory in our SVN whenever he thinks it's time for it. (... I prepare a vote after the discussion)If the kernel is stable, should it really be 2.3 or can it be 2.2?
my suggestion would be: leave the kernel out and let's keep working on allowing us to deploy and ship the blocks in binary format.
classloading isolation will happen later, when the need will be impossible for people to avoid ;-)
My mishap? Misinterpretation? Or just one of my usual brainfarts??? :-P
considering what have been discussed before. Neither the less, what you propose makes perfect sense to me. My idea was to start implementing the pipline part of the blocks management system, as we IMO understand enough about it to be able to work on that. Then add the possiblity to expose components and take care of class loader issues in a later step.
On this you have my +1... Also because, I've been looking at a little tool called "Maven" :-P That already tells us the dependancies of one particular library against others... By using the (let's assume) "httpclient-x.y.z.jar" from Maven, the maven descriptor file _already_ tells us this "library" dependancies.
We can wrap the library into a "block" (or proto-component), and use the maven descriptor file to calculate dependancies, and use those as instructions to build the classloader structure required by (but separate from) blocks.
After having read your mails I agree that we at least for the time being, should consider component management with classloader isolation, a separate concern. By _assuming_ independence between blocks and component management, anyone who feel the itch can start working on class loader isolation right away. Then we can integrate the component management stuff in the blocks later if we feel the need. And if we don't, we saved ourself from considerable complexity.
I have that itch, and to tell you the truth, the kernel in SVN _already_ does a some level of classloader isolation. Thing is, I use it on a daily basis for an XML repository we have (in house) at VNU, and the more I use it, the more I see the problems of the _current_ approach.
I hit a dead end with the implementation in CVS last week when I wanted to upgrade JAXP from 1.2 to 1.3, running on a 1.4 JVM, but _not_ using the -Djava.endorsed.dirs JVM flag. I can't tell you the issues on trying to isolate the JAXP 1.3 contract and kernel plug-in from the underlying JVM, but with a bit of luck, I found what's wrong, and we should be up and running with the new kernel (here at VNU) in a week-or-so...
--- o0o ---
Ok, taking a look at the technical issues. IIUC, the problem that you describe does not depend on whether a block contains Java classes or libraries or not. The problem appears as soon as a block tries to expose a component. Then the user of the component must have get all the eposed interfaces from its parent classloader. And when we add mutual dependencies between blocks and different versions of the interfaces, it start feeling more like headache than fun.
PRECISELY, you got this spot on...
So let's take a look at some different levels of block issolation, and their properties (the pipeline is exposed in all cases):
1. No component exposing ------------------------
The block doesn't expose any components at all, not even VPCs. The block can still contain as much own Java code as it want. It gets a parent classloader with the core Cocoon functionality and adds it own classes in its own classloader. The block must obviously be compatible with the Cocoon core, but there are no version interdependencies on the Java level between blocks.
It can even expose its classloader to extending blocks without problems. The extending block must of course be compatible at the Java level with the extended one, but still no circular dependencies.
We can package the VPCs as (block) web services (ws) instead with:
VPCReader - Stream -> Stream ws VPCGenerator - Stream -> XML (SAX) ws VPCTransformer - XML -> XML ws VPCSerializer - XML -> Stream ws
by making the block protocol competent enough and introducing pipeline components that talk with the corresponding ws, we get something that works like and is as efficient as VPCs.
And this can be achieved with the running ECM+++ by Carsten, as every sitemap _HAS_ its own classloader. No need to change the underlying implementation until we have a final solution, right?
2. Exposing VPCs only ---------------------
Like the previous alternative but exposing VPCs. If we go for this, Sylvain's proposal about separating VPCs from other componsnts in the sitemap is preferable IMO.
I like this approach, but should be combined with the previous one. ECM+++ already provides isolate class loaders for sitemaps (and therefore blocks). The idea of exposing VPCs only is that an XSLT transformer is nothing without its stylesheet.. A I18N transformer is nothing without its catalog file.
Now, the transformers, serializers, generators, blablabla, EXPOSED by a block must be _full_ components ready to implement a contract saying (for example) transform an XML in the "book.dtd" into a XML in the "xhtml11.dtd". You want to write it in JAva? Native C code? Xalan + XSLT? That's not a problem, but what is exposed is not a class, it is an implementation of the o.a.c.Transformer interface converting "book.dtd" into "xhtml11.dtd".
3. Exposing "sitemap components" only -------------------------------------
In this alternative a block can expose components with interfaces that allready are defined in Cocoon core, or possibly a well defined subset of it. As all blocks gets a common parent classloader that contains these interfaces, we still don't get the "mutual dependency of forign blocks" nightmare.
4. Expose what you choose to ----------------------------
This is, AFAIU, the original block idea. It requires classloader isolation and dependency resolution to work.
5. Expose your classes to everyone ----------------------------------
This is what we do today. All classes/jars from blocks are loaded into a common classloader that is available for everyone. We can combine the idea of having a block aware component manager with a common classloader.
I prefer a combination of 1 and 2 as I said above to 3, 4 and 5 :-P
--- o0o ---
I think we can rule out alternative 5. at once. Its hard enough to get it to work today when we as a community control all the blocks. It was no accident that we choosed to move all libraries to lib/optional. There is no chance that this will scale, when external organizations start to create blocks.
+1 :-P
Alternative 4. would maybe be nice, but as Pier I start to doubt that this is the right level of SoC, pipelines and Java components are quite different levels of abstraction. And it certainly add alot of compleity.
I am glad that my usual broken "brain2email" transformer is producing something comprehensible by others! :-P
I would prefer alternative 1. or possibly 2. Its clean and simple and solve my current needs.
1 AND 2? :-P
--- o0o ---
IMO, we should start simple and add functionality when needed. Remove things is much harder. Also even if we chose to go for alternative 4. an important message from Pier that we should take into account is that component exposure adds complexity. So if we go that way, we should have mechanisms that so that we can have detailed control over what components and classes a block exposes. A block that exposes much will be much more likely to create conflicts with other blocks.
Glad that we have agreement on this! :-D
Pier
