[DGD] Java or LPC (DGD)?

Albert Deinbeck albert-deinbeck at albert-deinbeck.de
Thu Aug 14 11:29:27 CEST 2003


Hi all, hi Dworkin,

----- Original Message -----
From: "Felix A. Croes" <felix at dworkin.nl>
To: <dgd at list.imaginary.com>
Sent: Sunday, August 10, 2003 11:58 PM
Subject: RE: [DGD] Java or LPC (DGD)?


> I've looked further into the issue of class reloading for Java.

I've too... :o)
>
> 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.

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

>
> The wrapper class must forward method invocations to the wrapped class
> using the reflection API, passing an array of Object arguments and an
> array of Object field values, returning an Object value.  Done in this
> way, you can't have typechecking for method arguments and return values
> at compile time.  However, you can still have them at runtime with the
> appropriate casts.  The alternative would be to let the wrapper and
> wrapped class both implement the same interface.  This would allow for
> compile-time typechecking, but then the interface is fixed and cannot
> be changed.
>
> Furthermore, since each ClassLoader defines its own class namespace,
> a simulated global object namespace will have to be created which the
> ClassLoaders can use to find wrapped classes to inherit from.
>
> You could create a Java preprocessor which properly translates method
> invocations and field access in normal Java source code, allowing the
> wrapper/wrapped pairs to simulate ordinary Java classes.
>
> 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.

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.

Regards,
Albert


_________________________________________________________________
List config page:  http://list.imaginary.com/mailman/listinfo/dgd



More information about the DGD mailing list