(Whoa, I actually understand what you're saying now.. neato..)

> Maybe I wasn't really clear... (since you and rickard seem to miss that
> point) the "nightmare" scenario is a "nightmare scenario" in the parent CL
> case.
>
> It essentially says that "deploying" beans independently is a fallacy...
you
> need to deploy *everyone* at once (except perhaps the last one), because
the
> structure we use today in the container is the parent delegation one and
> that is only done at construction time of the CL, in other words, we can't
> take an already deployed bean and add the parent for that application....
> ALLs CL are still linked to the Applications (in the XML case).  There is
no
> "independent beans assembled independently in the runtime"...

Not so fast....

> I don't know that anyone in the industry has a solution to that problem
> either? but I am wrong? does anyone out there have a solution to the dumbo
> problem?

:-) I think so.

What we need is the "flat CL" you mentioned. And it is possible to do one,
and keep decent classloading semantics. Basically all EAR classloaders would
be regular URLClassLoaders with the system loader (=MLet loader in our case)
as parent. So far so good. Now, how to tie them together? By letting the
application have a "FlatCL" that holds the set of EAR CL's. EAR CL's are
added to the application FlatCL as they are added or removed from the
system. How does the FlatCL work? On loadClass() it:
1) checks its parent CL (=system loader), i.e. normal classloader delegation
2) enumerates the EAR CL's and does loadClass on each of them. If any of
them returns a class, then return that

And now for the last piece of crucial magic:
Then set FlatCL as thread context classloader for the EJB's. Tada. The
FlatCL will be used to, for example, get the classes for instances (=used by
instance pools), but of course the CL attached to any given class will never
be the FlatCL, since it doesn't define any classes at all. It's just a
"spider in the web".

So, now any container can access any class from any EAR in the application
(app=set of EAR's) by simply querying the context classloader. The JNDI
implementation uses the CCL so that'll work just fine too.

The only problem left is: if an EJB instance wants another class, let's say
it does "new Foo" then Foo will be loaded by the URL CL of the EAR it is in.
Hence, it cannot access any classes in other EAR's since the parent of the
URL CL is the system loader and not the FlatCL. So, why is not FlatCL simply
the parent of the EAR URL CL's? Well, since URL CL.loadClass() will delegate
to parent, which then is FlatCL, which will delegate to URL CL set, which
will first delegate to parent which is FlatCL, which will.. etc. etc.

So, that's no good. So this is working kinda well, except for this little
problem. Solvable?

Actually, yes: let each EAR URL CL have a FlatCL as parent, where the FlatCL
has the system loader as parent, and the FlatCL delegates to the set of EAR
CL's in the application *MINUS* the EAR URL CL of the current EAR! Then
there will be no endless loadClass delegation loops, *and* there is
consistent classloading semantics, *and* you can locate all classes in other
EAR's of the application.

Victory.

There's still the little problem that the entire application must be cycled
because of the bean-is-holding-a-reference problem.

Note that not the entire container must be cycled, it is enough that the
caches are cleared and the pools emptied. This is a fairly lightweight
operation and the only drawback is that usage of the container will be
somewhat slow immediately after the clearing (as the caches and pools build
up again). But the clearing itself is pretty fast (HashMap.clear()'s
basically).

Comments?

/Rickard




Reply via email to