portmapper
service
is a well-known service that handles RPC calls on a standard port
Internally a client will look like
prepare for discovery
|
discover a lookup service
|
prepare a template for lookup search
|
lookup a service
|
call the service
|
prepare for discovery
|
discover a lookup service
|
create information about a service
|
export a service
|
renew leasing periodically
|
Entry
public interface Entry {}
Address
Comment
Name
ServiceInfo
Entry[] entries = new Entry[] {new Comment("best toaster made"),
new Name("Classy Toaster")};
Converter
service
package jini;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Converter extends Remote {
public float inchToMM(float value) throws RemoteException;
public float mmToInch(float value) throws RemoteException;
};
package jini;
public class ConverterImpl implements Converter {
public float inchToMM(float value) {
return value * 25.4f;
}
public float mmToInch(float value) {
return value / 25.4f;
}
};
package jini;
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.jeri.BasicJeriExporter;
import net.jini.jeri.BasicILFactory;
import net.jini.jeri.tcp.TcpServerEndpoint;
import net.jini.export.*;
public class Server {
// explicit proxy for Jini 2.0
protected Remote proxy;
protected ConverterImpl impl;
public static void main(String argv[]) throws Exception {
Server server = new Server();
// stay around forever
Object keepAlive = new Object();
synchronized(keepAlive) {
keepAlive.wait();
}
}
public Server() throws Exception {
// Create a service object
impl = new ConverterImpl();
// Specify the transport protocol: Jeri over TCP
Exporter exporter =
new BasicJeriExporter(TcpServerEndpoint.getInstance(0),
new BasicILFactory());
// Export the service object. This creates a socket
// endpoint to listen for requests and pass them to
// the service
proxy = exporter.export(impl);
// install suitable security manager to protect
// against downloaded code
System.setSecurityManager(new RMISecurityManager());
// Find LUS's and register the service proxy with them
JoinManager joinMgr = null;
LookupDiscoveryManager mgr =
new LookupDiscoveryManager(LookupDiscovery.ALL_GROUPS,
null, // unicast locators
null); // DiscoveryListener
joinMgr = new JoinManager(proxy, // service proxy
null, // attr sets
(ServiceIDListener) null, // ServiceIDListener
mgr, // DiscoveryManager
new LeaseRenewalManager());
}
} // ConverterServer
package jini;
import java.rmi.RMISecurityManager;
import net.jini.discovery.LookupDiscovery;
import net.jini.core.lookup.ServiceTemplate;
import net.jini.discovery.LookupDiscoveryManager;
import net.jini.lookup.ServiceDiscoveryManager;
import net.jini.core.lookup.ServiceItem;
import net.jini.lease.LeaseRenewalManager;
public class Client {
private static final long WAITFOR = 100000L;
public static void main(String argv[]) {
new Client();
// stay around long enough to receive replies
try {
Thread.currentThread().sleep(2*WAITFOR);
} catch(java.lang.InterruptedException e) {
// do nothing
}
}
public Client() {
// Prepare a service description
Class [] classes = new Class[] {Converter.class};
ServiceTemplate template = new ServiceTemplate(null, classes,
null);
// Try to find an LUS and lookup the service
ServiceDiscoveryManager serviceDiscoveryMgr = null;
System.setSecurityManager(new RMISecurityManager());
try {
LookupDiscoveryManager mgr =
new LookupDiscoveryManager(LookupDiscovery.ALL_GROUPS,
null, // unicast locators
null); // DiscoveryListener
serviceDiscoveryMgr = new ServiceDiscoveryManager(mgr,
new LeaseRenewalManager());
} catch(Exception e) {
e.printStackTrace();
System.exit(1);
}
ServiceItem item = null;
// Try to find the service, blocking till timeout if necessary
try {
item = serviceDiscoveryMgr.lookup(template,
null, // no filter
WAITFOR); // timeout
} catch(Exception e) {
e.printStackTrace();
System.exit(1);
}
// We've either found a service or timed out
if (item == null) {
// couldn't find a service in time
System.out.println("no service");
System.exit(1);
}
// Extract the service from the description
Converter converter = (Converter) item.service;
if (converter == null) {
System.out.println("Converter null");
System.exit(1);
}
// Now we have a suitable service, use it
try {
System.out.println("2 inches is (mm): " +
converter.inchToMM(2.0f));
System.out.println("3000mm is (in): " +
converter.mmToInch(3000f));
} catch(java.rmi.RemoteException e) {
System.err.println(e.toString());
}
System.exit(0);
}
} // Client
reggie
Converter
ConverterImpl
Server
Converter
Client
Converter
ConverterImpl
grant {
permission java.security.AllPermission "", "";
};
grant {
permission net.jini.discovery.DiscoveryPermission "*";
// multicast request address
permission java.net.SocketPermission "224.0.1.85", "connect,accept";
// multicast announcement address
permission java.net.SocketPermission "224.0.1.84", "connect,accept";
// RMI connections
permission java.net.SocketPermission "*.dstc.edu.au:1024-", "connect,accept";
permission java.net.SocketPermission "130.102.176.249:1024-", "connect,accept";
permission java.net.SocketPermission "127.0.0.1:1024-", "connect,accept";
// reading parameters
// like net.jini.discovery.debug!
permission java.util.PropertyPermission "net.jini.discovery.*", "read";
};
grant {
permission net.jini.discovery.DiscoveryPermission "*";
// multicast request address
permission java.net.SocketPermission "224.0.1.85", "connect,accept";
// multicast announcement address
permission java.net.SocketPermission "224.0.1.84", "connect,accept";
// RMI connections
permission java.net.SocketPermission "127.0.0.1:1024-", "connect,accept";
permission java.net.SocketPermission "*.dstc.edu.au:1024-", "connect,accept";
permission java.net.SocketPermission "130.102.176.249:1024-", "connect,accept";
// DANGER
// HTTP connections - this is where external code may come in - careful!!!
permission java.net.SocketPermission "127.0.0.1:80", "connect,accept";
permission java.net.SocketPermission "*.dstc.edu.au:80", "connect,accept";
// reading parameters
// like net.jini.discovery.debug!
permission java.util.PropertyPermission "net.jini.discovery.*", "read";
};
The common classes needed by all of reggie, the clients and servers are
lib
directory.
The command Launch-All
in the Jini installverify
directory will start the needed support services.
The client needs to have the following classes in its CLASSPATH, in addition to the Jini classes
Converter
interface
Client
The client can then be run by
java -Djava.security.policy=policy.all Client
The server needs to have the following classes in its CLASSPATH, in addition to the Jini classes
Converter
interface
Server
ConverterImpl
The server can then be run by
java -Djava.rmi.server.codebase=http://hostname/classes \
-Djava.security.policy=policy.all \
Server
Serializable
and the implementation itself is advertised, then a
copy of the service is run on the client