cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Pier Fumagalli <p...@betaversion.org>
Subject Re: [SUMMARY] From Woody to Cocoon Forms 1.0
Date Fri, 05 Mar 2004 23:41:15 GMT
On 5 Mar 2004, at 21:10, Stefano Mazzocchi wrote:

> Tim Larson wrote:
>
>> On Fri, Mar 05, 2004 at 01:24:57PM -0500, Stefano Mazzocchi wrote:
>
>>>  Package: org.apache.cocoon.cforms
>>>
>>> here I would go "forms" instead. package naming is where the estate 
>>> really is, where class collissions might happen.
>> I understand how this seems like a good place for the battleground,
>> but to introduce a new winner it looks like this would force us to
>> break code compiled against the previous major version because we
>> would be stealing the class and interface names for the new version.
>> Does the new block system somehow solve this problem like via
>> classloaders or something else?
>
> eh, very good question, actually. I spent a few hours discussing with 
> Pier about this yesterday over IM. Pier, as usual, sees the very core 
> problem and I always miss ;-)

Heh! :-) No, Ste, it's that I only have to shovel more crap than you 
have to on production environments...

What it means is that I'd rather have a simpler (and more 
understandable) environment to code against, rather than a complete but 
complex one, because when shit happens, I'm going to be the one who has 
to bring our LIVE server up-and-running QUICK! :-P

> The way the JVM classloading mechanism is designed (well, the code 
> verifier actually) is that you cannot have two classes with the same 
> name and package in the same classloading hierarchy.
>
> So, for example, suppose you have the following hierarchy:
>
>     B
>    /
>   A
>    \
>     C
>
> where block A depends on block B and C. Now, if B and C expose the 
> same class, there is no problem if that is accessed from B or from C 
> internally, but as soon as A starts to access it, which one does it 
> get?

Perfectly correct... More in details, A will have an instance of the 
Class object from either B or C linked to the class name. For example 
if both B and C expose the class "org.betaversion.MyClass", the C and B 
classloader will both contain an instance of that class associated with 
that name.

When A receives an instance of "org.betaversion.MyClass" the ByteCode 
Verifier will check it against A's classloader instance of the 
"org.betaversion.MyClass" class object, which he got from either B or 
C.

If the instance of the class object A has is different from the one 
that instantiated the object, well, the BCV will throw a 
ClassCastException

(It might be tricky to understand what's an instance of a Class and 
what's an instance of an Object, if someone has some doubts, ask me, 
please... I had to read the JVM specification 3 or 4 times before 
grasping it)

> So, in short, it is feasible (IMHO, even if I haven't tried yet) to 
> come up with a classloading hierarchy that allows isolation, but only 
> when the semantics associated to the class usage are *really* 
> isolated.

It is absolutely possible, yes... IN THEORY! :-D

It means that if (in the above example), we could analyze all classes 
accessible by A supplied by B and C (which means all public classes), 
analyze their signatures, come up with a list of all the class 
instances which are "visible" from outside, we can safely see whether 
we can (or not) satisfy our versions tree.

In practice (though) this is quite impossible as 99.9% of the classes 
created are always "public" and therefore accessible from the children 
class loaders...

> Note that this seems easy to enforce, but it's really not, especially 
> if you get into block versioning!!!
>
>       X.1
>      /
>     B
>    /
>   A   D
>    \ / \
>     C   E
>      \   \
>       F   X.2
>
> Now, if A asks for a particular task that B executes, requiring 
> version 1 of block X, then asks for another task, executed by C, left 
> to D, which handles to E which requires version 2 of X, then you get a 
> ClassCastException. No way out!
>
> And debugging this is going to be the biggest pain in the universe!!

Not even debugging... Analyzing the dependancies (although possible) 
will be a nightmare...

> So, my suggestion is to create a dependency checker which will tell 
> all the potential class collision conflicts, at deploy time (by 
> crawling the class space, perform MD5 hashing of classes and identify 
> collisions)

You don't even have to have an MD5 :-) Because even if you have the 
SAME EXACT file, if that file is loaded by two different classloaders, 
you won't be able to do a cast operation...

It's a matter of instances of class objects... The instance of the 
class is different, no way you can cast...

> So, in short: having to different versions of the same interface in 
> memory is possible only if there is always a way for the system to 
> differentiate between them. that is: no way to use them both.
>
> Trivial for a few blocks, but very tricky when the number of blocks 
> dependencies explodes.

Ok, I see that it MIGHT be a problem... But it will also be an 
incentive. If I (Pier) write a block, and that relies on a set of other 
blocks, and I CANNOT avoid the problem of "old versions", I will be 
forced to "maintain" my block if I want to use new features...

It basically turns a technical disadvantage into a social advantage. We 
cannot guarantee cross-version compatibility for a particular set of 
block, the community, if the block is "worthy" will make sure that it's 
always up-to-date to the latest standards :-)

If you don't maintain your block, you're out :-) If you're not involved 
with the community, your code will fade away :-) I wouldn't see this as 
a problem! :-)

> This is the best answer I can give at the moment.
>
> Pier, anything to add here?

Yep... That I don't see versioning problems as a problem at all... If 
we don't solve the versioning problem, we'll never have the other 
problem of "uh, I don't know how that block works so I won't fix it or 
update it" :-)

	Pier


Mime
View raw message