Again, the primary issue with all of this that Javaspaces does not download
code. It does matching, by just having serialized name=value pairs of public
fields. When you "take" or "read" the object from the space, you get a
completely deserialized value. That value can be a bean. It can be anything
you want. The public fields could be declared final.
Things that are passed around a network environment, I believe, should largely
be immutable values in most cases, because they represent some state that
exists, and needs to be transformed into something else that is the "result".
This is, for me, a large part of creating idempotent services. The data that
you pass represents the state that you want to create, not an incremental change
to the state that "might" exist at some point in time.
When writing data content manipulation APIs, I create methods like:
public boolean setXXX( XXX value ) throws RemoteException;
public boolean removeXXX( XXX value ) throws RemoteException;
The use of setXXX() instead of an addXXX() and editXXX() method indicates that
you want this value to be the current value, no matter whether you are editing
or adding. Thus, the implementor is given the responsibility of the existence
check for the addXXX() behavior, and the editXXX() behavior, and the API doesn't
have the confusion of an isXXX() method too!
In a large/many participant environment, I'd expect that Entry objects would
largely be transfer kinds of objects with references to "state" that is (to be)
persisted somewhere. They might contain data, but that data would be immutable
values to use as input to some task.
If you want to use javaspaces to send a mutable object around, and keep changing
its content, you will likely run into the "lost codebase" problem at some point.
The classloaders associated with the varying content of the object, would be
changing on each marshalling task performed by the VM that wrote the object back
into the space. Allowing a client to arbitrarily inject confusing classloading
is the primary battle to try and not fight.
In other words, immutable objects with a single marshall->unmarshall step, are
really the best way to make use of mobile code from my perspective. If you
chain an object around between VMs, you risk that one VM would destroy the
codebase annotations because of its classpath configuration, and you'd lose the
ability to use that object.
As Sean suggested, I too use a factory model for the TO creation step so that
APIs exist for this usage pattern. We also separate DO objects from ACTOR
objects on a regular bases to keep the DO as decoupled from the actors as
possible. This makes the DO usable as a TO in many cases. We use generic decls
on ACTORs with the DO type as well, so that in many cases, we can create actor
instances that act on the TO instead of the DO. This refactoring and broadening
of the codebase into smaller data objects with smaller actors makes for a lot
more flexible system too.
I did do some exploration of looking at this issue with changes to reggie so
that you could get access to the unmarshalled data of a service object. This
would allow you to pass the service definition between VMs so that you could
actually unmarshall and use a service, and then pass a reference to that service
to another JVM as part of making sure they used the same service instance you did.
Also, I misremembered the name of my space project on java.net. I did, call it
jspace on the old jini development site I believe. But it is actually at
http://griddle.dev.java.net now. Too many things to remember.
Gregg Wonderly