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).
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.
|
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.
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.
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.
java.lang.Object --
The object or service to be registerednet.jini.core.entry.Entry[] --
An array of attributes associated with the objectnet.jini.lookup.ServiceIDListener or
net.jini.core.lookup.ServiceID -- Every service receives
a unique service identifier. If the service has already received the
identifier from the LUS, then it uses the id as a parameter; otherwise
it supplies an id listener to receive the id. The id listener would
store the id for subsequent registration.net.jini.discovery.DiscoveryManagement -- This is an
interface that defines the discovery operations as outlined in the
previous section. The LookupDiscovery class implements
this interface. In addition the LookupLocatorDiscovery
class implements this interface using unicast instead of the multicast
protocol.net.jini.lease.LeaseRenewalManager -- The lease
renewal manager is responsible for renewing your lease with the
LUS. This is how resources are managed across the Jini network,
e.g. time allocation management.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.
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).
|
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 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 Scout display of active services here.
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.
|
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 © 2007 O'Reilly Media, Inc.