Chapter 13: Join Manager

Finding a lookup service involves a common series of steps. Subequent interaction with them also involves common steps. A join manager encapulates these into one convenience class for services.

13.1. Join Manager

A service needs to locate lookup services and register the service with them. Locating services can be done using the utility classes of ``Discovery Management''. As each lookup service is discovered, it then needs to be registered, and the lease maintained. The class JoinManager performs all of these tasks. There are two constructors


public class JoinManager {
     public JoinManager(Object obj,
                        Entry[] attrSets,
                        ServiceIDListener callback,
                        DiscoveryManagement discoverMgr,
                        LeaseRenewalManager leaseMgr)    
            throws IOException;

     public JoinManager(Object obj,
                        Entry[] attrSets,
                        ServiceID serviceID,
                        DiscoveryManagement discoverMgr,
                        LeaseRenewalManager leaseMgr)    
            throws IOException;

     public JoinManager(Object obj,
                        Entry[] attrSets,
                        ServiceIDListener callback,
                        DiscoveryManagement discoverMgr,
                        LeaseRenewalManager leaseMgr,
                        Configuration config)    
            throws IOException,
                   ConfigurationException;

     public JoinManager(Object obj,
                        Entry[] attrSets,
                        ServiceID serviceID,
                        DiscoveryManagement discoverMgr,
                        LeaseRenewalManager leaseMgr,
                        Configuration config)    
            throws IOException,
                   ConfigurationException;
}
The first of these is when the service is new and does not have a service id. A ServiceIDListener can be added which can note and save the id. The second form is used when the service already has an id. The other parameters are for the service and its entry attributes, a DiscoveryManagement object to set groups and unicast locators (typically this will be done using a LookupDiscoveryManager) and a lease renewal manager. The third and fourth constructors add a Configuration parameter to the first and second constructors respectively.

The following example uses the first constructor to register a FileClassifierImpl. There is no need for a DiscoveryListener, since the join manager adds itself as a listener and handles the registration with the lookup service. Note that a proxy has to be created using an Exporter, and then the proxy is passed as the first parameter to the JoinManager.


package joinmgr;

import rmi.FileClassifierImpl;

import net.jini.lookup.JoinManager;
import net.jini.core.lookup.ServiceID;
import net.jini.discovery.LookupDiscovery;
import net.jini.core.lookup.ServiceRegistrar;
import java.rmi.RemoteException;
import net.jini.lookup.ServiceIDListener;
import net.jini.lease.LeaseRenewalManager;
import net.jini.discovery.LookupDiscoveryManager;
import net.jini.discovery.DiscoveryEvent;
import net.jini.discovery.DiscoveryListener;
import java.rmi.RMISecurityManager;
import java.rmi.Remote;

import net.jini.config.*; 
import net.jini.export.*; 

/**
 * FileClassifierServer.java
 */

public class FileClassifierServer 
    implements ServiceIDListener {

    // explicit proxy for Jini 2.0
    protected Remote proxy;
    protected FileClassifierImpl impl;
    private static String CONFIG_FILE = "jeri/file_classifier_server.config";
    
    public static void main(String argv[]) {
	new FileClassifierServer();

        // stay around forever
	Object keepAlive = new Object();
	synchronized(keepAlive) {
	    try {
		keepAlive.wait();
	    } catch(InterruptedException e) {
		// do nothing
	    }
	}
    }

    public FileClassifierServer() {
	try {
	    impl = new FileClassifierImpl();


	} catch(Exception e) {
            System.err.println("New impl: " + e.toString());
            System.exit(1);
	}

	String[] configArgs = new String[] {CONFIG_FILE};

	try {
	    // get the configuration (by default a FileConfiguration) 
	    Configuration config = ConfigurationProvider.getInstance(configArgs); 
	    
	    // and use this to construct an exporter
	    Exporter exporter = (Exporter) config.getEntry( "FileClassifierServer", 
							    "exporter", 
							    Exporter.class); 
	    // export an object of this class
	    proxy = exporter.export(impl);
	} catch(Exception e) {
	    System.err.println(e.toString());
	    e.printStackTrace();
	    System.exit(1);
	}

	// install suitable security manager
	System.setSecurityManager(new RMISecurityManager());

	JoinManager joinMgr = null;
	try {
	    LookupDiscoveryManager mgr = 
		new LookupDiscoveryManager(LookupDiscovery.ALL_GROUPS,
					   null,  // unicast locators
					   null); // DiscoveryListener
	    joinMgr = new JoinManager(proxy, // service proxy
				      null,  // attr sets
				      this,  // ServiceIDListener
				      mgr,   // DiscoveryManager
				      new LeaseRenewalManager());
	} catch(Exception e) {
	    e.printStackTrace();
	    System.exit(1);
	}
    }

    public void serviceIDNotify(ServiceID serviceID) {
	// called as a ServiceIDListener
	// Should save the id to permanent storage
	System.out.println("got service ID " + serviceID.toString());
    }
    
} // FileClassifierServer

An Ant build, deploy and run file for this is joinmgr.FileClassifierServer.xml


	
      

There are a number of other methods in JoinManager, which allow one to modify the state of a service registration.

13.2. Summary

A JoinManager can be used by a server to simplify many of the aspects of locating lookup services, registering one or more services and renewing leases for them.

13.3. Copyright

If you found this chapter of value, the full book "Foundations of Jini 2 Programming" is available from APress or Amazon .

This file is Copyright (©) 1999, 2000, 2001, 2003, 2004, 2005 by Jan Newmarch (http://jan.newmarch.name) jan@newmarch.name.

Creative Commons License This work is licensed under a Creative Commons License, the replacement for the earlier Open Content License.