the cajo project
Free, simple, powerful: Transparent Distributed Computing
Items are the core of cajo functionality
Any remotely accessible object is called an item in terms of this framework. Items can be any type of object, they sometimes derive from the utility class BaseItem. Remotely accessible objects are created from otherwise ordinary objects using the Remote class. Remote takes the object in its constructor, and implements the Invoke interface, which serves to make all of its member object's public methods, including its static ones, remotely callable. The Invoke interface defines only one method:
   Object invoke(String method, Object args);
Remote objects call the invoke method on a remote reference to the object, passing it a method name, and an argument that can either be an object, and object array, or null. The invoke implementation of the Remote class uses the Java reflection mechanism, whereby it finds the public method of its wrapped object matching the name provided in the remote call, accepting arguments of the type, and in the order provided by the caller. (autoboxing of primitive method arguments occurs automatically) If there is a match, it will invoke the corresponding method on the item, and return the result if any, or the exception, if thrown. If no matching method can be found however, in both method name and argument order, the invocation will result in a NoSuchMethodException being thrown at the caller.

Item objects are free to implement any public, in this case meaning remotely callable methods, of any type. The only requirement is that the calling object from a different machine, virtual or physical, must know the item's method signature. This is no different then for local objects, except that clients do not need to know the signature at compile time. This opens a lot of interesting dynamic interaction possiblities. Naturally, there can be no compile time typechecking; all argument and return typechecking will be done at runtime.
Deploying items
An object can be made accessible for remote use in either, or both, of two ways:

The object can be passed to the static bind method of the ItemServer class, along with a name, by which it may be referenced. This allows remote machines to fetch the reference using the getItem method of Remote, by providing the host name and item name. This is called static linking in the context of this framework. By de facto convention, the primary item served by a VM is bound under the name "main". Note: before the first item is remoted, a call to configure network settings should be made to the static config method of the Remote class. It is used to assign specified TCP ports for communication, otherwise the objects will be remoted on anonymous ports. It need only be called once, in the lifetime of the server. It is highly recommended to use port 1198 when the server is accessible from the internet, as this is the cajo world-wide standard port, granted the by the Internet Assigned Numbers Authority.

The remote object reference can be broadcasted to all listening VMs. This technique is covered in the multicast section. This is called dynamic linking, in the context of this framework.
Remote Transparency
When objects have their methods invoked using the static Remote.invoke method, the calling object need not know if the object is local or remote. However, if it is important to know the remoteness, or locality of an object reference, it can be tested very simply, in the following way:
   if (foo instanceof RemoteInvoke) {
      // foo is a remote object ...
   } else {
      // foo is a local object ...
   }
This is the sole purpose of the RemoteInvoke interface, testing reference locality, as it is otherwise a bodyless interface.
Base Items
The utility BaseItem class can optionally define a MainThread object, which would be started automatically by the ItemServer, on the binding of the item. This allows an item to perform default processing, independently of its other method invocation threads. Its main thread instance can be accessed via its public member named thread, on which it can be interrupted. In fact, the item's run method should periodically monitor, to check if the thread isInterrupted(), and perform an orderly shutdown. An item can optionally have no main thread. This would be known as an event-driven item; meaning it executes only when called by a client. Note: having multiple clients can cause an Item's public methods to be invoked reentrantly.
Loadable Items
There is a special static bind method in the ItemServer class. It serves a very powerful purpose. It allows one or more items, their related classes, and serialised objects, to be stored into separate jar files. These items can then be loaded, as needed at runtime, by the server JVM. This greatly reduces complexity and maintenance issues associated with a large server design. Just as remote object transparency allows application scaling across multiple VMs; loadable items allows additional scalability between them.
Conclusion
Binding at runtime, combined with loadable items, offers application scalability in two important dimensions as illustrated in this diagramme:

cajo framework scalability

Here remotely accessible objects are represented as red and gray dots. Critical application items can be distributed statically between VMs as needed at server startup. (gray dots) All VMs have the option to load additional items, as needed (red), from a collection of loadable items (blue), at runtime.

In the next section, see how an item can use a proxy item to send some, or a majority of its functionality, even a graphical user interface; to run inside remote client Virtual Machines!

Items are just objects, which can be invoked by both local and remote objects.

© 2004 John Catherino, GNU FDL