Mobile Code for Network Service Access

James KEMPF <james.kempf@sun.com>
Sun Microsystems Laboratories
USA

Jason GOLDSCHMIDT <jgoldsch@acm.org>
Bucknell University
USA

Abstract

While most work in the area of mobile code networking has focused on the network infrastructure, an equally important area is mobile code for providing clients access to network services. Mobile code for service access allows a client to obtain service drivers exactly when needed, so the client doesn't require the code to be built-in. As a result, the client can be much thinner and always obtains the latest update of the service driver without requiring a client upgrade. The Jini distributed object system provides limited support for mobile service access code. A Java Application Programming Interface (API) and an infrastructure based on the Java Remote Method Execution (RMI) protocol allow services to advertise their driver objects and clients to query for particular services based on the Java class of their service objects and a collection of attributes describing the service. The downloaded code is restricted by the infrastructure to RMI proxy stubs, however, so service drivers supporting arbitrary protocols cannot be advertised. We describe an experiment in replacing the Jini RMI infrastructure with a standard enterprise service discovery system, Service Location Protocol (SLP). The resulting system allows service access drivers supporting arbitrary protocols to be advertised and discovered through the Jini API.

Keywords: mobile code, network service access, Jini, SLP

Contents

1.0 Introduction

Most work to date in mobile code networking has focused on how mobile code can enhance the networking infrastructure. Equally important is how clients access network services. By deploying mobile code for network service access, called service drivers, clients can download code for particular network services when needed, exactly as capsules and mobile code allow routers and other infrastructural elements to download code for processing protocols that were not previously encountered. Client application software interacts with the downloaded network service driver through a standardized programmatic interface defined for the service.

Mobile service drivers have several advantages for clients. While the client application must be programmed to deal with the driver interface, the driver interface is usually defined in a generic manner. Consequently, the client can access many specialized versions of the service, for example, different models of a color printer or even different printing protocols, with the same generic interface. The client does not need the code for all versions of the service because it downloads the code only when needed. In addition, the client never needs to be upgraded when the service access code is upgraded. The latest drivers can be installed on a server or delivered with firmware updates to the service hardware, and clients will obtain the new code the next time they use the service.

The Jini distributed object system [1] provides limited support for mobile code service drivers. A Java API and supporting infrastructure allow clients to locate and install downloaded service driver objects written in the Java language. Because the Jini infrastructure is built on Java RMI, the service driver code to be downloaded is restricted to RMI proxies. As a result, drivers for network services that utilize other system or application protocols cannot be deployed with Jini, for example, a stock quote service that multicasts quotes to clients.

In this paper, we discuss an extension of Jini that enables Jini clients and servers to communicate with any protocol. The Jini API is layered on top of a standard service discovery mechanism, SLP [4]; however, the design could be used equally well with a directory service protocol such as the Lightweight Directory Access Protocol (LDAP) [2] or any other attribute-based directory service or service discovery system. In addition to allowing a broader choice of network protocols, the result simplifies and standardizes the infrastructure required to deploy Jini, and assures better scalability.

2.0 The Jini distributed object system

In concept, the Jini distributed object system is very similar to CORBA or COM. An important difference is that Jini is restricted to the Java language only; hence, it derives power from specific Java language mechanisms like the Java type system. Jini actually covers three broad categories of APIs

  1. Attribute-based discovery of Java objects implementing particular services.
  2. Distributed transaction management.
  3. Tuple-spaces.

In this paper, we are concerned only with the APIs involved in attribute-based discovery.


Figure 1: Jini distributed object system architecture

Figure 1 schematically illustrates how Jini clients discover Jini services. The Jini Lookup Server (LUS) is a network service itself, but it is discovered using one of the proprietary Jini LUS discovery protocols. A Jini service registers a service advertisement with the Jini LUS through the Jini API. A logical name, called a group, is associated with the advertisement, for provisioning access to the service. The advertisement includes the service object, a collection of attribute objects that describe the service, and a lease. The lease determines how long the advertisement is valid. The service must reissue the registration prior to the expiration of the lease because the LUS flushes the advertisement when the lease is up. The RMI daemon (rmid) and the RMI registry (rmiregistry) are required because the LUS and the Jini libraries in the client and server communicate exclusively with RMI.

A Jini client looks up a service object in the LUS by supplying the group name, a collection of attribute objects that describe the service, and the Java class object corresponding to the desired class of the service object or an interface implemented by the service object. A service object in the LUS matches the client's template if the group name, class, and attributes in the template match the corresponding group name, class, and attributes in the advertisement.

In some cases, a client may want to be notified when a service appears or if an existing service changes. Jini supports notifications for this purpose. A client registers a remote listener with the LUS, along with a template describing the advertisements that should trigger the notification. Like service advertisements, notifications are also registered with leases. When an advertisement matching the notification template arrives, the LUS notifies the client of its arrival through the listener. In this way, a client can obtain service drivers when the services appear or change.

The protocols used by Jini for network communication are all specific to Java or proprietary. Jini uses the Java-based remote procedure call protocol RMI for all network communication, with the exception of the initial step in which the client discovers a LUS. A collection of three proprietary protocols are used for discovering the LUS: the Multicast Request Protocol, Multicast Announcement Protocol, and Unicast Discovery Protocol. These protocols play no further role after LUS discovery. The result of discovery is that the client obtains an RMI proxy object for the LUS, an implementation of the ServiceRegistrar interface, which it can use to perform RMI-based Remote Procedure Calls (RPCs) to the LUS to obtain service driver objects.

The LUS and the client library implementing ServiceRegistrar depend exclusively on RMI to transmit distributed objects between the service, the LUS, and the client. Jini depends on the RMI class loader to obtain the stub code for RMI objects. If the object wasn't marshaled as an RMI object, it won't have the Uniform Resource Locator (URL) for the class code. The restriction to RMI also requires the server and client to be implemented in Java. A non-Java server, for example, a legacy print server, could not communicate directly with a Jini client, but rather requires an RMI-based proxy. In addition, RMI and the LUS constitute a particular infrastructure that must be deployed before Jini can be deployed. The infrastructure includes rmid and the rmiregistry in addition to the LUS. This infrastructure may not be available in a particular enterprise network.

These issues prompted exploration of whether the Jini API could be implemented on a standard service discovery or directory service protocol.

3.0 SLP

SLP [3] [5] [7] is a scalable protocol for the discovery of network services. Figure 2 illustrates the SLP architecture. If the number of SAs and UAs increases, the amount of multicast can increase until it becomes a significant fraction of network load. Multicast can be reduced considerably by deploying a cache, called a Directory Agent (DA). When a directory agent is deployed, the SA registers its service advertisements with the DA using unicast (SrvReg/SrvAck), and the UA unicasts its SrvRqst to the DA instead of multicasting it. These transactions are shown in the lower part of the figure. DAs improve the scalability of SLP but deployment of DAs is not required in simple networks.

Service advertisements in SLP consist of a service URL and a collection of attribute tag/value list pairs. The service URL contains a human-readable representation of the class or type of service, called the service type name, along with the host and optional port number of the machine hosting the service, and optionally, any additional information needed for contacting the service. A service advertisement has a lifetime associated with it. When the lifetime expires, the advertisement is flushed.

For example, a print server named printserv.eng offering service using the LPR protocol [8] might look like this:

    service:printer:lpr://printserv.eng/queue1

Here, service:printer:lpr is the service type name and queue1 is the printer queue.

As with all strings in SLP, attribute tags and values are transmitted as UTF-8 [9] text strings. Attribute values have a few simple types inferred from their lexical structure: string, integer, Boolean, and array of bytes, or opaque. Attributes can be single valued or multivalued. The queries submitted by clients for services are formatted as LDAPv3 string filters [10]. An example of a query is the following:

    (&(dpi=600)(color=true)(paper-feed=double-sided))

This example illustrates a client searching for a color printer with 600 dpi resolution and double-sided paper feed. Attributes and values are LDAPv3 compliant, for increased interoperability with LDAP directory servers.


Figure 2: SLP architecture (from [3])

A standardized format for defining SLP service types and service URLs is available [5]. The format is called a service type template. It defines the syntax for the variable part of the service URL, and exactly what attributes a service advertisement is required to have, what attributes are optional, and what the types and required values of the attributes are. The template is used as a standardization mechanism, to ensure that all applications that implement SAs and UAs for the service type are interoperable.

As with Jini groups, SLP supports a provisioning mechanism, called a scope. SAs and DAs can be configured into one or more scopes either through a static configuration or through DHCP [11]. A UA is either configured or dynamically discovers its scopes. A UA dynamically discovers its scopes through either dynamically discovering DAs and using one or more of the scopes supported by the DAs, or, in the absence of any DAs, by dynamically discovering SAs and using the scopes supported by the SAs. In the absence of any scope configuration, all agents use the scope default. There is no requirement that DAs and SAs be configured with a scope, because they can always use the default. SAs and DAs never dynamically discover their scopes, however, because if they have a scope other than the default, the scope must be fixed so UAs can always be properly provisioned.

The major infrastructural differences between SLP and Jini is the reduction in the infrastructure required for SLP. An SLP network consisting of a service client and service provider can operate with no other infrastructure. The deployment of DAs serves as a scaling mechanism, allowing SLP to cover large intranets with many thousands or hundreds of thousands of hosts, but is not necessary. Jini, on the other hand, requires the deployment of the LUS, RMI daemon, and RMI registry. In addition, SLP is a language-independent protocol, while the underlying Jini protocols are either proprietary or tied very closely to Java. As a result, SLP SAs can be written in C or even assembler, when compact implementation or compatibility with older code are a concern.

A major functionality difference between SLP and Jini is that SLP does not support notification. SLP UAs are required to poll for changes in service advertisements, or the appearance of a newly advertised service, while Jini clients can register a listener to be informed when changes occur. The other differences are relatively minor.

  1. Service advertisements in SLP consist of formatted strings, while service advertisements in Jini consist of service driver objects and attribute objects.
  2. Jini queries use object equality for comparing attributes, while SLP queries use logical comparisons of attribute values to values supplied in the query.
  3. There is no a priori support for mobile code in SLP, whereas Jini supports mobile RMI proxy code.
  4. Jini uses the Java type system to identify services while SLP uses string-based service type names.

In the following sections, we discuss solutions to these deficiencies in functionality that allow SLP to support the Jini API.

4.0 SLP subscription/notification service

One of the major tasks in layering the Jini API on top of SLP was designing and implementing a notification system. As discussed above, the SLP model of service discovery involves the UA client actively performing a query to find services. This model works well with applications such as word processors in which the application needs a service to perform a particular task. There is another class of applications in which the application needs to monitor the availability of services and inform the user when a new service appears or an old one changes. An example is a desktop Graphical User Interface (GUI) that displays an icon when a new printer appears. Implementing these kinds of applications with SLP's on-demand model requires the application to poll periodically for new or changed services, an inefficient use of processor and network resources.

The SLP subscription/notification service [12] provides notification to UA clients. As with SLP in general, the subscription/notification service was designed to be scalable from small networks to large enterprise networks. The small network design is relatively simple. When no DAs are deployed in the network, an SA appears and multicasts a SrvReg with its service advertisement to the SLP multicast group address. UAs that are interested in being notified monitor the multicast group address. Because multicast is unreliable, the SA periodically rebroadcasts the SrvReg with its attributes and service URL over a period of 15 seconds. The algorithm is exactly the same as the multicast algorithm used by the UA when it multicasts out a service request [3], except the SA is not expecting a reply. The SA rebroadcasts a SrvReg when attributes are added, and a SrvDereg when attributes are deleted or the SA is about to cease operation. Note that no periodic multicast is performed by the SA beyond the 15-second transmission interval immediately after a state change. Periodic multicasts have been a problem in other service discovery systems because they tend to exert a fixed size load on the network [3]. Because the base SLP was designed to avoid periodic multicasts where possible, the notification extension was designed that way as well.


Figure 3: SLP subscription/notification protocol

As the size of the network increases, the number of UAs and SAs may increase to the point where it becomes inefficient to simply multicast state changes, regardless of whether any UAs are interested. Because DAs are the primary scaling mechanism in an SLP network, the notification design allows DAs to control if SAs perform notification in larger networks. A UA that is interested in obtaining notification about changes in a service type sends its DA a notice of interest, called a subscription. The UA is returned a life time that indicates when the DA will time out the subscription unless the UA renews it. The DA multicasts the subscription information to all existing SAs immediately, and unicasts to all new SAs in the SrvAck reply when they first perform registration. If an SA supports the service type and the attributes match the query in the subscription, the SA performs multicast notification exactly as in the small network model. If the attributes don't match or the SA is of another service type, the SA stays quiet. Figure 3 provides a more detailed time line diagram of the interaction between the UA, SA, and DA in the subscription/notification protocol. As indicated in the figure, the protocol is implemented with extensions to standard SLP messages using the base SLP extension feature.

The protocol is also designed to be robust with respect to the appearance and disappearance of DAs. If the original DA crashes, the SAs continue notifying after the life time has expired if there is no DA available when a state change occurs. If there is a DA, the SAs expire the notification if it isn't renewed. When the UA performs a subscription renewal to a new DA, the new DA informs the SAs, thereby causing notification to continue. The result is no gap in subscription coverage, even if the DA that took the original subscription crashes. An added benefit is that the subscription/notification protocol for large networks is a superset of the notification protocol for small networks, reducing the amount of code in implementations.

5.0 Jini Service Type

As discussed above, SLP and Jini differ in a number of areas involving how the Jini API is implemented. We define a special service type in SLP, the service:jini abstract type, for SLP-enabled services that would like to advertise Jini drivers. This service type includes attributes that allow SLP to implement Java type matching and downloading of driver code.

For SLP to properly support the Jini API, some method is required whereby a client can query for a parent type and receive a driver object implemented as a child class. This allows the client to specify a generic service interface and the server to supply a child class object that is specific to the implementation of the server, as is the case with the RMI-based Jini implementation. Because SLP uses a string-based service type name to identify services, simply equating the Java class name and the service type name is insufficient. Two service type names are equivalent if they are equal as strings, which leaves no room to implement the Java subtype rules.

Java subtyping can be implemented in SLP by using SLP's query handling capability. Because Java type equivalence corresponds to string matching between class names, SLP's string matching capabilities in query handling are sufficient to implement type equivalence. To implement type matching in SLP, an SA that is prepared to offer a Jini service driver must advertise an attribute, called interfaces, that contains the class hierarchy behind the type of the service driver class.

For example, suppose the Model 30 RocketColor printer is advertising a Java printer driver, of type com.rp.RocketPrinterColorModel30. Suppose further that the com.rp.RocketPrinter class contains all common features of the Rocket Printer series, and that all printers are required to implement the net.jini.Printer interface. The interfaces attribute for this advertisement is

    interfaces=net.jini.Printer,
    com.rp.RocketPrinter,
    com.rp.RocketPrinterColorModel30

A client searching for a printer driver formulates the following query:

    (interfaces=net.jini.Printer)

Because at least one value of the multivalued attribute matches the query, the service URL for the Model 30 printer is returned.

Once a client has found a service with the Jini driver, the service advertisement must provide the client with a path to a downloadable service driver. The java-driver-factory attribute provides this information. The client uses SLP to retrieve the value of the java-driver-factory attribute and then uses the URL class loader in Java to download the driver file. An example of the a driver URL for the Model 30 RocketColor printer is the following:

    java-driver-factory=http://printserv.eng/drivers/printerDrivers/M30RocketColor.jar

With the interfaces and java-driver-factory attributes, the service:jini abstract type provides a way for SAs to advertise mobile code service drivers for Jini clients. Abstract types in SLP allow a set of attributes to be associated with a range of concrete implementation types. A concrete type for service:jini contains the Java class name of the service, with the periods in the package name replaced by hyphens. For example, the Model30 RocketColor printer advertises a service URL with the following form:

    service:jini:com-rp-RocketPrintColorModel30://rainbow.eng

The service:jini attributes provide the mechanism for Java type system queries and downloadable code.

6.0 Layering the Jini API on SLP

When the Jini client downloads the jar file from the java-driver-factory URL, it needs some way to be able to call into one of the classes from the jar file to create the service driver object and Jini attributes. To provide this capability, the jar file containing the mobile code service driver is required to have a class that implements the following interface:

    public interface ServiceItemFactory {
        public ServiceItem getServiceItemInstance(ServiceURL serviceURL,Map attributes);
        ...
    }

Given the SLP service URL and a Java Map collection object containing all the SLP attributes, the ServiceItemFactory returns a Jini ServiceItem. The ServiceItem object contains the Jini attributes, to be matched against the Jini attribute objects included in the Jini query, and the driver object, which is an appropriate return from the ServiceRegistrar. This allows the SLP code to substitute for RMI in the ServiceRegistrar lookup method. For the client code to know which class to instantiate, the jar file manifest contains an attribute, Java-Driver-Factory, set to the name of the class implementing the ServiceItemFactory interface. The client need only look in the manifest to determine what class to instantiate to obtain the ServiceItem object.

The procedure for discovering a Jini service advertisement, matching Jini attributes, and downloading the mobile code service driver given a Jini template including Jini attribute objects can be summarized as follows. This procedure is used when a Jini client calls into a ServiceRegistrar implemented with SLP.

  1. Formulate a query for the class included in the template. The query includes all classes and interfaces in the class hierarchy. For example, if the client is looking for a RocketPrinter that implements the net.jini.Printer interface, the following query would be used:
        (&(interfaces=com.rp.RocketPrinter)(interfaces=net.jini.Printer))
    
  2. Make the query using the SLP Locator. The service type is service:jini, the abstract type. The abstract type is used because the client needs to obtain all concrete types that match the interfaces in the query.
  3. With the returned service URLs, use the Locator to obtain the java-driver-factory attribute and other SLP attributes, which include serialized Jini attributes.
  4. Download the jar file for the service driver.
  5. Instantiate the class corresponding to the Java-Driver-Factory attribute in the manifest file.
  6. Call the ServiceItemFactory.getServiceItemInstance() method to instantiate the driver object and the ServiceItem.
  7. Compare the Jini attribute objects passed in through the template with the Jini attribute objects returned in the ServiceItem.
  8. If the attributes match, return the driver object or ServiceItem.

Given this procedure, absolutely no change is required in the ServiceRegistrar interface to layer it on top of SLP. The SLPRegistrar class implements the ServiceRegistrar interface with code that uses SLP to look up and return service driver objects, instead of RMI. However, because Jini was not designed to have replaceable ServiceRegistrar implementations, changes in the internals of the LUS discovery code were required to return SLPRegistrar objects to the client. Both changes are transparent to Jini clients.

7.0 Discussion

An important difference between the Jini API layered on SLP and standard Jini is that Jini-on-SLP returns service driver objects created from downloading classes, while Jini-on-RMI returns RMI proxy objects. Jini-on-SLP is not a distributed object system like Jini-on-RMI, but rather a mobile code networking system. The result opens the Jini client API for considerably more flexibility in what kinds of services can be utilized. The service driver code downloaded into the client can implement any protocol, naturally including RMI. As a result, legacy protocols and protocols that are not Java specific can offer driver objects for clients without requiring the servers to be implemented in Java.

As mentioned above, the base Jini system was not originally designed with replacement of the underlying service discovery code in mind. The LUS discovery code is constructed with the proprietary Jini lookup discovery protocols. An alternative implementation is to use a service provider approach, like JNDI [6]. A Java property contains a list of discovery provider modules to load. The discovery code creates provider objects for all known discovery providers, and returns ServiceRegistrar instances implementing the discovery providers to the client. The result is a more flexible system that can accommodate a variety of underlying directory service or service discovery infrastructures.

Another interesting extension is providing mobile code client services access to clients in languages other than Java. In principle, if the operating system supports dynamic linking of libraries, it should be possible for a client to perform service discovery using a protocol such as SLP, download a library, and dynamically link the library into the client process. The client then has access to the service driver API, provided it was compiled with the proper header files that describe how to access the functions in the library. In practice, there are a variety of problems with extending the mobile code approach to clients in other languages. Security and accommodating different binary formats for different processors are two examples. However, these problems are ones that must be faced by other mobile code networking systems, and are not unique to client service access mobile networking code.

8.0 Summary

In this paper, we have described a system for providing clients of network services with drivers to access those services by loading mobile code drivers. The system is built under the Jini distributed object system API. The RMI protocol-based service discovery system in Jini was replaced with a system built on a standard service discovery protocol, SLP. Services advertise Jini drivers using a concrete instance of the service:jini abstract type. Clients utilize SLP to discover these services, then download Jini drivers for accessing the services.

The resulting system replaces Jini's distributed object paradigm with a mobile code paradigm. The benefit is that drivers can implement any protocol that the service requires, and are not restricted to RMI. In addition, the infrastructure required for RMI is eliminated unless the services specifically require it. The infrastructural requirements for SLP are much less extensive. Finally, servers can be implemented in languages other than Java, as long as they provide Java drivers for Jini clients.

9.0 Acknowledgments

The authors would like to thank Jon Wood and Erik Guttman, of Sun, and Charlie Perkins, of Nokia, for their ideas during the initial design phases of the SLP subscription/notification service. Erik and Robert Nielsen, of Everest Technologies, were also instrumental in working out the details for the downloading procedure of the mobile driver code in Java.

10.0 References

  1. Arnold, K., O'Sullivan, B., Scheifler, R., Waldo, J., and Wollrath, A., The Jini Specification, Addison-Wesley, Reading MA, 1999.
  2. Howes, T, Smith, M, and Good, S., Understanding and Deploying LDAP Directory Services , MacMillian, Indianapolis, 1997.
  3. Kempf, J. and St. Pierre, P., Service Location Protocol for Enterprise Networks , Wiley, New York, 1999.
  4. Guttman, E., Perkins, C., Veizades, J., and Day, M., "Service Location Protocol, Version 2," IETF RFC 2608, June, 1999.
  5. Guttman, E., Perkins, C., and Kempf, J., "Service Templates and service: Schemes," IETF RFC 2609, June, 1999.
  6. Sun Microsystems, JNDI: Java Naming and Directory Interface , 1997.
  7. Kempf, J., and Guttman, E., "An API for Service Location," IETF RFC 2614, June, 1999.
  8. McLaughlin, L., "Line Printer Protocol," IETF RFC 1179, August, 1990.
  9. Yergeau, F., "UTF-8, a transformation format of ISO 10646", IETF RFC 2279, January, 1998.
  10. Howes, T., "The String Representation of LDAP Search Filters," IETF RFC 2254, December, 1997.
  11. Perkins, C., and Guttman, E., "DHCP Options for Service Location", IETF RFC 2610, June, 1999.
  12. Kempf, J., and Goldschmidt, J., "Notification and Subscription for SLP," an Internet draft, work in progress.