The message body, consisting of an array of java.lang.Object allows all kinds of
objects to be transmitted by message. However, the objects must be system
classes, and they must be serializable.
This might bring up some protest.
Passing application objects
Certainly, Java programming benefits greatly from the creation of classes. Objects from these classes may contain a bundle of parameters which shall be passed between parts of the program. There are numerous places in the program code, also in AMETAS, where such objects are passed.
Thus, the restriction not to use those classes seems to break with all traditions of object-oriented programming. But when sending objects between agents, we are in a different situation here.
Watch this:
Suppose that agent A transmits an instance of a class called
Complex, representing a complex number, to agent B. Agent
B also knows a class called Complex, but it is used for something
completely different. Using the same class name in different Place Users with different
implementations is actually no problem, but in this case, we would encounter severe problems:
Complex?
Complex,
but with a different meaning?
How else would you like to reference classes in your programs but by their name? If you had to use something like the class digest, program texts would become unreadable.
On the other hand, how could you possibly force all agents from all authors to use one special implementation? This would mean that you ans an implementor must know in advance which classes were already used somewhere. Stupid idea.
What can be used instead?
Integer). But we suggest to use our AMETAS-specific wrappers like AInteger which respect inheritance between numerical types.
Set, Vector, Map etc.
You can use any combination of these and other classes, even create arrays of higher dimension from them. You will not run into trouble as long as you avoid putting an application-specific class into these data structures.
What about the CLASSPATH?
One possible solution is to put all such required classes into the CLASSPATH. What
happens is that your local Java virtual machine gets a collection of application classes to
its set of standard system classes.
That is, you can already answer the question what could happen in the worst case: If you forget
to put these classes into the CLASSPATH of a place where your agent migrates to, it will
crash there.
But you probably don't have access to all of those places, so your agent will not be able to migrate there.
| If you put application-specific classes into the classpath, you must make sure that all places where your application runs (and where your agents might migrate to) also have the same set of classes in their classpath, and - of course - the same versions of classes! |
Why must the objects be serializable, not just cloneable?
Java does not use a deep copy when duplicating arrays. That means that an array of object references yields another array of object references as a clone, but the referred objects are the same. Wondrous things may happen:
The receiver retrieves a message and find a vector in the message body. It gets the vector and adds another entry (it's its own vector, why shouldn't it?). But if this vector was sent to different receivers, they will all observe the vector changing, because only the reference was copied, not the whole vector. And this might happen even deeper in the message, probably in a vector of vectors.
The solution is to serialize the message body. On deserialization, a completely independent copy is created. Yes, it's a heavy performance penalty, but this is the only reliable way of creating a deep copy so far.