Download presentation
Presentation is loading. Please wait.
Published byGianpaolo Bernardini Modified over 5 years ago
1
Jini Instructors: Geoffrey Fox and Bryan Carpenter
Dept. of Computer Science School of Computational Science and Information Technology 400 Dirac Science Library Florida State University Tallahassee Florida 1/17/2019 it2jini
2
it2ejb http://aspen.csit.fsu.edu/it2spring01
Jini Jini is a set of specifications that enables services to discover each other on a network, and facilitates reliable interaction of those services. Jini is built on top of Java RMI. It incorporates a considerably more advanced and powerful model of lookup. Replacing the rather limited RMI registry. It adds a small but interesting set of concepts for reliable, fault-tolerant programming in distributed environments. 1/17/2019 it2ejb
3
it2ejb http://aspen.csit.fsu.edu/it2spring01
Jini Community Hopes The discovered services are imaginatively supposed to work together as a community. Early Jini literature (perhaps a bit too imaginatively) refers to the Jini community as a djinn. In Jini, federation of services is supposed to happen spontaneously: Scenario: a PDA with a wireless connection is brought into the neighborhood of a printer registered in a local Jini registry. Drivers for the printer are transparently made available to the PDA, and the PDA can immediately use the printer. The community is supposed to be self-healing: If services or clients are lost due to vagaries of connectivity, etc., software should automatically clean up and reconfigure itself to take account of this. 1/17/2019 it2ejb
4
it2ejb http://aspen.csit.fsu.edu/it2spring01
References Jini in a Nutshell, Scott Oaks and Henry Wong, O’Reilly, 2000. The Jini Specification, Arnold, O’Sullivan, Scheifler, Waldo, Addison Wesley, 1999. Core Jini, W. Keith Edwards, Prentice Hall, 1999. Jini pages at Sun, e.g.: 1/17/2019 it2ejb
5
it2ejb http://aspen.csit.fsu.edu/it2spring01
Overview of Jini 1/17/2019 it2ejb
6
it2ejb http://aspen.csit.fsu.edu/it2spring01
Motivations According to Bill Joy’s foreword to The Jini Specification: The Jini architecture is designed to bring reliability and simplicity to the construction of networked devices and services. A Jini system is a collection of interacting Java programs—you can understand its behavior completely by understanding the semantics of the Java language and the nature of the network. Jini raises the “level of discourse” in distributed computing—from the bits and bytes of TCP/IP, to the level of objects. 1/17/2019 it2ejb
7
it2ejb http://aspen.csit.fsu.edu/it2spring01
Features Jini is a simple infrastructure for providing services in a network. Services can join or leave network in a robust fashion. Clients can rely on availability of visible services, or expect clear failure conditions. Interaction with a service goes through a Java object provided by that service. This object is downloaded from the lookup services to the client program. The client can talk to a service even if it has never seen its kind before. This relies on Java RMI dynamic class loading. 1/17/2019 it2ejb
8
Registration of Services in Jini
When a Jini-aware service is booted or added to a network, it goes through a process called discovery to find one or more Jini lookup services in its neighborhood. Having found a lookup service (or Jini registry), the new service registers its proxy object in the Jini registry. The proxy is a Java object. In Jini, the Java type of the proxy defines the kind of service that is provided. For example, there may be an agreed convention that all proxy classes for printer services implement a Java interface Printer. The interface-type Printer is one of the reference types Java recognizes for the proxy objects. 1/17/2019 it2ejb
9
Looking up and Using Services
When a client needs a service, it goes through the same discovery process to find a Jini registry. The client then asks the registry for a suitable service. It selects the kind of services it is interested in primarily by specifying the Java type of the proxy object it needs. For example if it is searching for a printer service, it might ask the lookup service for any proxy object that implements the Printer interface. If the lookup service holds such a proxy, it returns the (serialized) object to the client. As a transparent side-effect, the byte-codes for the proxy class are also downloaded to the client. The client can now execute methods from the well-known Printer interface on its copy of the proxy object, heedless of details about the proxy implementation. 1/17/2019 it2ejb
10
it2ejb http://aspen.csit.fsu.edu/it2spring01
Registration Lookup Service registration Printer Service Proxy Printer Interface (If printer is also capable of receiving faxes, proxy object might also implement some FaxReceiver interface.) 1/17/2019 it2ejb
11
it2ejb http://aspen.csit.fsu.edu/it2spring01
Lookup Lookup Service Printer Interface lookup Client Proxy 1/17/2019 it2ejb
12
Client-server transaction
(Lookup service no longer involved) Printer Interface Printer Service Print request Proxy Client 1/17/2019 it2ejb
13
Prerequisites for this Architecture
Homogeneity: JVM provides a universal platform in which downloaded code can execute. A single type system. Serialization, for proxy objects held in registry. Code downloading, for the proxy objects. Security. The JVM must provide mechanisms to defend against possibly malicious downloaded code. 1/17/2019 it2ejb
14
it2ejb http://aspen.csit.fsu.edu/it2spring01
Reliability Besides providing a particular architecture for service discovery, Jini incorporates a framework for reliable programming in the presence of partial failure. If a particular service or client in a federation is lost, or some part of the network fails, the Jini community as a whole should recover and continue operating. It should also be able to free up resources claimed by the failed components. The Jini framework includes three sub-specifications to support this kind of robustness: The Jini Distributed Leasing Specification The Jini Distributed Event Specification The Jini Transaction Specification 1/17/2019 it2ejb
15
it2ejb http://aspen.csit.fsu.edu/it2spring01
Leasing The concept of leasing is one of Jini’s most characteristic ideas for supporting robust, self-healing communities. Well behaved Jini services and clients are supposed to consistently lease any “resource” they hold on a remote machine. A resource could be a temporary file, some thread running in a server program, some temporary remote object created on behalf of a client, etc. Another example is the “slot” that a registered service holds in a Jini lookup service. A lease expires after some fixed interval. If the lease is not renewed within that interval, the “owner” of the leased resource reclaims it. 1/17/2019 it2ejb
16
Distributed Events and Transactions
Jini also defines APIs for distributed events. These work something like the event models of AWT: Any number of listeners can register to be notified of a particular event. The event source may be on a different machine to the listener. Compared with AWT, the Jini specification provides much looser guarantees of the synchronization of delivery of events. It only guaranteeing behaviors that can be guaranteed over an unreliable network. Finally, Jini incorporates a model of transactions, in some ways akin to that in EJB. 1/17/2019 it2ejb
17
Example: Acquiring compute slaves through Jini
1/17/2019 it2ejb
18
Use of Jini in the Example
The example here is from a proposed system for parallel computing, built on top of Jini. The system is called MPJ. The Jini lookup services are used to locate a group of compute slaves, over which a parallel program can be distributed. An important advantage of using Jini is that failures can be cleanly detected, and resources recovered in the event of a partial failure. If any slave process dies, the client may generate a Jini distributed event, MPJAbort. All slaves are notified and all processes killed. In case of other failures (network failure, death of client, death of controlling daemon, …) client leases on slaves expire in a fixed time, and processes are killed. 1/17/2019 it2ejb
19
Getting Started with Jini
1/17/2019 it2ejb
20
Getting the Reference Implementation
You can download Sun’s reference implementation of Jini and associated software from: You may have to register as a member of the Java Developer Connection, and accept the Sun Community Source License. In particular you will need the Jini Technology Start Kit. unzip the downloaded file in a suitable directory (such as your home directory). This should create a subdirectory with a name like jiniX_Y/ (e.g. jini1_1/, depending on the version of the software). It will be convenient to define an environment variable JAVA_HOME referencing this directory, e.g.: export JAVA_HOME=/home/user/dbc/jini1_1 1/17/2019 it2ejb
21
it2ejb http://aspen.csit.fsu.edu/it2spring01
Serving Class Files Jini makes free use of dynamic class loading. You will need at least one Web server running, to serve up class files. Both for basic Jini services, and for any service proxy classes you register in the lookup services. Clients, of course, obtain the class files for such proxies dynamically, from a Web server. The Jini starter kit comes with a stripped down Web server that can be used for this purpose, but I chose to use my Tomcat server instead. 1/17/2019 it2ejb
22
Configuring Tomcat for use with Jini
Initially I created two document contexts—one for downloading standard Jini classes, the other for downloading classes associated with any services I implement. In my subdirectory jakarta-tomcat-X.Y.Z/webapps/ I might do: sirah$ ln -s /home/users/dbc/jini1_1 sirah$ mkdir service-dl The first command creates a soft link to my Jini home directory in the Tomcat document directory. The second, of course, creates a new directory called service-dl. I have to add the contexts jini1_1 and service-dl to jakarta-tomcat-X.Y.Z/conf/server.xml, and restart my Tomcat server. 1/17/2019 it2ejb
23
Starting the Jini Browser
The examples in the starter kit include a browser application, which discovers any Jini lookup services on the LAN, and allows one to browse the services registered in them. Starting this application is a little long-winded; you need to define a class path, a security policy, and a code base, as well as specifying the class for the application: JINI_LIB_BASE= java -cp ${JINI_HOME}/lib/jini-examples.jar -Djava.security.policy=${JINI_HOME}/example/browser/policy -Djava.rmi.server.codebase=${JINI_LIB_BASE}/jini-examples-dl.jar com.sun.jini.example.browser.Browser Of course you should change the value of JINI_LIB_BASE to reference your Web server. You may want to put these commands in a runbrowser script. 1/17/2019 it2ejb
24
it2ejb http://aspen.csit.fsu.edu/it2spring01
Viewing the Browser A little window should pop up, telling us that there are no lookup services running at the moment: 1/17/2019 it2ejb
25
The RMI Activation Daemon
Jini also makes free use of activatable objects. We talked about activation in the context of EJB: in that case a bean may be “passivated” if it is not busy; it will be activated again if any request is made to the bean by a client. In fact, Java RMI has a built-in activation framework. This provides a similar functionality for RMI remote objects. The actual mechanism is different. Native Java RMI activation is handled by a daemon called the remote activation daemon or rmid (whereas EJB activation is handled by the EJB container). Before using the Jini lookup services you must start rmid, e.g.: sirah$ rmid -log rmi_log & To stop rmid, use the command: sirah$ rmid -stop 1/17/2019 it2ejb
26
Starting the Jini Lookup Service
Again, starting the lookup service from the starter kit is rather verbose. You need to define a security policy, a jar file containing the class for the application, and arguments including a code base, a security policy (again!) and a “group”: JINI_LIB_BASE= java -Djava.security.policy=${JINI_HOME}/example/lookup/policy -jar ${JINI_HOME}/lib/reggie.jar ${JINI_LIB_BASE}/jini-examples-dl.jar ${JINI_HOME}/example/lookup/policy public You may want to put these commands in a runlookup script. Note, however that once the lookup service has been installed with rmid, you don’t have to run this command again unless you delete the rmid’s log file. 1/17/2019 it2ejb
27
it2ejb http://aspen.csit.fsu.edu/it2spring01
Viewing the Browser The browser should notice that a lookup service has become available and change its display to: 1/17/2019 it2ejb
28
it2ejb http://aspen.csit.fsu.edu/it2spring01
Viewing the Browser If you click on the Registrar menu, you should see a list of discovered lookup services: 1/17/2019 it2ejb
29
it2ejb http://aspen.csit.fsu.edu/it2spring01
Viewing the Browser Selecting sirah we get the following message: 1/17/2019 it2ejb
30
it2ejb http://aspen.csit.fsu.edu/it2spring01
Viewing the Browser If you click on the Services menu, you should see a list of interfaces implemented by the registered services: 1/17/2019 it2ejb
31
it2ejb http://aspen.csit.fsu.edu/it2spring01
Writing a Service import net.jini.discovery.* ; import net.jini.core.lookup.* ; import java.io.* ; import java.rmi.* ; public class WorldService { public static void main(String [] args) throws IOException, InterruptedException { System.setProperty("java.rmi.server.codebase", " ; System.setProperty("java.security.policy", "policy.all") ; System.setSecurityManager(new RMISecurityManager()) ; LookupDiscovery disco = new LookupDiscovery(new String [] {""}) ; disco.addDiscoveryListener(new WorldServiceListener()) ; while(true) Thread.sleep(1000) ; } 1/17/2019 it2ejb
32
it2ejb http://aspen.csit.fsu.edu/it2spring01
Remarks The class WorldService itself only sets some global properties and policies and initiates the discovery process by registering a DiscoveryListener. The application just waits forever. In the background we will be processing discovery events. 1/17/2019 it2ejb
33
The Discovery Listener
class WorldServiceListener implements DiscoveryListener { . . . public void discovered(DiscoveryEvent evt) { System.out.println("Discovered a lookup service!") ; ServiceRegistrar [] regs = evt.getRegistrars() ; for (int i = 0 ; i < regs.length ; i++) registerWithLookup(regs [i]) ; } public void discarded (DiscoveryEvent evt) {} void registerWithLookup(ServiceRegistrar registrar) { 1/17/2019 it2ejb
34
Registering the service
class WorldServiceListener implements DiscoveryListener { final int LEASE_TIME = 10 * 60 * 1000 ; ServiceItem item = new ServiceItem(null, new WorldProxy(), null) ; . . . void registerWithLookup(ServiceRegistrar registrar) { try { ServiceRegistration registration = registrar.register(item, LEASE_TIME) ; if(item.serviceID == null) { item.serviceID = registration.getServiceID() ; System.out.println("Set serviceID to " + item.serviceID) ; } } catch (RemoteException e) { System.out.println("Failed to register: " + e.getMessage()) ; 1/17/2019 it2ejb
35
The Proxy Class and Interface
class WorldProxy implements World, Serializable { public void printMessage() { System.out.println("Hello, world!") ; } public interface World { void printMessage() ; } 1/17/2019 it2ejb
36
it2ejb http://aspen.csit.fsu.edu/it2spring01
Writing the Client . . . Import statements . . . public class WorldClient { public static void main(String [] args) throws IOException, InterruptedException { System.setProperty("java.security.policy", "policy.all") ; System.setSecurityManager(new RMISecurityManager()) ; LookupDiscovery disco = new LookupDiscovery(new String [] {""}) ; disco.addDiscoveryListener(new WorldClientListener()) ; while(true) Thread.sleep(1000) ; } 1/17/2019 it2ejb
37
The Client Discovery Listener
class WorldClientListener implements DiscoveryListener { . . . public void discovered(DiscoveryEvent evt) { System.out.println("Discovered a lookup service!") ; ServiceRegistrar [] regs = evt.getRegistrars() ; for (int i = 0 ; i < regs.length ; i++) lookForService(regs [i]) ; } public void discarded (DiscoveryEvent evt) {} void lookForService(ServiceRegistrar registrar) { 1/17/2019 it2ejb
38
Looking Up and Using the Service
class WorldClientListener implements DiscoveryListener { Class [] types = {World.class} ; ServiceTemplate template = new ServiceTemplate(null, types, null) ; . . . void lookForService(ServiceRegistrar registrar) { try { World service = (World) registrar.lookup(template) ; if (service != null) { System.out.println("Found a matching service. " + "Invoking 'printMessage()'...") ; service.printMessage() ; } else System.out.println("No matching service.") ; } catch (RemoteException e) { System.out.println("Error doing lookup: " + e.getMessage()) ; } 1/17/2019 it2ejb
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.