There is a spectrum of distributed system middleware: at the base there are stream-messaging systems such as socket-based systems. There are many systems functioning at this level, most of them with custom-built protocols, such as ftp, telnet, HTTP, etc. The next level up is remote procedure call systems, where interaction appears as a procedure call but is translated by the middleware into message calls using a protocol generalised for the RPC system. This includes Sun's RPC (now the IETF ONC), Web Services and UPnP using SOAP as standard protocol. The next level still is remote method calls for objects, with primary example being CORBA. In stream, RPC and remote method systems the "objects" do not move, and nodes deal with representatives or proxies for the remote "object". The proxy may be an IP address plus port, and HTTP URL or a CORBA endpoint.
Above these, we begin to move into middleware systems that support mobility of objects. Such middleware systems tend to be language specific since all nodes need to be able to deal with the objects they receive. The simplest level of these is typified by Java RMI, where an RMI proxy is sent from one node to another. The proxy is clearly defined in its possible activities and in how it communicates back to its source. Jini relaxes this by allowing proxies with unconstrained behaviour to be sent (the scope of their possible actions needs to be limited by security mechanisms). However, these proxies are still "ordinary" objects with no "volition" of their own. Agents are (currently) the final layer above this, able to move about the network and not being tied to any particular node.
Jini gives a tremendous amount of flexibility to a system, with system specification tied to Java interfaces but implementation upto the programmer. A number of scenarios have looked at how Jini could be used for home environments, for example. Despite this, there are no Jini-enabled home devices, but there are an increasing number of devices using the more "primitive" UPnP technology.
In part this is an industry based movement: UPnP was devised in competition to Jini, and although it was initially just a weakly thought out idea, its proponents have persisted in developing the technology and pushing it into the market place. Jini applications meanwhile have tended to ignore this space and concentrate on more business-oriented systems, while Sun's focus on small embedded systems has been towards the mobile phone arena.
However, there is also a strong set of technical reasons why Jini does not seem to be succeeding in the home-appliance. What should be advantages appear to be disadvantages in this area. While there have been a number of attempts (JMatos, JiniME) to overcome them, these have not translated into market-place solutions (at least, not yet).
In this paper we look at the advantages of Jini and how they might seem to be disadvantages, with UPnP held up as middleware that seems to be succeeding despite its lower level of sophistication. We then follow that up by looking at how Jini could be "dumbed down" to the UPnP level of technology, and what it would look like then.
In a client/service system, clients need to find services. Their location may be hard-coded as in stream-based systems or in many RPC systems. At a more advanced level search may be involved which requires one or more repositories of service information. Such repositories have been familiar as CORBA or RMI naming services. Jini uses an object-oriented variant, the Lookup Service. There must be at least one of these running and both services and clients must be able to find them.
Jini employs two methods to find lookup services: unicast to known locations and multicast to unknown services. The first is suitable for general internet nodes, the second is particularly suitable for local networks such as a home network: devices and services just find lookup services without any configuration on the part of a user.
Once a lookup service has been found, services can register with it and clients can query it for services, using unicast.
UPnP has adopted the multicast/unicast mechanism, but does not have an independant lookup service: each service advertises itself directly or responds to requests from client searchers. The two functions of responding to search requests and responding to invocation requests must both be handled by UPnP devices.
In a network with many devices, if each device is advertising itself as in UPnP, then the adverts could swamp the network. This happened for example with the Gnutella peer-to-peer middleware where knowledge of too many peers and keeping this knowledge current simply absorbed all the network bandwidth for many peers. This situation has not yet arisen in home networks, which have typically between zero and a dozen nodes, and may never occur. Nevertheless, it remains a possibility. Jini can work with only one lookup service, so this particular problem may not arise so easily. It can occur with lease renewals to the lookup service.
The major downside with a separate lookup service is administration. A Jini network has to have at least one lookup service, which has to be setup and kept running. This is a problem for "zero configuration" environments with no administrator and hence no-one to start a Jini lookup service. This is likely to be an issue with home networks unless routers or other common pieces of home networks (such as PCs) come pre-configured to run Jini lookup services. The likelihood of PCs pre-configured to run Jini lookup services is unlikely until PC vendors see an advantage in doing so.
A workaround for this is for a Jini device/service to run its own lookup service. A device on startup could firstly search for lookup services and if cannot find any that it can register with, then it could start its own. It would be a trivial matter for the device to register its own services directly with this lookup server.
When a Jini client or service finds a lookup service it downloads a proxy for the lookup service. This is an object in MarshalledObject format, and the receiving node must be able to unmarshall this to a Java object and make Java method calls on it. Thus the nodes must be able to handle MarshalledObject, ObjectInputStream (for readObject()) and dynamic class loading. None of these are supported by the "tiny Java" CLDC specification.
When a client searches successfully for a service, it will get the service proxy from the lookup service. This must be instantiated in the client. Typically the client will not have the service classes in its classpath and will have to dynamically download the classes from a network source, such as an HTTP server.
By contrast, a UPnP control point gets a XML document as a result of a successful search. Within this document is a URL for contacting the service. In effect, the client gets a "handle" to the service, and this involves no object mobility at all.
The requirement for object mobility currently requires Personal Java at a minimum, or J2SE or J2EE. If a device runs its own lookup service, then it obviously does not need to download a lookup service proxy.
A Jini service will define methods which can take almost any Java types as parameters or return types (they must be either Remote or Serializable). Any parameters other than java primitive types (int, boolean, etc) must be serialized and de-serialized at the receiving end.
UPnP only allows primitive types (including strings) as parameter and return types. Thus there is no question of object mobility. Service handles as in URLs could be passed as strings, but there are few UPnP objects that even require URL references. Largely this is due to the limited scope of current UPnP devices: switches, clocks, etc are not passing complex data.
One of the few UPnP devices that requires complex data are the A/V devices which can send results such as directory listings of music items. Rather than extend the UPnP data types, this done by sending a string which actually contains an XML representation of the directory.
The requirement for object mobility currently requires Personal Java at a minimum, or J2SE or J2EE. If a device runs its own lookup service, then it obviously does not need to download a lookup service proxy. However, if the service methods have Java objects as parameters then the service will still need to handle mobile objects. This can be avoided by using only primitive types. The Java class String could be included in this as the CLDC specification includes strings as readable objects from DataInputStream.
There does not seem to be so much opportunity to reduce the requirements of a client from at least Personal Java.
Discovery of a lookup service is done using a standardised multicast protocol. This returns a lookup service proxy that is unspecified. It may talk back to the lookup service using RMI, but need not. This is not specified by Jini. Similarly, when a client gets a proxy for the service and makes method calls on it, the proxy may communicate back using RMI and again, need not. It could use any protocol it wishes.
UPnP on the other hand specifies method invocation as using SOAP. This is a pretty clumsy protocol, both verbose and with some inherent flaws: it is not possible to pass back a reference to a SOAP object as the result of a SOAP method call. SOAP objects are not addressable - only their servers are. The REST community has been highly critical of SOAP, mainly because of this failing. Elsewhere I have shown that using SOAP instead of a REST-compliant protocol doubles memory use, doubles network traffic and so on.
Om the other hand, use of a standardised method invoation protocol means that clients in any language can talk to services. The Jini flexibility means that only the proxy "in the know" will be able to talk to a service.
The first question of course, is why? The authors of JMatos state that a typical Jini application requires many megabytes of memory. This is just too high for many embedded systems. Even Java-enabled phones have limited memory and will have difficulties running memory-intensive applications.
The Jmatos solution drastically reduces memory by use of a custom lookup service, but it should be possible to reduce it still further.
We remove all requirements on a Jini device to download objects: the device runs its own lookup service (without even checking for others); the lookup service only contains its "own" services and does not accept registrations from other services; the lookup service does not accept listeners for transtions (since none will occur!). The services on the device register themselves directly (in some unspecified way), and their methods only have primitive types as parameters and return values.
The lookup service when discovered will download a proxy to a client. This proxy can be a standard Java object and could be implemented in many ways. One extreme, as exemplified by JMatos, is for it to be a "complete" proxy that has no need to communicate back to the source lookup service: it contains all information necessary to answer all method calls made on it. Or it could use sone private protocol to talk back to the source lookup service.
The "complete" proxy has some