Body content restriction

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:

This problem cannot be solved. In Java, classes are identified by their names, not by their definition.

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.

  The Java VM holds all classes in class loaders. Within this class loader, the condition must be true that there is a unique mapping from names to definitions. In other words, there is at most one definition for each name. Each AMETAS Place User has its own class loader, so there is no interference between different Place Users.

What can be used instead?

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.