2001 Prentice Hall, Inc. All rights reserved. Chapter 22 - Jini Outline 22.1 Introduction 22.2 Installation 22.3 Set Up Run-Time Environment 22.4 Start Required Services 22.5 Running the Jini LookupBrowser 22.6 Discovery 22.6.1 Unicast Discovery 22.6.2 Multicast Discovery 22.7 Jini Service and Client Implementations 22.7.1 Service Interfaces and Supporting Classes 22.7.2 Service Proxy and Service Implementations 22.7.3 Registering the Service with Lookup Services 22.7.4 Jini Service Client 22.8 Introduction to High-Level Helper Utilities 22.8.1 Discovery Utilities 22.8.2 Entry Utilities 22.8.3 Lease Utilities 22.8.4 JoinManager Utility 22.8.5 Service Discovery Utilities 22.9 Internet and World Wide Web Resources
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
2001 Prentice Hall, Inc. All rights reserved.
Chapter 22 - JiniOutline22.1 Introduction22.2 Installation22.3 Set Up Run-Time Environment22.4 Start Required Services22.5 Running the Jini LookupBrowser22.6 Discovery
22.7 Jini Service and Client Implementations22.7.1 Service Interfaces and Supporting Classes22.7.2 Service Proxy and Service Implementations22.7.3 Registering the Service with Lookup Services22.7.4 Jini Service Client
22.8 Introduction to High-Level Helper Utilities22.8.1 Discovery Utilities22.8.2 Entry Utilities22.8.3 Lease Utilities22.8.4 JoinManager Utility22.8.5 Service Discovery Utilities
22.9 Internet and World Wide Web Resources
2001 Prentice Hall, Inc. All rights reserved.
22.1 Introduction
• Network services– Discover service
– Know the interface of the service
• Jini services– Discover services on the network dynamically
– Dynamically download classes required to use those services
– Dynamic class downloading is transparent to clients
2001 Prentice Hall, Inc. All rights reserved.
22.2 Installation
• Software requirements– Java 2 Standard Edition (J2SE)
• Unicast Discovery– Discover lookup services on a specific host
• Uses class LookupLocator
2001 Prentice Hall, Inc.All rights reserved.
Outline
1 // UnicastDiscovery.java2 // UnicastDiscovery is an application that demonstrates Jini3 // lookup service discovery for a known host (unicast).4 package com.deitel.advjhtp1.jini.discovery;5 6 // Java core packages7 import java.rmi.*;8 import java.net.*;9 import java.io.*;10 import java.awt.*;11 import java.awt.event.*;12 13 // Java extension packages14 import javax.swing.*;15 16 // Jini core packages17 import net.jini.core.discovery.LookupLocator;18 import net.jini.core.lookup.ServiceRegistrar;19 20 public class UnicastDiscovery extends JFrame {21 22 private JTextArea outputArea = new JTextArea( 10, 20 );23 private JButton discoverButton;24 25 // hostname for discovering lookup services26 private String hostname; 27
ClassUnicastDiscovery
1. Import packages
2. Declarations
2001 Prentice Hall, Inc.All rights reserved.
Outline
28 // UnicastDiscovery constructor29 public UnicastDiscovery( String host )30 {31 super( "UnicastDiscovery Output" );32 33 hostname = host; // set target hostname for discovery34 35 // create JButton to discover lookup services36 discoverButton = new JButton( "Discover Lookup Services" );37 discoverButton.addActionListener( 38 new ActionListener() {39 40 // discover lookup services on given host41 public void actionPerformed( ActionEvent event )42 {43 discoverLookupServices();44 }45 } 46 );47 48 Container contentPane = getContentPane();49 contentPane.add( outputArea, BorderLayout.CENTER );50 contentPane.add( discoverButton, BorderLayout.NORTH );51 52 } // end UnicastDiscovery constructor53
3. Constructor
3.1 GUI
Discover lookup services when user clicks the button
2001 Prentice Hall, Inc.All rights reserved.
Outline54 // discover lookup services on given host and get details55 // about each lookup service from ServiceRegistrar56 public void discoverLookupServices()57 {58 // construct Jini URL59 String lookupURL = "jini://" + hostname + "/"; 60 61 // connect to the lookup service at lookupURL62 try {63 LookupLocator locator = new LookupLocator( lookupURL );64 outputArea.append( "Connecting to " + lookupURL + "\n" );65 66 // perform unicast discovery to get ServiceRegistrar67 ServiceRegistrar registrar = 68 locator.getRegistrar();69 70 // print lookup service information and71 outputArea.append( "Got ServiceRegistrar\n" +72 " Lookup Service Host: " + locator.getHost() + "\n" +73 " Lookup Service Port: " + locator.getPort() + "\n" );74 75 // get groups that lookup service supports76 String[] groups = registrar.getGroups();77 outputArea.append( "Lookup service supports " +78 + groups.length + " group(s):\n" );79 80 // get group names; if empty, write public81 for ( int i = 0; i < groups.length ; i++ ) {82 83 if ( groups[ i ].equals( "" ) )84 outputArea.append( " public\n" );85 86 else87 outputArea.append( " " + groups[i] + "\n" );88 }89 }
4. Discover lookup services
4.1 specify Jini URL
4.2 connect to lookup service
4.3 perform unicast discovery
4.4 append output
Jini URL
Connect to lookup service
Perform unicast discovery
Get host name and port number of the lookup serviceGet group name of
1 // policy.all2 // grant AllPermission to all code (DANGEROUS!)3 grant {4 permission java.security.AllPermission "", "";5 };
Grant AllPermission
Exit when window closes
2001 Prentice Hall, Inc. All rights reserved.
22.6.2 Multicast Discovery
• Multicast Discovery– Discover lookup services when host is not known
– Multicast discovery request
– Multicast announcements
– Class LookupDiscovery
• Uses class LookupDiscovery– Implements DiscoveryListener
2001 Prentice Hall, Inc.All rights reserved.
Outline
1 // MulticastDiscovery.java2 // MulticastDiscovery is an application that demonstrates Jini3 // lookup service discovery using multicast.4 package com.deitel.advjhtp1.jini.discovery;5 6 // Java core packages7 import java.rmi.*;8 import java.io.*;9 import java.awt.*;10 import java.awt.event.*;11 12 // Java extension packages13 import javax.swing.*;14 15 // Jini core packages16 import net.jini.core.lookup.ServiceRegistrar;17 18 // Jini extension packages19 import net.jini.discovery.*;20 21 public class MulticastDiscovery extends JFrame 22 implements DiscoveryListener {23 24 // number of lookup services discovered through multicast25 private int servicesFound = 0;26 27 private JTextArea outputArea = new JTextArea( 10, 20 );28
ClassMulticastDiscovery
1. Import packages
2. Declarations
Implements DiscoveryListener to listen for discovery notifications
2001 Prentice Hall, Inc.All rights reserved.
Outline29 // MulticastDiscovery constructor30 public MulticastDiscovery ()31 {32 super( "MulticastDiscovery" );33 34 // discover lookup services in public group using multicast35 try {36 LookupDiscovery lookupDiscovery = new LookupDiscovery( 37 new String[] { "" } );38 39 outputArea.append( "Finding lookup services for " +40 "public group ...\n" );41 42 // listen for DiscoveryEvents43 lookupDiscovery.addDiscoveryListener ( this );44 }45 46 // handle exception discovering lookup services47 catch ( IOException exception ) {48 exception.printStackTrace();49 }50 51 getContentPane().add( new JScrollPane( outputArea ), 52 BorderLayout.CENTER ); 53 }54 55 // receive notification of found lookup services56 public void discovered ( DiscoveryEvent event )57 { 58 // get the ServiceRegistrars for found lookup services59 ServiceRegistrar[] registrars = event.getRegistrars();60 int order = 0;61
3. Constructor
3.1 multicast discover lookup service
3.2 add listener
4. Receive notification
Discover public lookup services
Register to receive discovery notifications
Receive notification when a valid lookup service is found
2001 Prentice Hall, Inc.All rights reserved.
Outline62 // get the information for each lookup service found63 for ( int i = 0; i < registrars.length ; i++ ) {64 ServiceRegistrar registrar = registrars[ i ];65 66 if ( registrar != null ) {67 68 // append information about discovered services69 // to outputArea70 try {71 order = servicesFound + i + 1;72 73 // get the hostname and port number74 Runnable appender = new TextAppender(75 "Lookup Service " + order + ":\n" +76 " Host: " + 77 registrar.getLocator().getHost() + "\n" +78 "\n Port: " + 79 registrar.getLocator().getPort() + "\n" +80 " Group support: " );81 82 // append to outputArea on event-dispatch thread83 SwingUtilities.invokeLater( appender );84 85 // get the group(s) the lookup service served86 String[] groups = registrar.getGroups();87 88 StringBuffer names = new StringBuffer();89 90 // get the group names, if empty write public91 for ( int j = 0; j < groups.length ; j++ ) {92 93 if ( groups[ j ].equals( "" ) )94 names.append( "public\t" );95 else96 names.append( groups[ j ] + "\t" );97 }
4.1 get lookup service information
4.2 append output
Get lookup service port number
Get lookup service hostname
Get lookup service group name
2001 Prentice Hall, Inc.All rights reserved.
Outline98 99 // append group names to outputArea100 SwingUtilities.invokeLater( 101 new TextAppender( names + "\n" ) );102 }103 104 // handle exception communicating with ServiceRegistrar105 catch ( RemoteException exception ) {106 exception.printStackTrace();107 }108 }109 }110 111 // update number of services found112 servicesFound = order;113 114 } // end method discovered115 116 // receive notification of discarded lookup services that117 // are no longer valid118 public void discarded( DiscoveryEvent event ) 119 {120 ServiceRegistrar[] discardedRegistrars = 121 event.getRegistrars();122 123 SwingUtilities.invokeLater( 124 new TextAppender( "Number of discarded registrars: " +125 discardedRegistrars.length + "\n" ) );126 }127
4.3 GUI
5 get invalid lookup service
5.1 GUI
Receive notification when a lookup service becomes invalid
2001 Prentice Hall, Inc.All rights reserved.
Outline128 // TextAppender is a Runnable class for appending129 // text to outputArea on the event-dispatching thread.130 private class TextAppender implements Runnable {131 132 private String textToAppend; // text to append to outputArea133 134 // TextAppender constructor135 public TextAppender( String text )136 {137 textToAppend = text;138 }139 140 // append text to outputArea and scroll to bottom141 public void run()142 {143 outputArea.append( textToAppend );144 outputArea.setCaretPosition( 145 outputArea.getText().length() );146 }147 148 } // end inner class TextAppender149 150 // launch MulticastDiscovery application151 public static void main( String args[] ) 152 {153 // set SecurityManager154 if ( System.getSecurityManager() == null )155 System.setSecurityManager(156 new RMISecurityManager() );157 158 MulticastDiscovery discovery = new MulticastDiscovery();159 discovery.setDefaultCloseOperation( EXIT_ON_CLOSE );160 discovery.pack();161 discovery.setVisible( true );162 }163 }
6. Inner class TextAppender
7. Main
7.1 set security manager
Set security manager
Inner class for appending text to output area on the event-dispatching thread
2001 Prentice Hall, Inc.All rights reserved.
Outline
Program output
2001 Prentice Hall, Inc. All rights reserved.
22.7 Jini Service and Client Implementations
• Jini service– Service proxy
– Backend interface
– Service implementation
• Jini client– Only knows service’s public interface
2001 Prentice Hall, Inc. All rights reserved.
22.7.1 Service Interfaces and Supporting Classes
• Service Interfaces– SeminarInterface (public interface)– BackendInterface (unknown to client)
• Supporting classes– Seminar
2001 Prentice Hall, Inc.All rights reserved.
Outline1 // Seminar.java2 // Seminar represents a seminar, or lecture, including the 3 // Seminar title and location.4 package com.deitel.advjhtp1.jini.seminar;5 6 // Java core package7 import java.io.Serializable;8 9 public class Seminar implements Serializable10 {11 private String title;12 private String location;13 private static final long serialVersionUID = 20010724L;14 15 // Seminar constructor16 public Seminar( String seminarTitle, String seminarLocation )17 {18 title = seminarTitle;19 location = seminarLocation;20 }21 22 // get String representation of Seminar object23 public String toString()24 {25 return "Seminar title: " + getTitle() + 26 "; location: " + getLocation();27 }28 29 // get Seminar title30 public String getTitle()31 {32 return title;33 }34 35 // get Seminar location36 public String getLocation()37 {38 return location;39 }40 }
1. Constructor
2. Methods
Explicitly specify the serial version UID
Specify the title and location of a seminar
2001 Prentice Hall, Inc.All rights reserved.
Outline1 // SeminarInterface.java2 // SeminarInterface defines methods available from the SeminarInfo3 // Jini service.4 package com.deitel.advjhtp1.jini.seminar.service;5 6 // Java core packages7 import java.rmi.Remote;8 9 // Deitel packages10 import com.deitel.advjhtp1.jini.seminar.Seminar;11 12 public interface SeminarInterface {13 14 // get Seminar for given date15 public Seminar getSeminar( String date );16 } ------------------------------------------------------------------------1 // BackendInterface.java2 // BackendInterface defines the interface through which the 3 // service proxy communicates with the back-end service.4 package com.deitel.advjhtp1.jini.seminar.service;5 6 // Java core packages7 import java.rmi.Remote;8 9 // Deitel packages10 import com.deitel.advjhtp1.jini.seminar.Seminar;11 12 public interface BackendInterface extends Remote {13 14 // get Seminar for given day of the week15 public Seminar getSeminar( String date ) throws RemoteException;16 }
InterfaceSeminarInterface
InterfaceBackendInterface
Public interface
Service proxy’s interfaceunknown to client
2001 Prentice Hall, Inc. All rights reserved.
22.7.2 Service Proxy and Service Implementations
• Service Proxy– SeminarProxy
• Service Implementation– SeminarInfo
2001 Prentice Hall, Inc.All rights reserved.
Outline1 // SeminarProxy.java2 // SeminarProxy is a proxy for the SeminarInfo Jini service. 3 package com.deitel.advjhtp1.jini.seminar.service;4 5 // Java core packages6 import java.io.Serializable;7 import java.rmi.*;8 9 // Deitel packages10 import com.deitel.advjhtp1.jini.seminar.Seminar;11 12 public class SeminarProxy implements SeminarInterface, 13 Serializable {14 15 private BackendInterface backInterface;16 17 // SeminarProxy constructor18 public SeminarProxy( BackendInterface inputInterface )19 {20 backInterface = inputInterface;21 }22 23 // get Seminar for given date through BackendInterface24 public Seminar getSeminar( String date )25 {26 // get Seminar from service through BackendInterface27 try {28 return backInterface.getSeminar( date );29 }30 31 // handle exception communicating with back-end service32 catch ( RemoteException remoteException ) {33 remoteException.printStackTrace();34 }35 36 return null;37 38 } // end method getSeminar39 }
ClassSeminarProxy
1. Constructor
2. Methods
Communicates through interface BackendInterface using RMI
Seminar service proxy implements the public interface SeminarInterface
2001 Prentice Hall, Inc.All rights reserved.
Outline
1 // SeminarInfo.java2 // SeminarInfo is a Jini service that provides information3 // about Seminars offered throughout the week.4 package com.deitel.advjhtp1.jini.seminar.service;5 6 // Java core packages7 import java.io.*;8 import java.rmi.server.UnicastRemoteObject;9 import java.rmi.RemoteException;10 import java.util.StringTokenizer;11 12 // Deitel packages13 import com.deitel.advjhtp1.jini.seminar.Seminar;14 15 public class SeminarInfo extends UnicastRemoteObject 16 implements BackendInterface {17 18 // Strings that represent days of the week19 private static final String MONDAY = "MONDAY";20 private static final String TUESDAY = "TUESDAY";21 private static final String WEDNESDAY = "WEDNESDAY";22 private static final String THURSDAY = "THURSDAY";23 private static final String FRIDAY = "FRIDAY";24 25 // SeminarInfo no-argument constructor26 public SeminarInfo() throws RemoteException {}27
ClassSeminarInfo
1. Import packages
2. Declaration
3. Constructor
RMI object
2001 Prentice Hall, Inc.All rights reserved.
Outline28 // get Seminar information for given day 29 public Seminar getSeminar( String date ) 30 throws RemoteException 31 {32 String[] titles = new String[] { "", "", "", "", "" };33 String[] locations = new String[] { "", "", "", "", "" };34 35 // read seminar information from text file36 try {37 String fileName = SeminarInfo.class.getResource(38 "SeminarInfo.txt" ).toString();39 fileName = fileName.substring( 6 );40 41 FileInputStream inputStream = 42 new FileInputStream( fileName );43 44 BufferedReader reader = new BufferedReader(45 new InputStreamReader( inputStream ));46 47 String line = reader.readLine();48 49 // read seminar info from the file50 for ( int lineNo = 0; ( line != null ) 51 && ( lineNo < 5 ); lineNo++ ) { 52 StringTokenizer tokenizer = 53 new StringTokenizer( line, ";" ); 54 55 titles[ lineNo ] = tokenizer.nextToken();56 locations[ lineNo ] = tokenizer.nextToken();57 line = reader.readLine();58 }59 }60
4. Get seminar information
4.1 load text file
4.2 read seminar info
Load text file that contains seminar data
Read seminar data
2001 Prentice Hall, Inc.All rights reserved.
Outline61 // handle exception loading Seminar file62 catch ( FileNotFoundException fileException ) {63 fileException.printStackTrace();64 }65 66 // handle exception reading from Seminar file67 catch ( IOException ioException ) {68 ioException.printStackTrace();69 }70 71 // match given day of the week to available seminars72 if ( date.equalsIgnoreCase( MONDAY ) ) {73 return new Seminar( titles[ 0 ], locations[ 0 ] );74 } 75 else if ( date.equalsIgnoreCase( TUESDAY ) ) {76 return new Seminar( titles[ 1 ], locations[ 1 ] );77 } 78 else if ( date.equalsIgnoreCase( WEDNESDAY ) ) {79 return new Seminar( titles[ 2 ], locations[ 2 ] );80 } 81 else if ( date.equalsIgnoreCase( THURSDAY ) ) {82 return new Seminar( titles[ 3 ], locations[ 3 ] );83 }84 else if ( date.equalsIgnoreCase( FRIDAY ) ) {85 return new Seminar( titles[ 4 ], locations[ 4 ] );86 }87 else {88 return new Seminar( "Empty", "Not available" );89 }90 91 } // end method getSeminar92 }------------------------------------------------------------------1 Advanced Swing GUI Components; Deitel Seminar Room2 Model-View-Controller Architecture; Deitel Seminar Room3 Java 2 Enterprise Edition; Deitel Seminar Room4 Introduction to Jini; Deitel Seminar Room5 Java 2 Micro Edition; Deitel Seminar Room
4.3 return result
Seminar text file
Return seminar information
Content of SeminarInfo.txt
2001 Prentice Hall, Inc. All rights reserved.
22.7.3 Registering the Service with Lookup Service
• SeminarInfoService– Multicast discovery for lookup services
– Registers the SeminarInfo service with lookup services
2001 Prentice Hall, Inc.All rights reserved.
Outline1 // SeminarInfoService.java2 // SeminarInfoService discovers lookup services and registers3 // the SeminarInfo service with those lookup services.4 package com.deitel.advjhtp1.jini.seminar.service;5 6 // Java core packages7 import java.rmi.RMISecurityManager;8 import java.rmi.RemoteException;9 import java.io.IOException;10 11 // Jini core packages12 import net.jini.core.lookup.*;13 import net.jini.core.entry.Entry;14 15 // Jini extension packages16 import net.jini.discovery.*;17 import net.jini.lookup.entry.Name;18 19 public class SeminarInfoService implements DiscoveryListener {20 21 private ServiceItem serviceItem;22 private final int LEASETIME = 10 * 60 * 1000;23 24 // SeminarInfoService constructor25 public SeminarInfoService()26 {27 // search for lookup services with public group28 try {29 LookupDiscovery discover = 30 new LookupDiscovery( new String[] { "" } );31 32 // add listener for DiscoveryEvents33 discover.addDiscoveryListener( this );34 }35 36 // handle exception creating LookupDiscovery
ClassSeminarInfoService
1. Import packages
2. Constructor
2.1 discover lookup services
Search for public lookup services with multicast discovery
Implements DiscoveryListener to receive notifications of discovered services
2001 Prentice Hall, Inc.All rights reserved.
Outline37 catch ( IOException exception ) {38 exception.printStackTrace();39 }40 41 // create an Entry for this service42 Entry[] entries = new Entry[ 1 ];43 entries[ 0 ] = new Name( "Seminar" );44 45 // set the service's proxy and Entry name46 serviceItem = new ServiceItem(47 null, createProxy(), entries );48 49 } // end SeminarInfoService constructor50 51 // receive lookup service discovery notifications52 public void discovered( DiscoveryEvent event )53 {54 ServiceRegistrar[] registrars = event.getRegistrars();55 56 // register service with each lookup service57 for ( int i = 0; i < registrars.length; i++ ) {58 ServiceRegistrar registrar = registrars[ i ];59 60 // register service with discovered lookup service61 try {62 ServiceRegistration registration = 63 registrar.register( serviceItem, LEASETIME );64 } 65 66 // catch the remote exception67 catch ( RemoteException exception) {68 exception.printStackTrace();69 }70 71 } // end for72 73 } // end method discovered
2.2 specify service item
3. Register service with lookup service
Name Entry
Specify service item
Lookup service found
Register service with lookup service
2001 Prentice Hall, Inc.All rights reserved.
Outline
74 75 // ignore discarded lookup services76 public void discarded( DiscoveryEvent event ) {}77 78 // create the seminar service proxy79 private SeminarInterface createProxy()80 {81 // get BackendInterface for service and create SeminarProxy82 try {83 return new SeminarProxy( new SeminarInfo() );84 }85 86 // handle exception creating SeminarProxy87 catch ( RemoteException exception ) {88 exception.printStackTrace();89 }90 91 return null;92 93 } // end method discovered94
4. Ignore invalid lookup service
5. Create service proxy
Return service proxy
2001 Prentice Hall, Inc.All rights reserved.
Outline
95 // method main keeps the application alive96 public static void main( String args[] )97 {98 // set SecurityManager99 if ( System.getSecurityManager() == null )100 System.setSecurityManager( new RMISecurityManager() );101 102 new SeminarInfoService();103 104 Object keepAlive = new Object();105 106 synchronized ( keepAlive ) {107 108 // keep application alive 109 try {110 keepAlive.wait();111 }112 113 // handle exception if wait interrupted114 catch ( InterruptedException exception ) {115 exception.printStackTrace();116 }117 }118 119 } // end method main120 }
6. main
6.1 set security manager
6.2 keep application alive
Keep application alive
2001 Prentice Hall, Inc. All rights reserved.
22.7.4 Jini Service Client
• UnicastSeminarInfoClient– Discover lookup service with unicast discovery
– Search for seminar service
– Get seminar info
2001 Prentice Hall, Inc.All rights reserved.
Outline1 // UnicastSeminarInfoClient.java2 // UnicastSeminarInfoClient uses unicast discovery to locate3 // lookup servides for the SeminarInfo service.4 package com.deitel.advjhtp1.jini.seminar.client;5 6 // Java core packages7 import java.awt.*;8 import java.awt.event.*;9 import java.io.*;10 import java.rmi.*;11 import java.net.*;12 import java.util.*;13 14 // Java extension packages15 import javax.swing.*;16 17 // Jini core packages18 import net.jini.core.discovery.LookupLocator;19 import net.jini.core.lookup.*;20 import net.jini.core.entry.Entry;21 22 // Jini extension packages23 import net.jini.lookup.entry.Name;24 25 // Deitel packages26 import com.deitel.advjhtp1.jini.seminar.Seminar;27 import com.deitel.advjhtp1.jini.seminar.service.SeminarInterface;28 29 public class UnicastSeminarInfoClient extends JFrame {30 31 // Strings representing the days of the week on which 32 // Seminars are offered33 private static final String[] days = { "Monday", "Tuesday",34 "Wednesday", "Thursday", "Friday" };35 36 // hostname and ServiceRegistrar for lookup services37 private String hostname;38 private ServiceRegistrar registrar;39
ClassUnicastSeminarInfoClient
1. Import packages
2. Declarations
2001 Prentice Hall, Inc.All rights reserved.
Outline40 // JButton for finding Seminars41 private JButton findSeminarButton;42 43 // UnicastSeminarInfoClient constructor44 public UnicastSeminarInfoClient( String host )45 {46 super( "UnicastSeminarInfoClient" );47 48 hostname = host; // set target hostname for discovery49 50 // create JButton for finding Seminars51 findSeminarButton = new JButton( "Find Seminar" );52 findSeminarButton.addActionListener(53 54 new ActionListener() {55 56 // discover lookup services, look up SeminarInfo57 // service, prompt user for desired day of the 58 // week and display available Seminars59 public void actionPerformed( ActionEvent event )60 {61 discoverLookupServices();62 63 SeminarInterface seminarService = 64 lookupSeminarService();65 66 String day = ( String ) JOptionPane.showInputDialog( 67 UnicastSeminarInfoClient.this, "Select Day", 68 "Day Selection", JOptionPane.QUESTION_MESSAGE, 69 null, days, days[ 0 ] );70 71 showSeminars( seminarService, day ); 72 }73 }74 75 ); // end call to addActionListener
3. Constructor
3.1 GUI
Get user-specified day
2001 Prentice Hall, Inc.All rights reserved.
Outline
76 77 JPanel buttonPanel = new JPanel();78 buttonPanel.add( findSeminarButton );79 80 getContentPane().add( buttonPanel, BorderLayout.CENTER );81 82 } // end UnicastSeminarInfoClient constructor83 84 // discover lookup services using unicast discovery85 private void discoverLookupServices()86 {87 String lookupURL = "jini://" + hostname + "/";88 89 // Get the lookup service locator at jini://hostname 90 // use default port91 try {92 LookupLocator locator = new LookupLocator( lookupURL );93 94 // return registrar95 registrar = locator.getRegistrar();96 } 97 98 // handle exceptions discovering lookup services99 catch ( Exception exception ) {100 exception.printStackTrace();101 }102 103 } // end method discoverLookupServices104
4. Discover lookup service
4.1 specify lookup URL
4.2 get lookup locator and registrar
Specify lookup URL
Get lookup locator and registrar
2001 Prentice Hall, Inc.All rights reserved.
Outline105 // lookup SeminarInfo service in given ServiceRegistrar106 private SeminarInterface lookupSeminarService()107 {108 // specify the service requirement109 Class[] types = new Class[] { SeminarInterface.class };110 Entry[] attribute = new Entry[] { new Name( "Seminar" ) };111 ServiceTemplate template = 112 new ServiceTemplate( null, types, attribute );113 114 // find the service 115 try {116 SeminarInterface seminarInterface = 117 ( SeminarInterface ) registrar.lookup( template );118 return seminarInterface;119 } 120 121 // handle exception looking up SeminarInfo service122 catch ( RemoteException exception ) {123 exception.printStackTrace();124 }125 126 return null; 127 128 } // end method lookupSeminarService129 130 // show Seminar in given SeminarInfo service for given 131 // day of the week 132 private void showSeminars( SeminarInterface seminarService, 133 String day )134 {135 StringBuffer buffer = new StringBuffer();136
5. Search for service
5.1 specify service requirement
5.2 lookup service
6. Display result
Service requirement
Lookup service
2001 Prentice Hall, Inc.All rights reserved.
Outline
137 // get Seminar from SeminarInfo service 138 if ( seminarService != null ) {139 Seminar seminar = seminarService.getSeminar( day );140 141 // get subject and location from Seminar object142 buffer.append( "Seminar information: \n" );143 buffer.append( day + ":\n" );144 buffer.append( seminar.getTitle() + "\n" ); // title145 buffer.append( seminar.getLocation() ); // location146 }147 else // SeminarInfo service does not available148 buffer.append( 149 "SeminarInfo service does not available. \n" );150 151 // display Seminar information152 JOptionPane.showMessageDialog( this, buffer );153 154 } // end method showSeminars155 156 // launch UnicastSeminarInfoClient application157 public static void main ( String args[] )158 {159 // check command-line arguments for hostname160 if ( args.length != 1 ) {161 System.err.println( 162 "Usage: java UnicastSeminarInfoClient hostname" );163 }164
6.1 append output
6.2 display output
7. main
Display output
Get seminar title and location
2001 Prentice Hall, Inc.All rights reserved.
Outline165 // create UnicastSeminarInfoClient for given hostname166 else {167 System.setSecurityManager( new RMISecurityManager() );168 169 UnicastSeminarInfoClient client = 170 new UnicastSeminarInfoClient( args[ 0 ] );171 172 client.setDefaultCloseOperation( EXIT_ON_CLOSE );173 client.pack();174 client.setSize( 250, 65 );175 client.setVisible( true );176 }177 178 } // end method main179 }
Program output
2001 Prentice Hall, Inc. All rights reserved.
22.7.4 Jini Service Client
• Preparing JAR files– Class files for the Jini service
• SeminarService.jar
– Class files for the Jini client• SeminarClient.jar
– Downloadable Jini service class files.• SeminarServiceDownload.jar
• Starting rmid, web server and lookup service• Launching SeminarInfoService• Launching UnicastSeminarInfoService
2.3 discover lookup services using LookupLocatorDiscovery
30 // UnicastDiscoveryUtility constructor31 public UnicastDiscoveryUtility( String urls[] )32 {33 super( "UnicastDiscoveryUtility" );34 35 getContentPane().add( new JScrollPane( outputArea ), 36 BorderLayout.CENTER );37 38 // discover lookup services using LookupLocatorDiscovery39 try {40 41 // create LookupLocator for each URL42 LookupLocator locators[] = 43 new LookupLocator[ urls.length ];44 45 for ( int i = 0; i < locators.length ; i++ ) 46 locators[ i ] = new LookupLocator( urls[ i ] );47 48 // create LookupLocatorDiscovery object49 LookupLocatorDiscovery locatorDiscovery = 50 new LookupLocatorDiscovery( locators );51 52 // register DiscoveryListener53 locatorDiscovery.addDiscoveryListener( this );54 55 } // end try56 57 // handle invalid Jini URL58 catch ( MalformedURLException exception ) {59 exception.printStackTrace();60 } 61 62 } // end UnicastDiscoveryUtility constructor63
Specify multiple lookup locators for unicast discovery
Create LookupLocatorDiscovery object
Add listener
2001 Prentice Hall, Inc.All rights reserved.
Outline
3. Lookup services found
4. Display lookup service info
64 // receive notification of found lookup services65 public void discovered( DiscoveryEvent event )66 {67 // get the proxy registrars for those services68 ServiceRegistrar[] registrars = event.getRegistrars();69 70 // display information for each lookup service found71 for ( int i = 0; i < registrars.length ; i++ ) 72 displayServiceDetails( registrars[ i ] );73 74 } // end method discovered75 76 // display details of given ServiceRegistrar77 private void displayServiceDetails( ServiceRegistrar registrar )78 {79 try {80 final StringBuffer buffer = new StringBuffer();81 82 // get the hostname and port number83 buffer.append( "Lookup Service: " );84 buffer.append( "\n Host: " + 85 registrar.getLocator().getHost() );86 buffer.append( "\n Port: " + 87 registrar.getLocator().getPort() );88 buffer.append( "\n Group support: " );89 90 // get lookup service groups91 String[] groups = registrar.getGroups();92
Found lookup services
Lookup service host
Lookup service port number
2001 Prentice Hall, Inc.All rights reserved.
Outline
4.1 append output
4.2 GUI
93 // get group names; if empty write public94 for ( int i = 0; i < groups.length ; i++ ) {95 96 if ( groups[ i ].equals( "" ) )97 buffer.append( "public," );98 99 else100 buffer.append( groups[ i ] + "," );101 }102 103 buffer.append( "\n\n" );104 105 // append information to outputArea106 SwingUtilities.invokeLater(107 108 // create Runnable for appending text109 new Runnable() {110 111 // append text and update caret position112 public void run()113 {114 outputArea.append( buffer.toString() );115 outputArea.setCaretPosition( 116 outputArea.getText().length() );117 }118 } 119 120 ); // end call to invokeLater121 122 } // end try123 124 // handle exception communicating with lookup service125 catch ( RemoteException exception ) {126 exception.printStackTrace();127 } 128 129 } // end method displayServiceDetails
Lookup service group name
Append output
2001 Prentice Hall, Inc.All rights reserved.
Outline
4.3 ignore invalid lookup service
5. main
130 131 // ignore discarded lookup services132 public void discarded( DiscoveryEvent event ) {}133 134 // launch UnicastDiscoveryUtility application135 public static void main( String args[] ) 136 {137 // set SecurityManager138 if ( System.getSecurityManager() == null )139 System.setSecurityManager( new RMISecurityManager() );140 141 // check command-line arguments for hostnames142 if ( args.length < 1 ) {143 System.err.println( 144 "Usage: java UnicastDiscoveryUtility " +145 "jini://hostname:port [ jini://hostname:port ] ..." );146 }147 148 // launch UnicastDiscoveryUtility for set of hostnames149 else {150 UnicastDiscoveryUtility unicastUtility = 151 new UnicastDiscoveryUtility( args );152 153 unicastUtility.setDefaultCloseOperation( EXIT_ON_CLOSE );154 unicastUtility.setSize( 300, 300 );155 unicastUtility.setVisible( true );156 }157 158 } // end method main159 }
32 // GeneralDiscoveryUtility constructor33 public GeneralDiscoveryUtility( String urls[] )34 {35 super( "GeneralDiscoveryUtility" );36 37 // lay out JTextAreas38 JPanel multicastPanel = new JPanel();39 multicastPanel.setBorder( 40 new TitledBorder( "Multicast (Group) Notifications" ) );41 multicastPanel.add( new JScrollPane( multicastArea ) );42 43 JPanel unicastPanel = new JPanel();44 unicastPanel.setBorder( 45 new TitledBorder( "Unicast (Locator) Notifications" ) );46 unicastPanel.add( new JScrollPane( unicastArea ) );47 48 Container contentPane = getContentPane();49 contentPane.setLayout( new FlowLayout() );50 contentPane.add( unicastPanel );51 contentPane.add( multicastPanel ); 52 53 // get LookupLocators and LookupDiscoveryManager54 try {55 LookupLocator locators[] = 56 new LookupLocator[ urls.length ];57 58 // get array of LookupLocators59 for ( int i = 0; i < urls.length ; i++ ) 60 locators[ i ] = new LookupLocator( urls[ i ] );61 62 // instantiate a LookupDiscoveryManager object63 lookupManager = new LookupDiscoveryManager( 64 DiscoveryGroupManagement.ALL_GROUPS, locators, this );65 }66
Lookup locators for unicast
Multicast group Unicast
LookupLocators
Output area for multicast discovery
Output area for unicast discovery
2001 Prentice Hall, Inc.All rights reserved.
Outline
3.4 handle exceptions
4. Receive notifications
4.1 get lookup service proxy registrar
4.2 display lookup service info
67 // handle invalid Jini URL68 catch ( MalformedURLException exception ) {69 exception.printStackTrace();70 }71 72 // handle exception creating LookupDiscoveryManager73 catch ( IOException exception ) {74 exception.printStackTrace();75 }76 77 } // end GeneralDiscoveryUtility constructor78 79 // receive notifications of discovered lookup services.80 public void discovered( DiscoveryEvent event )81 {82 // get the proxy registrars for those services83 ServiceRegistrar[] registrars = event.getRegistrars();84 85 // display information for each lookup service found86 for ( int i = 0; i < registrars.length ; i++ ) {87 88 // display multicast results in multicastArea89 if ( lookupManager.getFrom( registrars[ i ] ) ==90 LookupDiscoveryManager.FROM_GROUP ) {91 92 displayServiceDetails( registrars[ i ],93 multicastArea );94 }95 96 // display unicast results in unicastArea97 else98 displayServiceDetails( registrars[ i ], unicastArea );99 }100 101 } // end method discovered102
Display multicast discovered lookup services
Display unicast discovered lookup services
2001 Prentice Hall, Inc.All rights reserved.
Outline
5. Display details of lookup service
5.1 append output
103 // display details of given ServiceRegistrar104 private void displayServiceDetails( 105 ServiceRegistrar registrar, final JTextArea outputArea )106 {107 try {108 final StringBuffer buffer = new StringBuffer();109 110 // get hostname and port number111 buffer.append( "Lookup Service: " );112 buffer.append( "\n Host: " + 113 registrar.getLocator().getHost() );114 buffer.append( "\n Port: " + 115 registrar.getLocator().getPort() );116 buffer.append( "\n Group support: " );117 118 // get lookup service groups119 String[] groups = registrar.getGroups();120 121 // get group names; if empty write public122 for ( int i = 0; i < groups.length ; i++ ) {123 124 if ( groups[ i ].equals( "" ) )125 buffer.append( "public," );126 127 else128 buffer.append( groups[ i ] + "," );129 }130 131 buffer.append( "\n\n" );132
Lookup service host
Lookup service port
Lookup service groups
2001 Prentice Hall, Inc.All rights reserved.
Outline
5.2 GUI
6. Ignore invalid lookup service
133 // append information to outputArea134 SwingUtilities.invokeLater(135 136 // create Runnable for appending text137 new Runnable() {138 139 // append text and update caret position140 public void run()141 {142 outputArea.append( buffer.toString() );143 outputArea.setCaretPosition( 144 outputArea.getText().length() );145 }146 } 147 148 ); // end call to invokeLater149 150 } // end try151 152 // handle exception communicating with lookup service153 catch ( RemoteException exception ) {154 exception.printStackTrace();155 } 156 157 } // end method displayServiceDetails158 159 // receive discarded lookup service notifications160 public void discarded( DiscoveryEvent event ) {}161
2001 Prentice Hall, Inc.All rights reserved.
Outline
7. Main
program output
162 // launch GeneralDiscoveryUtility application163 public static void main( String[] args ) 164 {165 // set SecurityManager166 if ( System.getSecurityManager() == null )167 System.setSecurityManager( new RMISecurityManager() );168 169 // launch GeneralDiscoveryUtility for set of hostnames170 GeneralDiscoveryUtility utility = 171 new GeneralDiscoveryUtility( args );172 utility.setDefaultCloseOperation( EXIT_ON_CLOSE );173 utility.pack();174 utility.setVisible( true );175 176 } // end method main177 }
Exit when window closes
2001 Prentice Hall, Inc. All rights reserved.
22.8.2 Entry Utilities
• Standard Jini Entry attributes• Custom defined Entry attributes
2001 Prentice Hall, Inc. All rights reserved.
22.8.2 Entry Utilities
Attribute Description Address Specifies the physical location of a service. (e.g., the city and street
address of an Automated Teller Machine). Comment Provides general descriptive comments about a service. Location Provides more detailed location information, such as floor, suite and
room number. Name Provides the service’s name, suitable for use by people to identify a
service (e.g., "BankABC ATM"). ServiceInfo Provides basic information about a service. For example, the
manufacturer and model number of a printer. ServiceType Provides a human-understandable description of the service type (e.g.,
"Print Queue"). Status Describes the current status of the service in varying levels of severity. Fig. 22.33 Standard J ini Entry attributes.
2001 Prentice Hall, Inc.All rights reserved.
Outline
ClassSeminarProvider
1. No-argument constructor
2. Other constructor
1 // SeminarProvider.java2 // SeminarProvider is an Entry object for the SeminarInfo service.3 package com.deitel.advjhtp1.jini.utilities.entry;4 5 // Jini extension package6 import net.jini.entry.*;7 import net.jini.lookup.entry.*;8 9 public class SeminarProvider extends AbstractEntry 10 implements ServiceControlled11 {12 public String providerName = "";13 14 // no-argument constructor15 public SeminarProvider() {}16 17 // SeminarProvider constructor for specifying providerName18 public SeminarProvider( String provider )19 {20 providerName = provider;21 }22 }
No-argument constructor
Other constructor
Public field
2001 Prentice Hall, Inc. All rights reserved.
22.8.3 Lease Utilities
• Why leasing?– Self-healing
– Recover from commonplace problems
• Leasing strategy– Renew leases until service terminates
• Helper class– LeaseRenewalManager
2001 Prentice Hall, Inc.All rights reserved.
Outline
ClassSeminarInfoLeaseService
1. Import packages
2. Declarations
1 // SeminarInfoLeaseService.java2 // SeminarInfoLeaseService discovers lookup services, registers3 // the SeminarInfo service, and creates a LeaseRenewalManager4 // to maintain the SeminarInfo service lease.5 package com.deitel.advjhtp1.jini.utilities.leasing;6 7 // Java core packages8 import java.rmi.RMISecurityManager;9 import java.rmi.RemoteException;10 import java.io.IOException;11 12 // Jini core packages13 import net.jini.core.lookup.*;14 import net.jini.core.entry.Entry;15 import net.jini.core.lease.Lease;16 17 // Jini extension packages18 import net.jini.discovery.*;19 import net.jini.lookup.entry.Name;20 import net.jini.lease.LeaseRenewalManager;21 22 // Deitel packages23 import com.deitel.advjhtp1.jini.seminar.service.*;24 import com.deitel.advjhtp1.jini.utilities.entry.SeminarProvider;25 26 public class SeminarInfoLeaseService implements DiscoveryListener {27 28 private LookupDiscovery discover;29 private ServiceItem item;30 private static final int LEASETIME = 10 * 60 * 1000;31
2001 Prentice Hall, Inc.All rights reserved.
Outline
3. Constructor
3.1 multicast discovers lookup services
3.2 specify service
32 // SeminarInfoLeaseService constructor33 public SeminarInfoLeaseService()34 {35 // search for lookup services with public group36 try {37 discover = new LookupDiscovery( new String[] { "" } );38 39 // register DiscoveryListener40 discover.addDiscoveryListener( this );41 }42 43 // handle exception creating LookupDiscovery44 catch ( IOException exception ) {45 exception.printStackTrace();46 }47 48 // create and set Entry name for service49 Entry[] entries = new Entry[ 1 ];50 entries[ 0 ] = new SeminarProvider( "Deitel" );51 52 // specify the service's proxy and entry53 item = new ServiceItem( null, createProxy(), entries );54 55 } // end SeminarInfoLeaseService constructor56
Multicast discovery
Specify service
2001 Prentice Hall, Inc.All rights reserved.
Outline
4. Found lookup service
4.1 register service
4.2 renew service’s lease
57 // receive notifications of discovered lookup services58 public void discovered ( DiscoveryEvent event )59 {60 ServiceRegistrar[] registrars = event.getRegistrars();61 62 // register the service with the lookup service63 for ( int i = 0; i < registrars.length; i++ ) {64 65 ServiceRegistrar registrar = registrars[ i ];66 67 // register the service with the lookup service68 try {69 ServiceRegistration registration = 70 registrar.register( item, LEASETIME );71 72 // create LeaseRenewalmanager73 LeaseRenewalManager leaseManager = 74 new LeaseRenewalManager();75 76 // renew SeminarInfo lease indefinitely77 leaseManager.renewUntil( registration.getLease(), 78 Lease.FOREVER, null );79 80 } // end try 81 82 // handle exception registering ServiceItem83 catch ( RemoteException exception ) {84 exception.printStackTrace();85 } 86 87 } // end for88 89 } // end method discovered90
Register service
Renew service’s lease
2001 Prentice Hall, Inc.All rights reserved.
Outline
5. Ignore invalid lookup service
6. Create service proxy
91 // ignore discarded lookup services92 public void discarded( DiscoveryEvent event ) {}93 94 // create seminar service proxy95 private SeminarInterface createProxy()96 {97 // get BackendInterface reference to SeminarInfo98 try {99 BackendInterface backInterface = new SeminarInfo();100 101 return new SeminarProxy( backInterface );102 }103 104 // handle exception creating SeminarProxy105 catch ( RemoteException exception ) {106 exception.printStackTrace();107 }108 109 return null;110 111 } // end method createProxy112
Return service proxy
2001 Prentice Hall, Inc.All rights reserved.
Outline
7. main
7.1 set security manager
7.2 keep application alive
113 // launch SeminarInfoLeaseService114 public static void main( String args[] )115 {116 // set SecurityManager117 if ( System.getSecurityManager() == null ) {118 System.setSecurityManager( new RMISecurityManager() );119 }120 121 SeminarInfoLeaseService service = 122 new SeminarInfoLeaseService();123 124 Object keepAlive = new Object();125 126 // wait on keepAlive Object to keep service running127 synchronized ( keepAlive ) { 128 129 // keep application alive130 try {131 keepAlive.wait();132 }133 134 // handle exception if wait interrupted135 catch ( InterruptedException exception ) {136 exception.printStackTrace();137 }138 139 } // end synchronized block140 141 } // end method main142 }