On Thu, Mar 04, 2004 at 03:33:53PM +0100, Tim Plessers wrote:
> Hi Graham,
> Thanks for your quick reply.
> I looked into that mailinglist archive thread you suggested.
The current implementation in 2.0 b1 was a hack just to get something working.
It, as I think you saw, simply loads the classes in the system classloader.
This causes two problems: first, it's a security problem in some environments,
and second, no classloader will ever load a class twice.
If you look at how BeanShell implements its own classloaders for
setClassPath(), addClassPath() and reloadClasses() you'll see on example of
what can be done to work around this in the future.
What you have to do is load classes through a classloader that can be "thrown
away" when you want to load a new version.
So, one possibility would be to have our own classloader either load BeanShell
and everything it uses or possibly work with a context classloader that does
this. The bootstrap app has to have a few interfaces - whatever it needs to
interact with the interpreter - pulled out to its level and shared with the
child classloader. Then when you want to execute the script again you can
simply throw away the child classloader and create a new one.
Object instances created via classes defined in the old (tossed) classloader
can still hang around, and we can still use them because they stll implement
the common interfaces... They will simply prevent the classloader object
itself from being garbage collected.
The difficulty is in sharing the common interfaces with the parent. We'll have
to factor out an interface for the interpreter.
Alternately, we might be able to simply set our own context classloader in
BeanShell... as was discussed for the EJB environment a few weeks ago (some of
that thread might have been lost from the archive while sf.net was down).
In that case, we can add or redefine classes by wrapping any existing context
classloader with a new child... The child simply points to the next one in the
chain as its parent. And unlike a normal classloader, ours would not delegate
to the parent first (See BshClassLoader for an example).
There may be other options as well. I haven't really looked at it yet.
For example, we might simply create our own namespaces for the classes by
giving them internally unique names... As long as the interpreter knows what
the real names are it will look fine to the script... but we can always change
our mind and regenerate the classes with new names behind the scenes... To the
outside world the Impl names shouldn't matter, because they have to be using
them through a shared interface anyway...
Sorry if this is not helpful... but the point was that we have options to
address this in the future. And you might try loading bsh and your app through
a URLClassLoader that can be thrown away to test this in the interum.