A simple demonstration of agents

Agent is a buzzword that's been making the rounds a lot lately. Basically, an agent is a mobile unit of code and data that's shipped around to various machines. The classic example is a server that sends out chunks of data to be computed and then amasses the results into an aggregate. This demonstration doesn't do much that's interesting; it simply adds 10 to an integer value retained on the server. However, it shows the basic framework for implementing agents using RMI. Another interesting aspect is that, rather than using the rmiregistry program as the RMI server, the server object creates its own RMI registry.

There are 4 java classes involved

Agent, which is the java class that's shipped back and forth over the network. Note that this class doesn't use a remote interface; the class itself and its data are serialized and sent to the client.

AgentFactory, which is the remote interface for the AgentFactoryImpl class. This interface is invoked by the client, and the calls are passed to the server via RMI.

AgentFactoryImpl, which is the server-side implementation class. It creates instances of the Agent class and sends them to the client on request, and also accepts instances of the Agent class as arguments and interrogates it for changes to data.

AgentClient, which is the client program. It looks up an instance of the AgentFactory interface on a remote server (well, actually I've hardcoded "localhost" in this example, but really it could point to any remote server you like), calls getAgent() to get an instance of the agent, calls the agent's compute() method to perform whatever calculations the agent wants to do (note that the client doesn't have to know exactly what the agent does; it just has to run it), and then sends the updated agent back to the server.

  1. create a directory tom\java\agent somewhere under one of the directories in your classpath
  2. save all the java classes from this page to that directory.
  3. compile the classes -- say "javac *.java"
  4. run rmic on the AgentFactoryImpl class -- say "rmic tom.java.agent.AgentFactoryImpl"
  5. start the server -- say "java tom.java.agent.AgentFactoryImpl"
  6. start the client -- say "java AgentClient"

If you run the client repeatedly, you should see the value of the agent's data field increase

The source
Source for the AgentClient class
Source for the Agent interface
Source for the AgentFactory interface
Source for the AgentFactoryImpl class

Suggestions for enhancements

  1. make the compute function do something useful
  2. Have the client retrieve the Agent from one server and send it to another
  3. Create a generic interface for the Agent class, so that a client can download a generic piece of work, do it, and ship it back to the server without knowing what was in it. (Actually, I originally implemented the example this way, but decided to get rid of the interface to make the point that the class is not being accessed by a remote interface).