cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Hunsberger, Peter" <Peter.Hunsber...@stjude.org>
Subject RE: [SUMMARY] From Woody to Cocoon Forms 1.0
Date Mon, 08 Mar 2004 20:25:08 GMT
Pier Fumagalli <pier@betaversion.org> writes:

<snip/>

> > 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...
 
It's interesting to note that this same problem comes up on EJB related
mailing lists from time to time.  In particular, if you search the JBoss
forums for "versioning"  you'll note two things:

1) some EJB container vendors *may* have implemented versioning for EJB
instances;

2) people want this feature and have proposed ways to do it that have at
least partial buy in.

Really, adding a version attribute to a JNDI lookup isn't a big deal.
Extending a class loader to respect this attribute is a bit more of a
pain, but is it that bad? I'd note that I'd differ from some proposals
in that I'd default to oldest version instead of newest (since that
makes it easier to keep old code running) if no version is specified.  

I've noted the similarities between some of the Cocoon block proposals
and EJB management before.  I'm beginning to suspect that if done right
Cocoon blocks (and other Cocoon features) could replace EJB's for a lot
of what we  do with EJB's: eg, look up classes at run time, pull code
out of remote repositories.  Combined with Avalon pooling etc. and it's
not clear what EJB's really buy you over blocks (we're not doing
container managed persistence).

<snip/>

> > 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 dependencies (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...

If you're working with EJB's it's likely you already have this problem
(and it's not just casting).  It's not unusual to have a data class
loaded by the EJB container that is used in the servlet container.  I
spent a couple of hours just this week figuring out why adding a method
to a data class suddenly resulted in a No Class Def Found; touching the
class had resulted in Jikes building the classes in a different order
and the EJB tree got an instance of the class that previously hadn't
existed.  In our case, Jikes is the only compiler that can resolve
across the different class trees, but it is almost random (depending on
the version of Jikes) as to which classes will end up in what tree (some
newer versions of Jikes do better but then occasionally fail to resolve
the classes at all).

> 
> > 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" :-)
> 

That works until you get two _active_ versions of the same code that
conflict with each other.  Then there may be a real need to run both
versions while the differences get ironed out. Not a big problem with
today's Cocoon community, but if blocks can come from multiple spots and
Cocoon grows it sure would be nice to have a solution...




Mime
View raw message