Java Interface to the Spread Toolkit

This document gives a general overview of how to use this library. For more specific information on classes and methods, see the javadoc-generated documentation. This gives more in-depth information on each method call and the uses of each class.

javadoc-generated documentation

Writing Spread applications in Java is as simple and easy as writing Spread applications in C, but with the added benefits of the Java language. All of the functionality of the C interface to Spread is available when developing in Java, with some extra tools and utilities. The Spread library consists of one package, "spread", which contains ten classes. The main classes are SpreadConnection, which represents a connection to a deamon, SpreadGroup which represents a spread group, and SpreadMessage, which represents a message that is either being sent or being received with spread.

  • Getting Started
  • Connecting/Disconnecting
  • Joining/Leaving
  • Multicasting
  • Receiving
  • MessageFactory
  • Listeners
  • Exceptions
  • Applets
  • Samples

    Getting Started

    The Spread package is contained in a file, "spread.jar". To use Spread from a Java application, this file should be in your classpath. For Java 1.1, this is done by making sure the directory containing spread.jar is in the CLASSPATH enviornment variable. For Java2 this is done by using the "-classpath" option on the command line when compiling or running any classes that user Spread. For applets, simply put spread.jar in the same directory as the applet class. To access the Spread classes from any classes you write, simply include the following line at the top of the .java file:

    import spread.*;

    Connecting/Disconnecting

    To establish a connection to a spread daemon, use the SpreadConnection class. First, create a new SpreadConnection object, then use the connect() method to make a connection to a daemon:

    SpreadConnection connection = new SpreadConnection();
    connection.connect(InetAddress.getByName("daemon.address.com"), 0, "privatename", false, false);

    The first argument to connect() is an InetAddress, which is a class in the package java.net. The static method InetAddress.getByName() takes one argument, a String object specifying an Internet address, and returns an InetAddress object representing that address. The address can be passed either by name or by IP (A.B.C.D). Alternatively, if null is passed as the first argument to connect(), an attempt will be made to connect to a daemon on the localhost. The second argument to connect() is the port to connect to. If this is 0, the default port (4803) will be used.
    This connection can be used until the disconnect() method is called, which terminates the connection to the daemon.

    connection.disconnect();

    Aside from adding and removing listeners, no methods should be called on a SpreadConnection before connect() is called.

    Joining/Leaving

    To join a group on the connection, use the SpreadGroup class. First, create a new SpreadGroup object, then use the join() method to join a group:

    SpreadGroup group = new SpreadGroup();
    group.join(connection, "group");

    The first argument to join() is the SpreadConnection on which the group is joined. This must be specified so that Spread knows which connection messages should be received on. The second argument is the name of the group to join.
    Messages multicast to the group will be received on the connection until the leave() method is called.

    group.leave();

    Multicasting

    To multicast a message to one or more groups, use the SpreadMessage class. First, create a new SpreadMessage object:

    SpreadMessage message = new SpreadMessage();

    This creates a new outgoing message. Next, the message data, the groups the message is going to, and the type of delivery requested should be set:

    message.setData(data);
    message.addGroup("group");
    message.setReliable();

    The setData() method sets the message's data to an array of bytes. Alternatives to setData() are setObject() and digest(), each of which takes an object that implements the Serializable interface. setObject() is used for sending one Java object, while repeatedly calling digest() can be used to send multiple objects in one message. The addGroup() method is used to specify a group to send the message to. The setReliable() is used to set the delivery method. Possible delivery methods are: unreliable, reliable, fifo, causal, agreed, and safe. The setSelfDiscard() method can be used to specify that this message should not be sent back to the user who is sending it. To actually send the message, use SpreadConnection's multicast() method:

    connection.multicast(message);

    Receiving

    To receive a message, use SpreadConnection's receive() method.

    SpreadMessage message = connection.receive();

    receive() will block until a message is available. When one is ready to be received, the message will be read and placed into a new SpreadMessage object which is returned by receive().
    The isRegular() method can be used to check if the message is a regular message. Otherwise, it is a membership message. Membership messages will only be received if they are request by passing true as the final arguement to SpreadConnection's connect() method. If the message is a regular message, the get*() methods in SpreadMessage will provide more information about the message. If the message is a membership message, the getMembershipInfo() method can be used to return a MembershipInfo object, which provides information about the membership change.

    if(message.isRegular())
        System.out.println("New message from " + message.getSender());
    else
        System.out.println("New membership message from " + message.getMembershipInfo().getGroup());

    MessageFactory

    The MessageFactory class is a utility included with the Java interface to Spread. An object of the MessageFactory class is used to generate any number of outgoing messages based on a default message. To use a message factory, create a MessageFactory object, passing the default message to the constructor.

    messageFactory = new MessageFactory(message);

    To change the default at a later time, use the setDefault() method:

    messageFactory.setDefault(message);

    To get a message from the message factory, use the createMessage() method:

    SpreadMessage message = messageFactory.createMessage();

    This will create a clone of the default message. Message factories with more complex behavior can be created by extending the MessageFactory class. One example is a message factory that sets the message's data to the current system time:

    public class TimeStampMessageFactory extends MessageFactory
    {
        public SpreadMessage createMessage()
        {
            SpreadMessage message = super.createMessage();
            message.setObject(new Long(System.currentTimeMillis()));
            return message;
        }
    }

    Listeners

    In addition to using SpreadConnection's receive() method, there is another way to receive messages. This is by the use of two interfaces: BasicMessageListener and AdvancedMessageListener. To use a listener, first implement one of these two interfaces. Then add an instance of your implementation to a connection with one of SpreadConnection's add() methods:

    connection.add(listener);

    After being added to a connection, the listener will be alerted whenever a new message is received on the connection. BasicMessageListener's have one callback method, messageReceived(), which is called whenever a new message arrives. AdvancedMessageListener's have two callback methods: regularMessageReceived() is called whenever a regular message arrives, and membershipMessageReceived() is called when a membership message arrives. These methods will keep being called until the listener is removed from the connection with one of SpreadConnection's remove() methods:

    connection.remove(listener);

    There can be multiple listeners on a connection at any one time. SpreadConnection's receive() should not be called while the connection has any listeners.

    Exceptions

    When an error occurs in a Spread method, a SpreadException is thrown. One example is if receive() is called on a SpreadConnection() object before connect() is called on that object. Another example is calling leave() on a SpreadGroup object before calling join() on that object. Any method that is declared as throwing a SpreadException must be placed within a try-catch block:

    try
    {
        connection.multicast(message);
    }
    catch(SpreadException e)
    {
        e.printStackTrace();
        System.exit(1);
    }

    If you do not want to handle specific exceptions, but just want to exit with an error whenever a SpreadException is thrown, you can place your main code within one try-catch block:

    public final static void main(String args[])
    {
        try
        {
            ...
        }
        catch(SpreadException e)
        {
            e.printStackTrace();
            System.exit(1);
        }
    }

    More specific exceptions will probably be added at some future point. These exceptions will be extended from SpreadException, so code written to handle SpreadExceptions will also be catch any future exceptions that are added.

    Applets

    When using Java in an applet, there is usually a security manager installed, which restricts what your code is allowed to do. For example, when running an applet in a web browser, the code is not allowed to make Internet connections to any place other than the machine running the web server. So, if Spread is running in an applet, in a web browser, the spread daemon must also be running on the machine running the web server. The following code can be used, in the class that extends Applet, to get an InetAddress object for the machine running the web server:

    InetAddress host = InetAddress.getByName(getCodeBase().getHost());

    Samples

    Two sample java applications are included with the Spread interface for Java. User is an example of how to write a simple user in Java. It is similar to the C library sample, user.c. Flooder is an example of a flooder that can help test performance. It is similar to the C library sample, flooder.c.