The Artima Developer Community
Sponsored Link

Chapter 4 of Inside the Java Virtual Machine
Network Mobility
by Bill Venners

<<  Page 5 of 6  >>

Advertisement

The Jini Service Object: An Example of Network-Mobile Objects

Although the network-mobility of code made possible by Java's architecture and demonstrated by Java applets represented an important step in the evolution of computing models, Java's architecture held one other promise: the network mobility of objects. An object can move across a network as a combination of code, which defines the object's class, plus data that gives a snapshot of the object's state. Where network mobility of code can help simplify the work of systems administrators, network mobility of objects can help simplify the work of software developers designing and deploying distributed systems. Through object serialization and Remote Method Invocation (RMI), the Java API supplies a distributed object model that extends Java's local object model beyond the boundaries of the Java virtual machine. The distributed object model enables objects in one virtual machine to hold references to objects in other virtual machines, to invoke methods on those remote objects, and to exchange objects between virtual machines as parameters, return values, and exceptions of those method invocations. These capabilities, which are made practical by Java's underlying network-oriented architecture, can simplify the task of designing a distributed system because they in effect bring object-oriented programming to the network.

One technology that takes full advantage of the network mobility of objects made possible by Java's underlying network-friendly architecture, object serialization, and RMI, is Sun's Jini. Jini is a set of protocols and APIs that support the building and deployment of distributed systems that is targeted at the emerging proliferation of diskless embedded devices connected to networks. One particular piece of the Jini architecture, the service object, provides a good illustration of the way in which network-mobility of objects can be useful.

A Jini system is centered on a lookup service in which services register themselves by sending, among other objects, a service object. The service object represents the service to clients. Clients who want to access the service retrieve a copy of the service object from the lookup service and then interact with the service by invoking methods on the service object. The service object is responsible for implementing the service, either locally or by talking across the network to a software process or piece of hardware that implements the service.

What is Jini?

To the Jini way of thinking, the network is made up of "services" that can be used by clients or other services. A service can be anything that sits on the network ready to perform a useful function. Hardware devices, software servers, communications channels -- even human users themselves -- can be services. A Jini-enabled disk drive, for example, could offer a "storage" service. A Jini-enabled printer could offer a "printing" service.

To perform a task, a client enlists the help of services. For example, a client program might upload pictures from the image storage service in a digital camera, download the pictures to a persistent storage service offered by a disk drive, and send a page of thumbnail-sized versions of the images to the printing service of a color printer. In this example, the client program builds a distributed system consisting of itself, the image storage service, the persistent storage service, and the color-printing service. The client and services of this distributed system work together to perform the task: to offload and store images from a digital camera and print out a page of thumbnails.

How Jini Works

Jini provides a runtime infrastructure that enables service providers to offer their services to clients, and enables clients to locate and access services. The runtime infrastructure resides on the network in three places: in lookup services that sit on the network; in the service providers (such as Jini- enabled devices); and in clients. Lookup services are the central organizing mechanism for Jini- based systems. When new services become available on the network, they register themselves with a lookup service. When clients wish to locate a service to assist with some task, they consult a lookup service.

The runtime infrastructure uses one network-level protocol, called discovery, and two object-level protocols, called join and lookup. Discovery enables clients and services to locate lookup services. Join enables a service to register itself in a lookup service. Lookup enables a client to query a lookup service for services that can help the client accomplish its goals.

The Discovery Process

The discovery process begins automatically when a service provider, such as a Jini-enabled disk drive that offers a storage service, is plugged into the network. When a service provider is connected to the network, it broadcasts a presence announcement by dropping a multicast packet onto a well- known port. Included in the presence announcement is an IP address and port number where the service provider can be contacted by a lookup service.

Lookup services monitor the well-known port for presence announcement packets. When a lookup service receives a presence announcement, it opens and inspects the packet. The packet contains information that enables the lookup service to determine whether or not it should contact the sender of the packet. If so, it contacts the sender directly by making a TCP connection to the IP address and port number extracted from the packet. Using RMI, the lookup service sends an object, called a service registrar, across the network to the originator of the packet. The purpose of the service registrar object is to facilitate further communication with the lookup service. By invoking methods on the service registrar object, the sender of the announcement packet can perform join and lookup on the lookup service. In the case of a disk drive, the lookup service would make a TCP connection to the disk drive and would send it a service registrar object, through which the disk drive would then register its storage service via the join process.

The Join Process

Once a service provider has a service registrar object, the end product of discovery, it is ready to do a join -- to become registered in the lookup service. To do a join, the service provider invokes the register() method on the service registrar object, passing as a parameter an object called a service item, a bundle of objects that describe the service. The register() method sends a copy of the service item up to the lookup service, where the service item is stored. Once this has completed, the service provider has finished the join process: its service has become registered in the lookup service.

The service item is a container for several objects, including the object called the service object, which clients can use to interact with the service. The service item can also include any number of attributes, which can be any kind of object. Some potential attributes are icons, classes that provide GUIs for the service, and objects that give more information about the service.

Service objects usually implement one or more interfaces through which clients interact with the service. For example, a lookup service is a Jini service, and its service object is the service registrar. The register() method invoked by service providers during join is declared in the ServiceRegistrar interface, which all service registrar objects implement. Clients and service providers talk to the lookup service through the service registrar object by invoking methods declared in the ServiceRegistrar interface. Likewise, a disk drive would provide a service object that implemented some well-known storage service interface. Clients would look up and interact with the disk drive by this storage service interface.

The Lookup Process

Once a service has registered with a lookup service via the join process, that service is available for use by clients that query that lookup service. To build a distributed system of services that will work together to perform some task, a client must locate and enlist the help of the individual services. To find a service, clients query lookup services via a process called lookup.

To perform a lookup, a client invokes the lookup() method on a service registrar object. (A client, like a service provider, gets a service registrar through the process of discovery, described previously.) The client passes as an argument to lookup() a service template, an object that serves as search criteria for the query. The service template can include a reference to an array of Class objects. These Class objects indicate to the lookup service the Java type (or types) of the service object desired by the client. The service template can also include a service ID, which uniquely identifies a service, and attributes, which must exactly match the attributes uploaded by the service provider in the service item. The service template can also contain wildcards for any of these fields. A wildcard in the service ID field, for example, will match any service ID. The lookup() method sends the service template to the lookup service, which performs the query and sends back zero to many matching service objects. The client gets a reference to the matching service objects as the return value of the lookup() method.

In the general case, a client looks up a service by Java type, usually an interface. For example, if a client needed to use a printer, it would compose a service template that included a Class object for a well-known interface to printer services. All printer services would implement this well-known interface. The lookup service would return a service object (or objects) that implemented this interface. Attributes can be included in the service template to narrow the number of matches for such a type-based search. The client would use the printer service by invoking on the service object methods declared in the well-known printer service interface.

The Benefits of the Service Object

In Jini systems, network-mobile objects fly all over the place. When a client or service performs discovery, for example, it receives a service registrar object from a lookup service. When a service registers itself with a lookup service through the join process, it sends to the lookup service a service item object, which itself is a container of many objects, including attributes and the service object. When a client performs lookup, it sends a service template object, a bundle of objects that serves as a search criteria for the lookup query. If the lookup is successful, the client receives either the service object or the entire service item for the service or services that matched the query.

How do all the objects flying across the network between clients, services, and the lookup service actually make distributed programming easier? In short, Jini's use of network-mobile objects (in particular, the network-mobile service object) raises the level of abstraction for distributed systems programming, effectively turning network programming into object-oriented programming.

Jini's architecture brings object-oriented programming to the network by enabling network services to take advantage of one of the fundamentals of object-oriented programming: the separation of interface and implementation. For example, a service object can grant clients access to the service in many ways. The object can actually represent the entire service, which is downloaded to the client during lookup and then executed locally. Alternatively, the service object can serve merely as a proxy to a remote server. When the client invokes methods on the service object, it sends the requests across the network to the server, which does the real work. The local service object and a remote server could also share the work.

One important consequence of Jini's architecture is that the network protocol used to communicate between a proxy service object and a remote server does not need to be known to the client. As illustrated in Figure 4-2, the network protocol is part of the service's implementation. This protocol is a private matter decided upon by the developer of the service. The client can communicate with the service via this private protocol because the service injects its own service object into the client's address space -- the service object moves across the network from service to client. The injected service object could communicate with a back-end server via RMI, CORBA, DCOM, some home-brewed protocol built on top of sockets and streams, or anything else. The client simply doesn't need to care about network protocols, because it can talk to the well-known interface that the service object implements. The service object takes care of any necessary communication on the network.

Figure 4-2. The client talks to the service through a well-known interface.

Figure 4-2. The client talks to the service through a well-known interface.

Different implementations of the same service interface can use completely different implementation approaches and completely different network protocols. A service can use specialized hardware to fulfill client requests, or it can do all its work in software. Different implementations of a service can be tuned for different environments. In addition, the implementation approach taken by a single service provider can evolve over time. The client can be sure it has a service object that understands the current implementation of the service, because the client receives the service object (by way of the lookup service) from the service provider itself. To the client, a service looks like the well-known interface, regardless of how the service is implemented.

Thus, Jini attempts to raise the level of abstraction for distributed systems programming, from the network protocol level to the object interface level. In the emerging proliferation of embedded devices connected to networks, many pieces of a distributed system may come from different vendors. Jini makes it unnecessary for vendors of devices to agree on low-level network protocols that allow their devices to interact. Instead, vendors will need to agree on high-level Java interfaces through which their devices can interact. Raising the level of discourse, from the network protocol level to the object interface level, will allow vendors to focus more on high-level concepts and less on low-level details. The higher level of discourse made possible by Jini should facilitate the process by which vendors of similar products come to an agreement on how their services will interact with clients.

In addition, Jini's architecture enables software developers to enjoy the benefits of separation of interface and implementation when they develop distributed systems. One such benefit is that well-defined object interfaces can help software developers work together effectively on large distributed systems projects. Similar to the way in which object interfaces define the contract between the parts of any object-oriented program, object interfaces can also serve to clarify the contract between the various members and teams of a large project who are responsible for individual pieces of the program. Another benefit of the separation of interface and implementation is that programmers can use it to reduce the impact of change by minimize coupling. The only point of coupling of a well-designed object is its interface; The implementation of an object can change without affecting code in any other object.

Jini brings the object-oriented benefits resulting from raising the level of abstraction and clearly separating interface from implementation to distributed systems programming by taking advantage of Java's support for network-mobile objects. The network-mobility of objects made possible by the combination of Java's underlying architecture, object serialization, and RMI, and demonstrated by the Jini service object, enables Jini to bring the benefits of object-oriented programming to the network.

<<  Page 5 of 6  >>


Sponsored Links



Google
  Web Artima.com   
Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use