CS 696 Emerging Technologies: Java Distributed Computing Spring Semester, 1999 Jini Overview |
||
---|---|---|
© 1999, All Rights Reserved, SDSU & Roger Whitney San Diego State University -- This page last updated 21-Jul-99 |
What is Jini?
Released by Sun in January 1999
Jini – a general infrastructure for distributed computing between devices on a network
"Jini technology provides simple mechanisms which enable devices to plug together to form an impromptu community - a community put together without any planning, installation, or human intervention."
Jini Scenarios
Digital camera and pictures
Jini Services
Service
Standard Jini Services
Lookup Service
Transaction Manager
JavaSpaces Service
Jini Distribution
Contains:
Jini Lookup Service
A Server register a service with lookup service
A Client finds services via the lookup service
Registering a Service
Finding a Service
Interacting with a Service
Finding a Jini Lookup Service
(Discovery and Join)
There are two ways one can find a Jini lookup service
Multicast Discovery
The Good
Allows a Jini-aware device to connect to a network without knowledge of the network.
That is there is no need to configure the device to know about the services on the network. Anyone can plug in the device, and it will find the Jini lookup service and know about the available services.
The Bad
Most network administers turn off IP multicast when possible.
This means most networks must be modified to support Jini.
The Ugly
Sun’s Jini PR implies that a Jini system needs no setup.
A Jini system needs at least one lookup service running and multicast to be supported.
Lookup Service Basics
Server registers with lookup service:
The Service Proxy Code
Proxy is Java code that is downloaded to the client
Client uses proxy code to interact with the service
The Service Proxy Code
import java.rmi.*; import java.net.MalformedURLException; public class HelloClient { public static void main(String args[]) { Hello remote = (Hello) Naming.lookup( "rmi://eli.sdsu.edu/HelloServer"); String message = remote.sayHello(); System.out.println( message ); }
Service Proxy Code and Interfaces
The Jini client needs to know what methods to call to perform a given task – the service interface.
Before writing a Jini client, the service interface must exist
Service Proxy Code and Security
Java 2 (jdk1.2) security model provides fine grain control over:
Service Proxy Code
The Good
Do not have to manually configure Jini clients with device drivers for each Jini service
RMI generates the proxy code automatically
The Bad
RMI can be slow
RMI can has connection problems on the Internet
Requires http server for distributing class definitions
Downloading class definitions requires programmers to be careful
The Ugly
For consumer products, standard interfaces for the proxy code do not yet exist
Jini.org is has a number of working groups to establish these standard interfaces. If these interfaces are not supported by manufactures of the devices, Jini will not see wide spread use.
Leases
Jini uses leases to keep information about services current
Access to a service is leased for a given duration
If a client wants the service longer, it must request a lease renew before the end of the lease
At the end of a lease, a client’s access to the service is terminated
Lookup Service and Leases
Entries in the lookup service are leased
A device must renew the lease to remain listed in the lookup service
Lookup service leases are for a few minutes
Hello World Example
This example:
package whitney.jini.examples.hello; import java.rmi.Remote; import java.rmi.RemoteException; public interface HelloInterface extends Remote { public String sayHello() throws RemoteException; }
HelloServer Implementation package whitney.jini.examples.hello; import net.jini.core.entry.Entry; import net.jini.core.lookup.ServiceID; import net.jini.lookup.entry.Name; import com.sun.jini.lookup.ServiceIDListener; import com.sun.jini.lookup.JoinManager; import com.sun.jini.lease.LeaseRenewalManager; import java.rmi.Remote; import java.rmi.RemoteException; import java.rmi.RMISecurityManager; import java.rmi.server.UnicastRemoteObject; public class HelloServer extends UnicastRemoteObject implements HelloInterface, ServiceIDListener { private ServiceID myID; public HelloServer() throws RemoteException { } public String sayHello () throws RemoteException { return ("Hello World from Jini!"); } public void serviceIDNotify (ServiceID uniqueID) { myID = uniqueID; System.out.println("server: ID set: " + myID ); }
Registering HelloServer with Lookup Service
public static void main (String[] args) throws Exception { System.setSecurityManager (new RMISecurityManager ()); HelloServer myServer = new HelloServer (); Entry[] identityingAttributes = new Entry[1]; identityingAttributes[0] = new Name("HelloServer"); JoinManager myManager = new JoinManager ( myServer, identityingAttributes, myServer, new LeaseRenewalManager () ); System.out.println ("Server has joined a lookup service!"); } }
HelloClientUsing the HelloServer – Unicast Discovery
package whitney.jini.examples.hello; import net.jini.core.entry.Entry; import net.jini.core.lookup.ServiceTemplate; import net.jini.core.lookup.ServiceRegistrar; import net.jini.core.discovery.LookupLocator; import net.jini.lookup.entry.Name; import java.rmi.RMISecurityManager; public class HelloClient { public static void main (String[] args) throws Exception { System.setSecurityManager (new RMISecurityManager ()); LookupLocator lookup = new LookupLocator ("jini://eli.sdsu.edu"); ServiceRegistrar registrar = lookup.getRegistrar (); Entry[] serverAttributes = new Entry[1]; serverAttributes[0] = new Name ("HelloServer"); ServiceTemplate template = new ServiceTemplate (null, null, serverAttributes); HelloInterface myServerInterface = (HelloInterface) registrar.lookup (template); System.out.println ( myServerInterface.sayHello () ); } }
HelloClient Multicast Discovery
package whitney.jini.examples.discoveryJoin; import java.io.IOException; import java.rmi.RMISecurityManager; import net.jini.core.discovery.LookupLocator; import net.jini.core.entry.Entry; import net.jini.core.lookup.ServiceRegistrar; import net.jini.core.lookup.ServiceTemplate; import net.jini.discovery.DiscoveryEvent; import net.jini.discovery.DiscoveryListener; import net.jini.discovery.LookupDiscovery; import net.jini.lookup.entry.Name; import sdsu.util.ProgramProperties; public class HelloClient implements DiscoveryListener { public static void main (String[] args) throws Exception { System.setSecurityManager (new RMISecurityManager ()); ProgramProperties flags = new ProgramProperties( args); if ( !flags.containsKey( "group") ) { System.out.println( "Usage: java HelloClient -group=groupName" ); System.exit(0); } String groupsString = flags.getString( "group" ); new HelloClient( groupsString ); // discovery nneds some time to work Thread.currentThread().sleep( 1000 * 15 ); } public HelloClient( String group ) throws IOException { String[] serverGroup = { group }; LookupDiscovery findAllLookupServices = new LookupDiscovery( serverGroup ); findAllLookupServices.addDiscoveryListener( this ); } public void discovered(DiscoveryEvent lookupService ) { findServer( lookupService); } public void discarded(DiscoveryEvent lookupService) { // don’t care about this}
HelloClient Multicast Discovery
private void findServer( DiscoveryEvent event) { Entry[] serverAttributes = new Entry[1]; serverAttributes[0] = new Name ("HelloServer"); ServiceTemplate template = new ServiceTemplate (null, null, serverAttributes); try { ServiceRegistrar lookupServices[] = event.getRegistrars(); for (int k = 0; k < lookupServices.length; k++) { HelloInterface myServerInterface = (HelloInterface) lookupServices[k].lookup (template); if (myServerInterface != null ){ System.out.println ( myServerInterface.sayHello () ); } else{ System.out.println ( "No server yet" ); } } } catch (Exception lookupProblem) { lookupProblem.printStackTrace(); } } }
Transaction Manager
Uses a two-phase commit protocol to provide ACID transactions
ACID:
Other Jini Topics
JavaSpaces
Future of Jini
Work in progress