Java is a popular platform for distributed applications, such as the Web or client/server. The Java platform has many extension for such purposes: applets and servlets for Web applications; Enterprise JavaBeans (EJB) for server components; RMI and CORBA for distributed objects and more.
Jini promotes the concept of a federation of services that collaborate dynamically over a network. |
Jini technology builds on the Java platform and RMI to bring a new vision for distributed applications.
Jini technology
Jini promotes the concept of a federation of services that collaborate dynamically over a network. A service, for Jini, is essentially a Java interface. It is implemented as an RMI object. Therefore, any object could be turned into a service. Some examples of services are printing, controling a remote camera, or an electronic fund transfer.
Jini differs from other distributed architectures, such as RMI or CORBA, because it emphasizes a very dynamic approach. With Jini, as new services are plugged on the network, they immediately become available. For example, when you plug a Jini printer on the network, it is immediately possible to use it from other Jini-enabled devices such as a PC, a PDA, or even a camera.
To the developer, Jini appears as a toolbox that provides core services: how to lookup services on the network, how to download drivers, how to manage transactions, how to handle network failures, how to exchange messages, and more. Jini uses RMI as the underlying communication protocol.
In this article, we will look at two of the most fundamental core services: lookup and discovery.
Lookup
The lookup service allows client and server to find each other. Upon startup, a server registers its services with the lookup service. Clients use the lookup service to locate the services they are interested in. Note that lookup is a Jini service (i.e., an RMI object).
For example, when a Jini-enabled printer is plugged in to the network, it registers itself with the lookup service. A word processor would use lookup to find available printers.
Discovery
There is a chicken-and-egg problem with the lookup service: clients use lookup to find Jini services, but how do they find the lookup service itself? The answer is through the discovery protocol. Discovery is implemented through multicast and unicast requests, as well as multicast announcements.
Multicast request
Servers use the multicast request to locate the lookup service. Upon startup, a Jini server send multicast UDP packets to a well-known port. Multicast packets are received by every station on the local-area network. Lookup services listen on the well-known port and contact the sender, through the unicast protocol introduced in the next section, to request more information. Figure 1 illustrates a multicast request. Note that this only works on a local-area network.
Figure 1: A multicast request.
A multicast request is like shouting in an open room “Is anybody out there?” and waiting until there is an answer.
Unicast request
When the server knows the address of the lookup service, it can send a TCP request. The lookup service replies with an instance of ServiceRegistar — an RMI object. Figure 2 illustrates unicast request.
Figure 2: A unicast request.
Unicast is a permanent connection and is more efficient than multicast. However, unicast only works if one party knows the address of the other. In practice, unicast is used in conjunction with multicast. For example, the lookup service uses unicast to reply to multicast requests. It acquired the address of the server through the multicast request.
Unicast is also helpful when the lookup service is not on the local-area network and could not be reached by multicast. In this case, the user must provide the address of the lookup service.
Multicast announcement
Multicast announcements are used by lookup services to announce their presence on the network when they are first connected. Servers reply with a unicast request. Figure 3 illustrates a multicast announcement.
Figure 3: A multicast announcement.
LookupDiscovery
The discovery protocol is implemented in the Jini class LookupDiscovery. In practice, LookupDiscovery uses both multicast requests and multicast announcements. At startup, LookupDiscovery actively seeks lookup services using multicast requests. When it has found all the lookup services on the network, it switches to passively listening for multicast announcements.
Jini is a toolbox to build distributed applications |
LookupDiscovery sends discovered and discarded events to the application when it finds or loses track of a lookup service. The DoLookupDiscovery application in Listing 1 demonstrates how to use it. It registers as a listener for the discovered events and prints all the lookup services available on the network.
Thread.currentThread<br>().join() |
Listing 1. DoLookupDiscovery.java
import java.rmi.*;
import net.jini.discovery.*;
import net.jini.core.lookup.*;
public class DoLookupDiscovery
{
public static void main(String[] args)
throws Exception
{
System.setSecurityManager(new RMISecurityManager());
LookupDiscovery ld =
new LookupDiscovery(LookupDiscovery.NO_GROUPS);
ld.addDiscoveryListener(new DiscoveryListener()
{
public void discovered(DiscoveryEvent de)
{
try
{
// Invoke getRegistrar() on the
// LookupLocator to perform unicast
// discovery of the lookup service.
ServiceRegistrar[] registrars =
de.getRegistrars();
for(int i = 0;
i < registrars.length;
i++)
System.out.println(
registrars[i].getLocator());
}
catch (Exception e)
{}
}
public void discarded(DiscoveryEvent de)
{
}
});
ld.setGroups(LookupDiscovery.ALL_GROUPS);
Thread.currentThread().join();
}
}
Running the application
The Jini Starter Kit from Sun ships with a default lookup service called reggie. To test this application, you will need to run one or more copies of reggie. DoLookupDiscovery will print the list of available reggie. To compile and run the DoLookupDiscovery, follow these steps:
javac -classpath jini-ext.jar;jini-core.jar DoLookupDiscovery.java
grant {
permission java.security.AllPermission “”, “”;
};
rmid
Warning! This creates a log directory that you must manually delete between calls to rmid.
java -jar c:jini1_0libreggie.jar file:///c:jini1_0reggie-dl.jar
policy.all c:reggie_public public
To invoke a second copy of reggie, you must change the last two parameters, for example:
java -jar c:jini1_0libreggie.jar file:///c:jini1_0libreggie-dl.jar
policy.all c:reggie_second second
Warning! Again the fifth parameter is a log directory that you must manually delete between calls to reggie.
java -classpath c:jini1_0libjini-ext.jar;.
-Djava.security.policy=policy.all DoLookupDiscovery
(Editor’s note: Some lines of code above have been broken for display purposes.)
It will search for lookup services and print them.
To effectively test DoMulticast, you should start several copies of reggie, the lookup service. It is more interesting if you start some instances of reggie before running DoLookupDiscovery and others while DoLookupDiscovery is running. See DoLookupDiscovery dynamically discover new lookup services.
Conclusion
Jini is a toolbox to build distributed applications that dynamically communicate with each other. The discovery protocol allows servers to explore their environment at runtime.
Future articles in Gamelan will show you how to write your own Jini services.
About the author
Benoît Marchal is a software engineer and consultant based in Namur, Belgium. He has been working extensively on Java and XML. He also likes teaching and writing. Ben runs his own consulting company, Pineapplesoft, and can be reached at bmarchal@pineapplesoft.com. His first book, XML by Example will be published by Que at the end of the year.