[DGD] Java or LPC (DGD)?
Felix A. Croes
felix at dworkin.nl
Thu Aug 14 16:57:48 CEST 2003
"Albert Deinbeck" <albert-deinbeck at albert-deinbeck.de> wrote:
> From: "Felix A. Croes" <felix at dworkin.nl>
>[...]
> > The only way to accomplish this is to split each class in two: a
> > wrapper class which contains the values, and a wrapped class for
> > the program code which may be updated.
>
> An interesting approach, but of course not the only way. You presume the use
> of standard java serialization, which won't work with modified classes
> because a checksum of the class (i.e. the class bytecode) is saved along
> with the serialized instance.
> You can, however, use another form of serialization, either using the
> externalizable interface or some external serialization library like Java
> Serialization to XML (JSX). The latter would also allow for other programs
> or simple editors to modify the serialized data.
Actually, I was not presuming any sort of serialisation at all -- I was
treating the problem of saving and restoring data for an object as
already solved. I wasn't aware that ordinary Java serialization
includes a checksum for the bytecode -- how silly!
> The wrapper class must create
> > the wrapped class using a private ClassLoader instance. To upgrade
> > the wrapped class, a new ClassLoader instance must also be created.
>
> This is not necessary if you use a compiling classloader which checks every
> time the class is accessed, whether the class file has been modified an
> compiles and reloads the class if necessary. This way, you can use one
> classloader and circumvent the problems described below....
You could get it to work that way by giving each wrapped class a new
private name, every time you recompile it (since the "official" name
is in the simulated global namespace anyhow). Unfortunately, that would
keep the old classes around, no longer used. A memory leak, basically.
>[...]
> > What I previously referred to as "the problem of dependencies" is not
> > generally solvable. Old instances referred to by the thread of
> > execution will continue to exist side by side with new ones, resulting
> > in possible problems until the old instances are no longer used.
>
> This problem is of course solvable. If you have a wrapper class containing
> the real class instance, the wrapper could have a method:
> public void update(){
> store(myObject,fileName);
> myObject = null;
> getClassLoader().loadClass("MyObjectClass");
> myObject = (MyObjectClass) load(fileName);
> }
> where store serializes the class to a file and load unserializes it and
> returns an Object.
This won't work because "myObject = null;" does not actually unload
the object, even if it is the single remaining reference. Java does not
allow recompilation of an already loaded class, and does not have a way
to force unloading of an unreferenced object, other than by unreferencing
the class loader (which is why I suggested using one classloader per
class).
> Interfaces can be very useful in this case, used to define the static
> interface of modifyable classes. If your class is:
> class Living implements LivingInterface { // important Living methods}
> class Living2 implements LivingInterface { // modified Living methods}
> then you can make
> new Living.store("Living.dat");
> new Living2.store("Living2.dat");
> LivingInterface myLiving = (LivingInterface) load("Living.dat");
> LivingInterface myLiving = (LivingInterface) load("Living2.dat");
>
> So myLiving can in effect store different classes transparently.
This is what I myself suggested as an alternative :) But of course,
in a persistent environment interfaces have to be as mutable as
class bytecode.
Regards,
Dworkin
_________________________________________________________________
List config page: http://list.imaginary.com/mailman/listinfo/dgd
More information about the DGD
mailing list