ONJava.com    
 Published on ONJava.com (http://www.onjava.com/)
 See this if you're having trouble printing code examples


First Contact: Is There Life in JavaSpace?

by Robert Flenner
04/05/2001

I often went to bed as a child wondering about life in outer space. Was there other life out there, or are we all alone? The notion of "first contact" was always exciting, stimulating, and left you with a feeling that was difficult to describe. I could not have imagined that software engineering would lead me to a space where first contact is a reality -- space where encounters with aliens (other software engineers) can occur anywhere in the universe.

Jini and JavaSpaces hold great promise in allowing information workers to make contact and collaborate on the edge of emerging technologies. These technologies enable multidimensional information exchange and intuitive, ad hoc work group formation.

Jini network technology provides a network-centric view to services and service delivery. Services have a broad definition from applications to mobile appliances and anything in between on the network. You can make first contact with these services without prior knowledge of where they reside. Services take on a life of their own in Jini networks. The goal is to minimize the amount of human intervention and administration required.

JavaSpaces is an example service that runs on the Jini network. JavaSpaces is closely tied to the Jini architecture; in fact it is one of the few services that comes bundled with Jini. JavaSpaces was heavily influenced by the concept of a tuple space that was first described in 1982 in a programming language called Linda. The basic idea is that you can have many active programs distributed over physically dispersed machines, unaware of each other's existence, and yet still able to communicate. They communicate to each other by releasing data (a tuple) into tuple space. Programs read, write, and take tuples (entries) from tuple space that are of interest to them.

This distributed network of loosely coupled collaborating processes is an ideal foundation for the global competitive markets of the twenty-first century. Progressive corporations are investing in technologies to help information workers become more effective in the capture, analysis, and dissemination of information.

This series of articles will explain Jini and JavaSpaces in the context of promoting and creating a virtual work space -- a work space where project team members can assemble to discuss and exchange information without the physical constraints of the world around them. Let's start our journey in Jini and JavaSpaces to the fictitious land of JavaOffice Space (JOS).

Experiencing JavaOffice Space

Meet Elliot Franks, a software engineer with Global Business Intelligence (GBI). Elliot has been working on a new software design of Tracker for GBI. Tracker is agent-based software that tries to anticipate human interaction with software programs and assists with user navigation. The company wants to integrate Tracker into existing systems on-the-fly and, thus, reduce the time it currently takes to analyze human-to-system patterns of behavior. Elliot is a superior software designer, but this project has stretched his capabilities in design and cognitive science.

This morning Elliot has scheduled a meeting with Ian Gestal a noted researcher and engineer in pattern recognition strategies. Both men have worked together on previous projects and have mutual admiration and respect for each other.

As time draws near Elliot retreats to his office. His office this morning is cast in a blue amber light emanating from the floor of the room. On the far wall is a black doorway shaped opening. Above the opening is a neon light that radiates "Destination: Hong Kong". Yesterday Elliot spent time talking to the research group in Hong Kong and had not changed the transporter destination since then. This morning Elliot will be "space traveling" to London to discuss the Tracker project.

Elliot has looked forward to the meeting with Ian. It is always fascinating to experience the work space that Ian delivers to every meeting and encounter. From the moment you meet Ian and the connection occurs, your creative capabilities are stretched in new dimensions. The workspace that Ian delivers has proven advantageous in differentiating Ian's consultations from those of the masses and the herds of consultants on the channels.

Elliot casually adjusts his chair as he prepares for transportation. On his lap sits a panel which displays the world. e zooms into London and activates the transportation process. The neon light over the dark doorway changes to "Destination: London" and a momentary pause occurs as the instrumentation adjusts to the new location; the doorway lightens and Ian enters the room.

Ian, spinning a ball projecting bright lights, smiles coyly and quips about the thread traffic in the channel. "Almost 60 miles just to get here today", he says, "the commute was miserable this morning".

Elliot and Ian spend the next hour discussing the project goals and objectives of Tracker. Ian suggests some alternative design considerations and also points Elliot to a research team in Germany doing work that may be applicable to his project. During the course of the conversation Ian pulls up numerous references and plugs into a number of similar initiatives. In addition Ian agrees to multicast their conversation to an AI group developing human expectations based software.

Elliot thanks Ian and agrees to share any information that would be of value to their projects. They agree their software-agents will be in contact to schedule and coordinate future meetings. The doorway grows dark as Ian leaves the space. Elliot returns to his work. The spinning ball slowly dims at the entry to the gateway.

Traversing through the JOS channel
Traversing through the JOS channel

Analysis of our virtual work space

Elliot and Ian just experienced might seem far-fetched and a bit on the sci-fi edge. However most of the communication techniques are available today. While the scale and the illusion of the encounter may be exaggerated, the relevance of the content and the exchange is not. Let's look at the interaction from a technical perspective. More specifically how can Jini and JavaSpaces begin to lead us on a journey of collaboration in the information "space" age.

Discovery and The London Channel
Of course Elliot and Ian never physically left their offices. Their transportation was strictly digital. The channel that was referenced was a connection established between two well-known end points. The meeting required services to be invoked to facilitate and coordinate the exchange of information. Jini and JavaSpaces are ideal candidate technologies for dynamic exchange of content. Jini provides the infrastructure and JavaSpaces provides the content framework for creating, updating, and deleting data.

There are three basic steps to "first contact" in the Jini network.

There are many options and alternative techniques available to implement these three processes. We will focus on the LookupDiscovery and the JoinManager classes.

Discovery.

The process of discovery occurs when a service is searching for a registration point in the Jini network. This registration point or service is referred to as the Lookup Service (LUS). The Lookup Service is fundamental to the Jini network. It allows us to manage the life cycle of services. Services must register with a LUS in order for other services and clients to find and use them. In our example Ian and Elliot were using the JOS service for their collaboration. Ian would have registered the service with his local LUS in London.

The basic operations of discovering the lookup service are implemented by a Jini technology infrastructure software class. The net.jini.discovery.LookupDiscovery class implements the net.jini.discovery.DiscoveryManagement interface. This interface defines operations related to the discovery of a lookup service. An instance of the LookupDiscovery class acts as a mediator between devices and services and the LUS supporting the network. In our example the JOS service registers itself with a local instance of this class. You construct an instance of this class by passing an array of groups that you want the discovered lookup service to support. For instance public groups or groups identified by specific department or geographic region could be used to construct the LookupDiscovery class.

String[] groups = new String[] { "" };     
try {
    LookupDiscovery lookup = new LookupDiscovery(groups);
} catch (IOException ioe) {}

In the previous code fragment the empty string value is used to indicate all public groups.

This instance then multicasts a request on the local network for any lookup services that support the groups requested to identify themselves. The LookupDiscovery instance listens for replies and, if there are any, passes to the service (JOS) an array of objects that are proxies for the discovered lookup services. These proxies are what the service will use to register with the LUSes discovered.

Reggie, the Jini supplied LUS, is one of the services that you start when you establish your Jini network. You may start one or more lookup services on your network. The following batch file provides an example start-up script. The environment variable JINI_HOME points to your installation of Jini.

java -jar -Djava.security.policy=%JINI_HOME%\policy.file %JINI_HOME%\lib\reggie.jar
http://%IP_ADDRESS%:8080/reggie-dl.jar %JINI_HOME%\example\lookup\policy.all %JINI_HOME%\tmp\reggie_log public

Join
The process of Join occurs when a service has located a lookup service through discovery and now wishes to register a service with it.

Join.

The Join protocol is implemented by another Jini technology infrastructure software class, net.jini.lookup.JoinManager. This class actually combines discovery, the first step, with LUS registration. There are five parameters required to construct a JoinManager.

This code fragment demonstrates use of JoinManager. This is our DiscoveryListener implementation. It receives notification of LUSes discovered and discarded. Our implementation creates a new thread to handle the event.

net.jini.discovery.DiscoveryListener Interface

public void discovered(DiscoveryEvent de) { 
  new Thread(new DiscoveryNotifier(de)).start(); 
} 

public void discarded(DiscoveryEvent de) { 
     // removes the LUS from the lookup table
     // and may generate additional event notifications
}

Our DiscoveryEvent thread interfaces with the LUS proxy (ServiceRegistrar) to register our service with the LUSes returned.

class DiscoveryNotifier implements Runnable  
{ 
 DiscoveryEvent de; 
 DiscoveryNotifier(DiscoveryEvent de) { 
    this.de = de;   
    } 

 public synchronized void run() 
 { 
   try { 
    // get the LUS's returned
    ServiceRegistrar registrars[] = de.getRegistrars(); 
    for(int i=0; i < registrars.length; i++) { 
     if(lookups.containsKey(registrars[i]) == false) { 

      // create a ServiceItem
      ServiceItem si = new ServiceItem(id, obj, entries);  

      // register the service with the LUS
      ServiceRegistration sr = registrars[i].register(si,
       Long.MAX_VALUE); 
      System.out.println("registered on " + 
       registrars[i].getLocator() + " as " + 
       sr.getServiceID()); 

      // delegate lease management 
      lrm.renewUntil(sr.getLease(), Long.MAX_VALUE, null); 

      // update our LUS table
      lookups.put(registrars[i], sr); 
      }  
     } 
    } catch (Exception e) { e.printStackTrace(); } 
 
  } 
}

This is our ServiceIDListener implementation. This method receives notification of a new ServiceID assignment. Our implementation uses an instance of ReliableLog to capture and restore the unique service id.

net.jini.lookup.ServiceIDListener

public void serviceIDNotify(ServiceID serviceID) {  
 System.out.println("Notification of service id: " + serviceID);     
 this.id = serviceID;  
 try {       
     // capture the id to persistent storage
     log.snapshot();  
	  } catch (Exception e) { e.printStackTrace(); }         
 System.out.println("updated log file with: "+serviceID);        
}

At this point we have discovered the lookup services and registered an object with each service. It is now possible for a client to find the service through the lookup process.

Lookup "first contact"

The process of Lookup occurs when a client or user needs to locate and invoke a service described by its interface type and option service attributes. A lookup service maps interfaces indicating the functionality provided by a service to sets of objects that implement the service. In addition, descriptive entries associated with a service allow more fine-grained selection of services based on properties. If you look back at the parameters to the JoinManager you will notice an array of attributes as the second parameter. These attributes implement the Entry interface and are used to qualify or augment the object that has been registered. When lookups are performed users can supply attributes to limit the matching services. Entry attributes can be user defined; however, the Jini implementation provides some default attribute classes. The net.jini.lookup.entry package defines the Address, Comment, Location, Name, ServiceInfo, Status, and ServiceType attributes. When Elliot requested the JOS he qualified the service match with an Address and Location attribute.

Elliot used his visual transporter to find the service by invoking another Jini infrastructure class, net.jini.core.discovery.LookupLocator. The LookupLocator class is responsible for performing unicast discovery. A hostname is all that is required to discover the LUS at a specific location. Optionally a port number can be provided to the LookupLocator. Otherwise it will default to port 4160. The LookupLocator constructor takes a URL of the form: jini://host:port/.

Unicast discovery was used as opposed to multicast because the multicast protocol is restricted by network configurations. The multicast protocol is only used on local network segments. Typically routers block multicast packets across network defined boundaries. This is often a source of confusion with new developers to Jini. The basic pattern of communication involves a combination of multicast and unicast. This enables the best of both worlds: dynamic discovery of local peers and directed or trusted discovery of distant peers.

Objects in a lookup service may include other lookup services; this provides hierarchical lookup. Further, a lookup service may contain objects that encapsulate other naming or directory services, providing a way for bridges to be built between a Jini lookup service and other forms of lookup service.

This chart defines the steps after the service provider has discovered the local LUS.

In step 3 the HTTP server running on the server-side of the Jini network supplies the code to the client requesting the service. This movement of code from machine-to-machine is critical to the differentiation of Jini from other distributed object technologies. The codebase parameter supplied to the HTTP daemon at start-up determines the location of the jar and class files that are available for download distribution.

The following script starts the http server.

java -jar %JINI_HOME%\lib\tools.jar -port 8080 -dir %JINI_HOME%\download\lib -trees -verbose

In step 4 the client invokes methods on the service. Some methods may be invoked locally while others may be invoked remotely. The flexibility provided in the implementation of the service will determine the best invocation approach. Jini uses the Java Remote Method Invocation (RMI) framework to enable communication between services and clients. The infrastructure to support communication between services is not itself a service that is discovered and used but is, rather, a part of the Jini technology infrastructure. RMI provides mechanisms to find, activate, and garbage collect object groups.

RMI allows data and code to be passed from object to object around the network. The simplicity and dynamic capabilities of the Jini system are enabled by this ability to move code around the network in a form that is encapsulated as an object. The RMI daemon is another service that must be started to enable your Jini environment.

The following script starts the RMI daemon.

rmid -J-Djava.security.policy=%JINI_HOME%\policy.file

We now have the basis of a Jini environment in place.

There are two more services that must be configured and started to enable our JavaOffice Space. The transaction service (mahalo) and the JavaSpaces service (outrigger).

Activating JavaSpaces

JavaSpaces is a JINI service that supports distributed persistence and the design of distributed algorithms. It uses RMI and object serialization from the Java programming language to provide these services.

The process to access the JavaSpaces service is like accessing any other JINI service. You perform the Lookup process with an LUS that has the JavaSpaces service registered. The net.jini.space package provides the service interface and related classes for the Sun/Jini supplied implementation. There are basically four operations that can be performed in space:

The net.jini.core.entry.Entry interface is used to identify entries that are capable of being used in JavaSpaces. You will implement this interface or extend the AbstractEntry class to create objects for use.

JavaSpaces requires the use of a transaction service like the Jini supplied mahalo service. This enables support for transactional properties such as isolation through a two-phase commit protocol. There are two types of JavaSpaces instances that can be defined, transient and persistent. Transient space does not provide persistence across system restarts, while persistent space does.

The following script starts the mahalo transaction service.

java -jar -Djava.security.policy=%JINI_HOME%\example\lookup\policy.all -Dcom.sun.jini.mahalo.managerName=TransactionManager %JINI_HOME%\lib\mahalo.jar http://%IP_ADDRESS%:8080/mahalo-dl.jar %JINI_HOME%\example\txn\policy.all %JINI_HOME%\tmp\txn_log public\

Reading and taking entries from JavaSpaces requires a template to be constructed that matches the entry requested.

In our example Elliot and Ian were exchanging information by writing entries to and from an instance of JavaSpaces. The JavaOffice Space service provided a proxy to the JavaSpaces service that was running in London at Ian's office. When Elliot accessed the service, a reference to the JOS JavaSpaces instance was also made available. The space channel that was constructed allowed Ian and Elliot to view and exchange information using the JavaSpace API.

The following script starts the outrigger persistent service.

java -jar -Djava.security.policy=%JINI_HOME%\policy.all -Dcom.sun.jini.outrigger.spaceName=JavaSpaces %JINI_HOME%\lib\outrigger.jar http://%IP_ADDRESS%:8080/outrigger-dl.jar %JINI_HOME%\policy.all %JINI_HOME%\tmp\js_log public

Our Jini environment now contains.

One thing to note is that once your environment is in place, subsequent start-ups only require the first two services. An HTTP server for downloading code and the RMI daemon for activating services. Since reggie, mahalo, and outrigger are all activating services they will be started by RMI automatically when requested.

The Scout

The following class Scout can be used to display the services available in your JINI environment. It displays the services that match a specific template. You should be able to customize this class for finding specific services and displaying them on a console or visual editor.

View class here.

View Scout display of active services here.

JWorkPlace as an Example JavaOffice Space

JWorkPlace is a project I am promoting that presents a foundation for learning, sharing, and collaborating using Jini and JavaSpaces technologies. Like the fictional JavaOffice Space, JWorkPlace essentially will define the concept of a virtual development center, allowing development members to enter and leave the space, while providing multiple levels of community participation.

The current space can be segmented into components.

JWorkPlace Development and Resource Center
JWorkPlace Development and Resource Center

As we continue with this series we will build the necessary components for collaboration using JINI and JavaSpaces. Now that we have made "first contact" the opportunities that exist are only limited by our imagination. Stay tuned.

Robert Flenner is an active author, software developer, and independent contractor who is actively involved with emerging B2B technologies.


Return to ONJava.com.

Copyright © 2009 O'Reilly Media, Inc.