• The Jini distribution comes with three services that must be running correctly before executing Jiniapplications—a Web server to enable Jini clients to download class files through RMI
Trang 1In method discovered, lines 69–70 register the SeminarInfo service’s ceItem with the discovered ServiceRegistrar Lines 73–74 create a new Lease- RenewalManager , which class SeminarInfoLeaseService uses to manage the SeminarInfo service’s lease Lines 77–78 invoke method renewUntil of class LeaseRenewalManager Method renewUntil takes as its first argument the Lease object to be renewed In this example, we obtain the Lease object by invoking method getLease of class ServiceRegistration The second argument specifies the desired expiration time (in milliseconds) for renewed Leases Line 78 specifies the con- stant Lease.FOREVER to request a Lease that never expires This does not guarantee that the lookup service will provide an everlasting Lease—the lookup service is free to
Servi-grant a lease that is shorter than the requested length The third argument to method
renewUntil is the LeaseListener, to notify of problems encountered when renewing the Lease We pass null as the third argument to disregard such notifications.
To run the SeminarInfo Jini service with lease management, create a new JAR file named SeminarServiceWithLeasing.jar Figure 22.36 shows the contents of SeminarServiceWithLeasing.jar Note that this JAR file replaces Seminar- InfoService.class with SeminarInfoLeaseService.class Note also that
134 // handle exception if wait interrupted
135 catch ( InterruptedException exception ) {
Fig 22.35 SeminarInfoLeaseService uses class LeaseRenewalManager
to manage SeminarInfo service leasing (part 4 of 4)
Trang 2this JAR file includes SeminarProvider.class, which is our custom Entry object for the SeminarInfo service.
After packaging the classes in SeminarServiceWithLeasing.jar, run the
new version of the service by typing the following command at a command prompt:
java -classpath %CLASSPATH%;SeminarServiceWithLeasing.jar -Djava.security.policy=policy
-Djava.rmi.server.codebase=http://hostname:9090/
SeminarServiceDownload.jar
com.deitel.advjhtp1.jini.utilities.leasing.
SeminarInfoLeaseService
where policy is an appropriate security policy and hostname is the hostname where the Web
server for downloading the SeminarInfo service proxy is running The RenewalManager will renew the SeminarInfo service’s lease to maintain the ser-
Lease-vice’s lookup service registrations
22.8.4 JoinManager Utility
As we have seen, making a Jini service available in a Jini community requires several steps.The service must discover lookup services, register with discovered lookup services and
maintain registration leases Class JoinManager is a utility class that facilitates the
pro-cess of deploying a Jini service by performing lookup discovery, service registration andlease management in a single class
Class File Directory in SeminarServiceWithLeasing.jar
Trang 3Class SeminarInfoJoinService (Fig 22.37) uses class JoinManager to deploy the SeminarInfo service Lines 38–40 create a LookupDiscoveryManger that the JoinManager will use to discover lookup services We pass as the first argument
to the LookupDiscoveryManager constructor a String array with a single element, which is an empty String This argument specifies that the LookupDiscoveryMan- ager should perform multicast discovery for lookup services that support the “public” group For the second and third arguments, line 40 passes the value null These arguments disable unicast discovery and specify a null DiscoveryListener, respectively The JoinManager handles the discovery process, so class SeminarInfoJoinService need not handle DiscoveryEvents.
Lines 43–44 create a new Entry array with a single SeminarProvider element that specifies the provider of Seminars for the SeminarInfo service Lines 47–49 create a new instance of class JoinManager to discover lookup services, register the ser- vice and maintain the service’s registration leases Line 47 invokes method cre- ateProxy to create a SeminarProxy for the SeminarInfo service The second argument to the JoinManager constructor is the array of Entry attributes that describe the service The third argument is a reference to a ServiceIDListener When the JoinManager registers the Jini service with a lookup service, the JoinManager noti- fies the ServiceIDListener of the service ID that the lookup service assigns to the Jini service The fourth argument is a DiscoveryManagement object for discovering lookup services For this example, we pass the LookupDiscoveryManager created on lines 38–40 The final argument to the JoinManager constructor is a LeaseRenewal- Manager for maintaining the service’s registration leases
1 // SeminarInfoJoinService.java
2 // SeminarInfoJoinService uses a JoinManager to find lookup
3 // services, register the Seminar service with the lookup
4 // services and manage lease renewal.
Fig 22.37 SeminarInfoJoinService uses class JoinManager to facilitate
registering the SeminarInfo service and manage its leasing (part 1 of 3)
Trang 432 // use JoinManager to register SeminarInfo service
33 // and manage lease
42 // create and set Entry name for service
43 Entry[] entries = new Entry[ 1 ];
44 entries[ 0 ] = new SeminarProvider( "Deitel" );
45
46 // create JoinManager
47 JoinManager manager = new JoinManager( createProxy(),
48 entries, this, lookupManager,
49 new LeaseRenewalManager() );
50 }
51
52 // handle exception creating JoinManager
53 catch ( IOException exception ) {
59 // create seminar service proxy
60 private SeminarInterface createProxy()
67 // handle exception creating SeminarProxy
68 catch ( RemoteException exception ) {
74 } // end method createProxy
Fig 22.37 SeminarInfoJoinService uses class JoinManager to facilitate
registering the SeminarInfo service and manage its leasing (part 2 of 3)
Trang 5Method serviceIDNotify (lines 77–80) is required by interface IDListener The JoinManager invokes method serviceIDNotify to notify a ServiceIDListener that a lookup service has assigned a service ID to the Jini service.Line 79 simply prints out the service ID
Service-Method main (lines 83–92) sets the RMISecurityManager and launches the SeminarInfoJoinService application Note that method main does not use a keepAlive Object to keep the application running, as was required in previous exam-
ples The JoinManager keeps the application alive.
To run the SeminarInfo service using the JoinManager, create the JAR file SeminarServiceJoinManager.jar with the contents listed in Figure 22.38
75
76 // receive notification of ServiceID assignment
77 public void serviceIDNotify( ServiceID serviceID )
Service ID: 0084d3a0-4bbe-4b76-aa0b-f73294738fec
Class File Directory in SeminarServiceJoinManager.jar
Fig 22.38 SeminarServiceJoinManager.jar contents (part 1 of 2).
Fig 22.37 SeminarInfoJoinService uses class JoinManager to facilitate
registering the SeminarInfo service and manage its leasing (part 3 of 3)
Trang 6After packaging the classes in SeminarServiceJoinManager.jar, run the
new version of the service by typing the following at a command prompt:
java -classpath %CLASSPATH%;SeminarServiceJoinManager.jar -Djava.security.policy=policy
-Djava.rmi.server.codebase=http://hostname:9090/
SeminarServiceDownload.jar
com.deitel.advjhtp1.jini.utilities.join.
SeminarInfoJoinService
where policy is an appropriate security policy and hostname is the hostname where the Web
server for downloading the SeminarInfo service proxy is running Figure 22.37 shows
a sample service ID output from application SeminarInfoJoinService.
22.8.5 Service Discovery Utilities
Complex Jini clients often have specific requirements for the Jini services they employ Tosatisfy these requirements, the Jini client often must work with sets of Jini services Theclient searches through these services to locate the particular service that can satisfy the cli-ent’s needs For example, a Jini client that provides users with information about printersavailable in a given office needs a set of services for the available printers This printer-monitoring program would need to be aware of the status of each printer to know when anew printer has been added The service also should be able to search among the printersfor particular features (color support, print quality, capacity, speed etc.)
Class net.jini.lookup.ServiceDiscoveryManager provides Jini clients
with a richer set of service and lookup-service management features than interface
ServiceRegistrar provides Class ServiceDiscoveryManager facilitates
dis-covering available services and enables clients to perform finer-grained searches than are
possible with the ServiceRegistrar interface Jini clients also can use class viceDiscoveryManager to enhance application performance by maintaining a local
Ser-cache of services There are three primary ways in which Jini clients use class DiscoveryManager—creating a local cache of services, receiving event notifications
Class File Directory in SeminarServiceJoinManager.jar
Fig 22.38 SeminarServiceJoinManager.jar contents (part 2 of 2).
Trang 7when services become available or unavailable and performing detailed searches not
pos-sible with simple ServiceTemplates.
Class ServiceDiscoveryManager can enhance Jini-client performance by
cre-ating a local cache of discovered services This local cache—implemented as a
net.jini.lookup.LookupCache—enables the client to perform additional servicelookups without incurring the network overhead of a remote call to a lookup service When
the client needs a particular service that is in the LookupCache, the client simply invokes method lookup of interface LookupCache to retrieve the service from the local cache Jini clients also can use a LookupCache retrieved from a ServiceDiscovery- Manager to receive notifications related to a set of services By implementing interface
ServiceDiscoveryListener and registering with a LookupCache, a Jini client
can receive events indicating when a particular service has been discovered, when a
ser-vice’s attributes have changed and when the service is removed from the LookupCache.
This event notification is particularly useful for Jini clients that monitor availableresources, such as our printer-monitoring example
Class ServiceDiscoveryManager also provides an enhanced interface that
enables Jini clients to search for services using more specific search criteria Jini clients can
use class ServiceDiscoverManager with implementations of interface ItemFilter to locate services whose attribute values fall within a particular range For
Service-example, a Jini client could use a ServiceItemFilter to locate all automated teller
machines in the area whose service charge is less than two dollars Such a specific query is
not possible using the standard ServiceTemplate matching available through interface ServiceRegistrar.
For more information on class ServiceDiscoveryManager, please see the Jini
API documentation included with the Jini Technology Core Platform
22.9 Internet and World Wide Web Resources
developer.java.sun.com/developer/products/jini/installation.in-This site provides installation instructions for Jini technology
SUMMARY
• Many network devices provide services to network clients
• Each service has a well-defined interface
• To use a service, a client must be able to discover that a service exists and must know the interfacefor interacting with the service
• Jini extends RMI to provide services to a network
Trang 8• Jini services are plug-and-play—clients can discover services on the network dynamically, ently download classes required to use those services, then begin interacting with those services
transpar-• RMI’s dynamic class-downloading capability enables Jini clients to use services without installingspecial driver software for those services in advance
• For Jini clients to discover and use Jini services, standardized interfaces for common services must
be developed
• The basic software requirements for Jini include the Java 2 Standard Edition (J2SE) and the JiniTechnology Starter Kit If you are going to write commercial Jini services and want to test theircompatibility with the Jini platform, you also need to download the Jini Technology Core PlatformCompatibility Kit (Jini TCK)
• The Jini Starter Kit has three components—the Jini Technology Core Platform (JCP), the Jini nology Extended Platform (JXP) and the Jini Software Kit (JSK) The JCP contains the fundamentalJini interfaces and classes The JXP provides helper utilities for implementing Jini services and cli-ents The JSK contains an implementation of the services specified in the JCP and the JXP
Tech-• To compile and execute Jini services and clients the JAR files core.jar, ext.jar and sun-util.jar must be included in the CLASSPATH environment variable These three JAR files are in the lib directory of the Jini Starter Kit—they correspond to the Jini Technol-
jini-ogy Core Platform, the Jini Technoljini-ogy Extended Platform and the Jini Software Kit, respectively
• The Jini distribution comes with three services that must be running correctly before executing Jiniapplications—a Web server to enable Jini clients to download class files through RMI, so the cli-
ents can access Jini services dynamically; the RMI activation daemon (rmid) to enable the RMI
infrastructure that allows Jini clients to communicate with Jini services; and a lookup service tomaintain information about available Jini services, and to enable clients to discover and use those
services The Web server and rmid must be executing (they can be started in any order) before
starting the lookup service
• The Jini Technology Core Platform implementation includes the StartService GUI tool for
launching required services
• The Jini lookup service is the heart of a Jini community The process of finding the lookup servicesand obtaining references to them is called discovery
• Discovery distinguishes Jini technology from RMI In RMI, you must know in advance where toregister an object In Jini, you do not need to know where—just how The discovery process de-termines where, but hides the details from the developer
• Discovery can be accomplished using either unicast discovery or multicast discovery
• Unicast discovery, or locator discovery, enables a Jini service or client to discover lookup services
on a specific host
• Method getRegistrar of class LookupLocator performs unicast discovery The method returns a ServiceRegistrar, which represents a lookup service An overloaded version of method getRegistrar takes as an integer argument the maximum number of milliseconds to wait for the unicast discovery to locate a ServiceRegistrar before issuing a timeout
• Methods getHost and getPort of class LookupLocator retrieve the hostname and port
number where a lookup service was discovered
• Multicast discovery, or group discovery, enables a Jini service or client to discover lookup serviceswhen the particular host running the lookup service is not known A multicast discovery request usesnetwork multicast to discover nearby lookup services Lookup services periodically issue multicastannouncements to notify interested Jini services and clients that the lookup services are available
• Class net.jini.discovery.LookupDiscovery performs multicast discovery
• Implementing interface DiscoveryListener enables an object of a class to receive coveryEvents—notifications of discovered lookup services
Trang 9Dis-• Class LookupDiscovery invokes method discovered when LookupDiscovery locates
new lookup services
• Method getRegistrars of DiscoveryEvent obtains an array of ServiceRegistrars
• Class LookupDiscovery invokes method discarded when a lookup service should be
dis-carded because it is no longer available or because it no longer matches the set of groups in whichthe Jini service or client is interested
• A Jini service consists of several components, each of which contributes to the flexibility and bility of the Jini architecture A service proxy is an intermediary between a Jini service and its clients.The service proxy communicates with the actual service implementation through the service’s back-end interface, which defines methods in the service implementation A separate application discoverslookup services and registers the Jini service, making the service available to Jini clients
porta-• A Jini client uses the lookup service discovery techniques to discover lookup services The Jiniclient then uses the discovered lookup services to locate the desired Jini service When the lookupservice locates the service requested by the Jini client, the lookup service serializes the serviceproxy and delivers the proxy to the Jini client The client can then invoke methods defined in the
service’s public interface directly on the service proxy, which implements that interface The
service proxy communicates with the service implementation through the back-end interface
• An Entry (package net.jini.core.entry) describes a service, which enables Jini clients
to search for services of a particular description
• The lookup service requires a ServiceItem (package net.jini.core.lookup) to
regis-ter a Jini service
• Jini helper utilities simplify the process of developing the Jini applications These helper utilitiesprovide high-level management capabilities
• Class LookupLocatorDiscovery enables a Jini service or client to discover lookup services
on multiple known hosts Class LookupLocatorDiscovery uses DiscoveryEvents to
notify the Jini service or client of discovered lookup services
• Class LookupDiscoveryManager provides flexible lookup service discovery by enabling
Jini applications and clients to perform both unicast and multicast lookup service discovery using
a single class
• Entry attributes specify characteristics of Jini services By attaching attributes to services,
ser-vice providers can publish serser-vices with detailed information, such as the serser-vice location and thefunctionality of the service Developers also can create custom attributes for Jini services Class
AbstractEntry provides a basic implementation of interface Entry.
• An Entry class must supply a no-argument constructor Also, instance variables must be lic references to Serializable objects.
pub-• One goal of Jini technology is to make Jini communities “self-healing” and able to recover fromcommon problems, such as network outages, hardware failures and software failures Therefore,when a Jini service registers with a lookup service, the registration is not permanent The registra-tion is leased for a specific amount of time, after which the lookup service revokes the registration.This prevents problematic services from disrupting the entire Jini community
• The leasing strategy that Jini employs is strict—if a Jini service does not renew its lease, the lookupservice terminates the registration when the lease expires, making the service unavailable to clients
• Class LeaseRenewalManager is a Jini utility class that enables services to manage their leases
to ensure that the service’s leases do not expire prematurely
• Class JoinManager is a utility class that facilitates the process of deploying a Jini service by
performing lookup discovery, service registration and lease management in a single class
• Complex Jini clients often have specific requirements for the Jini services they employ To satisfythese requirements, the Jini client often must work with sets of Jini services The client searches
Trang 10through these services to locate the particular service that can satisfy the client’s needs Class
ServiceDiscoveryManager facilitates discovering available services and enables clients to perform finer-grained searches than are possible with the ServiceRegistrar interface
• There are three primary ways in which Jini clients use class ServiceDiscoveryManager—
creating a local cache of services, receiving event notifications when services become available or
unavailable and performing detailed searches not possible with simple ServiceTemplates.
• Class ServiceDiscoveryManager can enhance Jini-client performance by creating a local cache of discovered services This local cache—implemented as a LookupCache.
TERMINOLOGY
SELF-REVIEW EXERCISES
22.1 Fill in the blanks in each of the following statements:
a) Name three required services for running Jini services and clients: ,
ServiceDiscoveryManager lookup method of
ServiceDiscoveryManager
discovery
DiscoveryListener interface lookup service
DiscoveryManagement class LookupCache interface
getFrom method of
LookupDiscoveryManager
LookupDiscoveryManager class LookupLocator class
getGroups method of LookupDiscovery LookupLocatorDiscovery class
getHost method of class LookupLocator multicast discovery
getPort method of class LookupLocator Name class
getRegistrar method of class
group discovery renewUntil method of
LeaseRenewalManager
Jini
Jini client ServiceDiscoveryListener interface
Jini Software Kit ServiceDiscoveryManager class
Jini Technology Core Platform Compatibility Kit ServiceID class
Jini Technology Starter Kit serviceIDNotify method of
ServiceIDListener
Jini transaction manager service
ServiceDiscoveryListener
lease renewal service
LeaseListener interface unicast discovery
Trang 11c) To generate the stub file for a remote object, use
d) A service proxy that is exported to the remote client must implement interface
.e) Service providers use to describe a service Jini clients use tofind a matching service
22.2 State whether each of the following is true or false If false, explain why.
a) Unicast discovery is also known as locator discovery
b) The JoinManager can discover lookup services, register a service and renew a
ser-vice’s lease
c) Class LookupDiscoveryManager can perform only unicast discovery.
d) Jini requires only the RMI activation daemon (rmid) and a Web server.
e) Jini clients must have all the class files for a Jini service in the local CLASSPATH.
ANSWERS TO SELF-REVIEW EXERCISES
22.1 a) the HTTP Web server, the rmi activation daemon, the lookup service b) unicast discovery, multicast discovery c) rmic d) Serializable e) ServiceItem, ServiceTemplate 22.2 a) True b) True c) False Class LookupDiscoveryManager performs both unicast and
multicast discovery d) False Jini also requires lookup services to enable clients to locate Jini
servic-es e) False Jini clients require that only the public interface and supporting classes be in the local
CLASSPATH Having the Jini service’s class files in the client’s CLASSPATH prevents network
class loading
EXERCISES
22.3 Modify class MulticastDiscovery (Fig 22.13) to perform multicast discovery for
look-up services that slook-upport any grolook-up, not just the public grolook-up Can you use null for a wildcard match? 22.4 Create an application to find all services that are registered with local lookup services
22.5 Write a currency exchange service using Jini technology This currency exchange service ply does one function: It exchanges the currency of one country to the currency of another country Theexchange rate can be dynamically loaded from an on-line resource or can be just statically loaded from
sim-a file Cresim-ate the public interfsim-ace, service proxy, bsim-ack-end interfsim-ace sim-and service implementsim-ation
22.6 Register the currency exchange service with the lookup services on the local machine using
JoinManager.
22.7 Create a Jini client that allows a user to use the exchange service Search the currency change service with the lookup service on the local machine, and use the found service to exchangeone currency into another currency
ex-22.8 Modify Exercise 22.6 to add a set of Entry attributes to the service The attributes should
include the name of the exchange service, the address of the exchange service and any other attributesyou want to add to the service Use part or all of the attributes set to find a matching service
BIBLIOGRAPHY
Edwards, W K., Core Jini (Second Edition), Upper Saddle River, NJ: Prentice Hall, Inc 2001
Li, S., Professional Jini, Birmingham, U.K.: Wrox Press Ltd 2000
Newmarch, J., A Programer’s Guide to Jini Technology, New York, NY: Springer-Verlag New York,
Inc 2000
Oaks, S., and Wong, H., Jini in a Nutshell, Sebastopol, CA: O’Reilly & Associates, Inc 2000
Trang 12Take nothing on its looks: take everything on evidence
There’s no better rule.
Charles Dickens
Believe nothing, no matter where you read it, or who said it,
no matter if I have said it, unless it agrees with your own
reason and your own common sense.
Buddha
Trang 1323.1 Introduction
Objects that take part in distributed systems must be able to communicate with one anotherand share information Thus far we have introduced several mechanisms by which Java ob-jects in distributed systems can communicate Java servlets (Chapter 9) enable Java objects(and non-Java objects) to communicate using the HTTP protocol RMI (Chapter 13) en-ables Java objects running in separate virtual machines to invoke methods on one another
as if those objects were in the same virtual machine The Java Message Service (Chapter16) enables Java objects (and non-Java objects) to communicate by publishing and con-suming simple messages
The JavaSpaces service is a Jini service that implements a simple, high-level
architec-ture for building distributed systems The JavaSpaces service enables Java objects to municate, share objects and coordinate tasks using an area of shared memory.1 A
com-JavaSpaces service provides three fundamental operations—write, take and read The write operation places an object—called an entry—into the JavaSpaces service The take opera-
23.11 Updating Entries with Jini Transaction Service
23.11.1 Defining the User Interface
23.11.2 Discovering the TransactionManager Service
23.11.3 Updating an Entry
23.12 Case Study: Distributed Image Processing
23.12.1 Defining an Image Processor
23.12.2 Partitioning an Image into Smaller Pieces
23.12.3 Compiling and Running the Example
23.13 Internet and World Wide Web Resources
Summary • Terminology • Self-Review Exercises • Answers to Self-Review Exercises • Exercises • Works Cited • Bibliography
Trang 14tion specifies a template and removes from the JavaSpaces service an entry that matches
the given template The read operation is similar to the take operation, but does not removethe matching entry from the JavaSpaces service In addition to the three basic operations,JavaSpaces services support transactions through the Jini transaction manager, and a noti-fication mechanism that notifies an object when an entry that matches a given template iswritten to the JavaSpaces service
In the first half of this chapter, we present fundamental JavaSpaces technology cepts and use simple examples to demonstrate operations, transactions and notifications.The case study at the end of this chapter uses JavaSpaces services to build a distributedimage-processing application This image-processing application uses JavaSpaces services
con-to distribute the work of applying filters con-to images across many programs (normally on arate computers)
sep-23.2 JavaSpaces Service Properties
JavaSpaces technology eases the design and development of distributed systems A aSpaces service has five major properties:2
Jav-1 A JavaSpaces service is a Jini service
1 Multiple processes can access a JavaSpaces service concurrently
2 An entry stored in a JavaSpaces service will remain in the JavaSpaces service untilits lease expires or until a program takes the entry from the JavaSpaces service
3 A JavaSpaces service locates objects by comparing those objects to a template.The template specifies the search criteria against which the JavaSpaces servicecompares each entry When one or more entries match the template, the JavaSpac-
es service returns a single matching entry
4 JavaSpaces services use the Jini transaction manager to ensure operations executeatomically
5 Objects in a JavaSpaces service are shared Programs can read and take entries
from the JavaSpaces service, modify the public fields in those entries and write
them back to the JavaSpaces service for other programs to use
23.3 JavaSpaces Service
The JavaSpaces service provides distributed, shared storage for Java objects Any patible client can put shared objects into the storage However, several restrictions apply tothese Java objects First, any object stored in the JavaSpaces service must implement interface
Java-com-Entry (package net.jini.core.entry) JavaSpaces service Entrys adhere to the Jini Entry contract defined in the Jini Core Specification (see Chapter 22, Jini) An Entry
can have multiple constructors and as many methods as required Other requirements include
a public no-argument constructor, public fields and no-primitive type fields The aSpaces service proxy uses the no-argument constructor to instantiate the matching Entry
Jav-during the deserialization process All fields that will be used as the template matching fields
in an Entry must be public (for more information on template matching fields, see tion 23.8) As defined by the Jini Core Specification, an Entry cannot have primitive-type
Sec-fields The object field requirement simplifies the model for template matching because
prim-itive types cannot have null values, which are used as wildcards in templates
Trang 15JavaSpaces technology, like Jini, requires several underlying services The JavaSpacesservice depends on the Jini lookup service (for more information on Jini services, seeChapter 22, Jini) When transactions are required, the Jini transaction service(Section 23.11.2) must be started JavaSpaces services also depend on a Web server and
rmid (for more information on starting these services, see Chapter 22, Jini) Section 23.6
explains the relationships between JavaSpaces services and these Jini services Section23.11 demonstrates using the Transaction service with the JavaSpaces service To use the
JavaSpaces service, we need to start outrigger, which is Sun’s implementation of the
JavaSpaces service Two versions of the JavaSpaces service are available One is the sient JavaSpaces service (nonactivatable) The other is the persistent JavaSpaces service
tran-(activatable) The transient JavaSpaces service does not require the RMI activation daemon
(rmid), because the transient JavaSpaces service is not activatable Once the transient aSpaces service terminates, all state information is lost and rmid is unable to restart the
Jav-service.The persistent JavaSpaces service is activatable, and therefore requires the RMIactivation daemon If the persistent JavaSpaces service terminates, all of its state informa-
tion is stored in a log file and rmid can restart the service at a later time
To start the transient JavaSpaces service enter the following a command prompt
java -Djava.security.policy=policy
-Djava.rmi.server.codebase=
http://hostname:port/outrigger-dl.jar
-jar c:\files\jini1_1\lib\transient-outrigger.jar public
where policy is the path to an appropriate policy file, hostname is the name of the machine
on which the Web server is running and port specifies the port number on which the Web
server will accept connections The argument public specifies to which group this
ser-vice belongs
The following command starts the persistent JavaSpaces service:
java -jar c:\files\jini1_1\lib\outrigger.jar
http://hostname:port/outrigger-dl.jar
policy log_path public
where hostname is the name of the machine on which the Web server is running, port specifies the port number from which the Web server will accept connections, policy is
the full path of the policy file and log_path is the location where the outrigger log will
be created
An additional parameter is useful in systems where two or more JavaSpaces servicesoperate The parameter is
-Dcom.sun.jini.outrigger.spaceName=name
where name defines the String with which the JavaSpaces service will register itself in
the Jini lookup service The default name for the JavaSpaces service is "JavaSpace".
When searching for a specific JavaSpaces service in the Jini lookup service, you must use
a Name Entry (package net.jini.lookup.entry) and initialize it to the String
specified in the previous parameter While this is a necessary parameter for systems withtwo or more JavaSpaces services, the examples in this chapter assume that only one Jav-aSpaces service exists in the system The examples introduce a simple by which clients canlocate the JavaSpaces service from the Jini lookup service
Trang 16You can start either a transient or persistent JavaSpaces service from the vice GUI tool included in the Jini distributions Start the GUI as in Chapter 21, then choose the TransientSpace tab (for a transient JavaSpaces service) or the FrontEnd- Space (for a persistent JavaSpaces service) Go to the Run tab and click the Start Tran- sientSpace button to run the transient service or click the Start FrontEndSpace button
StartSer-to run the persistent service
23.4 Discovering the JavaSpaces Service
Upon initialization, each JavaSpaces service registers itself with local Jini lookup services
We assume that you already know how to start a Web server and RMI activation daemonfrom Chapter 22 The following is an example of a command that starts the persistent Jav-
aSpaces service Replace hostname with the name or IP address of your computer and port
with the port number on which the Web server is listening
java -jar C:\files\jini1_1\lib\outrigger.jar
http://hostname:port/outrigger-dl.jar
C:\files\jini1_1\policy\policy.all
C:\tmp\outrigger_log public
Class JavaSpaceFinder (Fig 23.1) shows how to obtain access to a JavaSpaces
ser-vice (We use this class in the example of Fig 23.3.) The application performs unicast covery to find the Jini lookup service on the hostname that the user specifies Lines 35–36 get
dis-the LookupLocator at a user-specified Jini URL and obtain its ServiceRegistrar.
Lines 55-68 look for all JavaSpaces services registered in the lookup service Lines 55–57
specify a ServiceTemplate object (package net.jini.core.lookup) Lines 61–
62 use the ServiceTemplate to search for all matching services in the lookup service and obtain a JavaSpace Method getJavaSpace (lines 77–80) returns the discovered Jav- aSpace For more information on how to use the Jini lookup service, please refer to Chapter
Trang 1718 // Java extension package
27 LookupLocator locator = null;
28 ServiceRegistrar registrar = null;
29
30 System.setSecurityManager( new RMISecurityManager() ); 31
32 // get lookup service locator at "jini://hostname"
33 // use default port and registrar of the locator
39 // handle exception invalid jini URL
40 catch ( MalformedURLException malformedURLException ) {
41 malformedURLException.printStackTrace();
42 }
43
44 // handle exception I/O
45 catch ( java.io.IOException ioException ) {
46 ioException.printStackTrace();
47 }
48
49 // handle exception finding class
50 catch ( ClassNotFoundException classNotFoundException ) {
51 classNotFoundException.printStackTrace();
52 }
53
54 // specify the service requirement
55 Class[] types = new Class[] { JavaSpace.class };
65 // handle exception getting JavaSpaces service
66 catch ( RemoteException remoteException ) {
Trang 1823.5 JavaSpace Interface
Clients access objects in a JavaSpaces service through interface JavaSpace (package net.jini.space ) Interface JavaSpace provides several methods—notify, read, readIfExists, take, takeIfExists, write and snapshot The purpose
of each method is as follows:3
1 write—This method implements the write operation The write operation inserts an Entry into a JavaSpaces service If an identical Entry already exists
in the JavaSpaces service, this operation does not overwrite the existing Entry Instead, the write operation places a copy of the Entry into the JavaSpaces ser- vice JavaSpaces services may contain multiple copies of the same Entry Section 23.7 demonstrates how to use the write operation.
2 read, readIfExists—These two methods implement the read operation, which attempts to read an Entry that matches an Entry template from a Jav- aSpaces service If no matching Entry exists in the JavaSpaces service, this oper- ation returns null If multiple matching Entry exist in the JavaSpaces service, the read operation arbitrarily picks one among the matching Entrys Method read blocks until a matching Entry is found in the JavaSpaces service or until a time-out occurs Method readIfExists checks to see if a matching Entry ex- ists within the JavaSpaces service If an Entry does not exist in the JavaSpaces service, method readIfExists should return null immediately Method readIfExists does not block unless the matching Entry is a participant in an
uncommitted transaction For information on transactions, see Section 23.11
Section 23.8.1 demonstrates the read and readIfExists operations.
3 take, takeIfExists—These two methods implement the take operation, which attempts to remove an Entry that matches an Entry template from a Jav- aSpaces service This operation works like the read operation, except that the take operation removes the matching Entry from the JavaSpaces service Method take blocks until a matching Entry is found in the JavaSpaces service
or until a time-out occurs Method takeIfExists checks to see if a matching Entry exists within the JavaSpaces service If an Entry does not exist in the JavaSpaces service, method takeIfExists should return null immediately.
70 // if does not find any matching service
Trang 19Method takeIfExists does not block unless the matching Entry is part of
an uncommitted transaction Section 23.8.2 demonstrates the take and IfExists operations
take-4 notify—This method implements the notify operation, which requests that
the JavaSpaces service sends a notification to a listener object when a client writes
a matching Entry into the JavaSpaces service With this method, an application does not need to check repeatedly for an Entry in a JavaSpaces service Section 23.9 demonstrates the notify operation.
5 snapshot—This method increases performance when a program must serialize one Entry repeatedly Each time a program transfers an Entry into a JavaSpac-
es service (e.g., by writing that Entry or by using that Entry as a template), that Entry must be serialized If a program transfers the same Entry to a JavaSpaces
service many times, the serialization process can be time consuming Invoking
method snapshot serializes the Entry once and reuses this serialized Entry for future transfers Section 23.10 demonstrates how to use method snapshot.
At-AttendeeCounter (Fig 23.2) is an Entry that represents a count of the number
of people attending a seminar Recall that Entrys require non-primitive type, public fields (lines 9–10) and an empty constructor (line 13) The AttendeeCounter con- structor on lines 16–19 takes as a String argument the day of the week for which this AttendeeCounter tracks attendee registrations
Common Programming Error 23.1
Including primitive fields in an Entry does not cause an error during compilation
Howev-er, an IllegalArgumentException does occur during serialization 23.1
9 public String day;
10 public Integer counter;
11
Fig 23.2 AttendeeCounter is an Entry for keeping track of registrations for a
seminar on a particular day (part 1 of 2)
Trang 20Software Engineering Observation 23.1
Use wrapper classes rather than primitive types in Entry fields. 23.1
23.7 Write Operation
The write operation places an Entry in a JavaSpaces service Method write takes three arguments—an Entry, a Transaction object and a long value that requests an amount of time for which the JavaSpaces service should keep the Entry The long value represents the lease length for the Entry Normally, the JavaSpaces service grants each written Entry a lease time of 5 minutes The JavaSpaces service will not keep the Entry beyond the lease time granted A developer can extend the life of an Entry by renewing its lease before it expires Method write returns a net.jini.lease.Lease object that contains the time that the JavaSpaces service granted to the Entry Method write throws two exceptions Method write throws a RemoteException (package ja- va.rmi) when a network failure occurs or a variety of other errors occur on the server
When a write operation takes place under an invalid transaction, method write throws
a TransactionException (package net.jini.core.transaction) For
in-formation on transactions, see Section 23.11
The WriteOperation application (Fig 23.3) uses class AttendeeCounter (Fig 23.2) and class JavaSpaceFinder (Fig 23.1) to demonstrate writing an Entry into a JavaSpaces service In this example, a seminar administrator would use the Writ- eOperation application to place AttendeeCounter Entrys for each available sem- inar in the JavaSpaces service The constructor (lines 30–36) takes a JavaSpace as an argument Method writeEntry (lines 39–62) writes an Entry into the JavaSpaces ser- vice Lines 44–45 initialize an Entry by setting the number of people who register for the seminar to zero Line 46 writes the Entry into the JavaSpaces service The first argument (counter) specifies the Entry to write into the JavaSpaces service The second argu- ment (null) indicates that the write operation does not use a Transaction When the write operation completes, the written Entry is ready for a read or take operation If a Transaction object is specified, the write operation uses that Transaction to
ensure that a series of operations completes successfully This means that until the
transac-tion completes successfully, other clients cannot read or take the Entry from the aSpaces service The third argument (Lease.FOREVER) specifies how long the JavaSpaces service should keep the Entry Although we request that the JavaSpaces ser- vice keep our Entry forever, Sun’s implementation limits the lease to 5 minutes Pro-
Jav-12 // empty constructor
13 public AttendeeCounter() {}
14
15 // constructor has a single String input
16 public AttendeeCounter( String seminarDay )
17 {
18 day = seminarDay;
19 }
20 }
Fig 23.2 AttendeeCounter is an Entry for keeping track of registrations for a
seminar on a particular day (part 2 of 2)
Trang 21grams can use the Jini lease-renewal mechanism to maintain Leases for Entrys After
the lease expires, the JavaSpaces service removes and destroys the object
Method showOutput (lines 65–75) displays the results In method main, lines 81–
85 check the user-specified hostname Lines 88–90 ask user to choose a particular day to
write Figure 23.4 shows the results of running the WriteOperation application.
1 // WriteOperation.java
2 // This application initializes an new Entry,
3 // and puts this Entry to the JavaSpace.
24 private JavaSpace space;
25 private static final String[] days = { "Monday" , "Tuesday" ,
26 "Wednesday" , "Thursday" , "Friday" };
27 private String output = "\n" ;
33 String jiniURL = "jini://" + hostname;
34 JavaSpaceFinder findtool = new JavaSpaceFinder( jiniURL );
35 space = findtool.getJavaSpace();
36 }
37
38 // deposit new Entry to JavaSpace
39 public void writeEntry( String day )
40 {
41 // initialize AttendeeCounter Entry and deposit
42 // Entry in JavaSpace
43 try {
44 AttendeeCounter counter = new AttendeeCounter( day );
45 space.write( counter, null, Lease FOREVER );
46
Fig 23.3 Writing an Entry into a JavaSpaces service (part 1 of 2)
Trang 2247 output += "Initialize the Entry: \n" ;
48 output += " Day: " + day + "\n" ;
49 output += " Count: 0\n" ;
50 }
51
52 // handle exception network failure
53 catch ( RemoteException exception ) {
54 exception.printStackTrace();
55 }
56
57 // handle exception invalid transaction
58 catch ( TransactionException exception ) {
86 // get user input day
87 String day = ( String ) JOptionPane.showInputDialog(
88 null, "Select Day" , "Day Selection" ,
89 JOptionPane QUESTION_MESSAGE , null, days, days[ 0 ] ); 90
Trang 23This application takes a command-line argument that specifies the hostname of a puter that has the JavaSpaces service running The following steps compile and execute the
com-WriteOperation application Ensure that your CLASSPATH includes core.jar , jini-ext.jar and sun-util.jar Compile the java files in the com\deitel\advjhtp1\javaspace\common directory Run WriteOpera- tion by specifying the hostname of the Jini lookup service Do not forget to specify to theJVM the policy file with the proper permissions
jini-23.8 Read and Take Operations
The read and the take operations retrieve Entrys from a JavaSpaces service A client can read or take an Entry from the JavaSpaces service by supplying a template Entry against which to compare the public fields of Entrys in the JavaSpaces service The
template indicates which fields to use for comparison purposes
The retrieval process uses a template-matching mechanism to match Entrys according
to the values of their public fields Each Entry in the JavaSpaces service requires its public fields to be object references, so each field is either null or a reference to an object Fields in the template with non-null values must match with their Entry counterparts in the JavaSpaces service exactly Fields in the template that are set to null act as wildcards.
If a set of Entrys of the same type exist within a JavaSpaces service, only those fields which equal those of the template are used to match an Entry or a set of Entrys contained in the JavaSpaces service Fields in the template set to null can have their matching counterparts
in the JavaSpaces service have any value in the corresponding field(s)
23.8.1 Read Operation
The read operation obtains Entrys without removing them from the JavaSpaces service Methods read and readIfExists perform the read operation Each method takes three arguments—an Entry that specifies the template to match, a Transaction object and a long value The long value has different meanings in methods read and readIfEx- ists Method read specifies a period of time for which the read operation should block be- fore simply returning null Method readIfExists is a non-blocking version of method read If there are no matching Entrys, readIfExists returns null immediately Method readIfExists blocks only if the developer specifies a period of time for which the readIfExists waits if, at first, the matching Entry is a part of an incomplete trans- action If the matching Entry is not involved in any transaction, then the read operation returns the matching Entry immediately Both the read and readIfExists methods re-
Fig 23.4 Results of running the WriteOperation application
Trang 24turn only one Entry If multiple Entrys match the template, the read operation picks one arbitrarily These methods throw four exception types—RemoteException, Transac- tionException , UnusableEntryException and InterruptedException The first two are the same as in method write If the matching Entry cannot be deserial- ized, these methods throw an UnusableEntryException (package net.ji- ni.core.entry).
The ReadOperation application (Fig 23.5) uses class AttendeeCounter (Fig 23.2) and class JavaSpaceFinder (Fig 23.1) to demonstrate reading an Entry
from a JavaSpaces service A seminar administrator or prospective attendee could use thisapplication to determine the current enrollment for a particular seminar Line 47 specifies
the matching template against which to compare Entrys Users must specify the day for
which they would like to see attendee registrations
1 // ReadOperation.java
2 // This application reads an Entry from the JavaSpace and
3 // displays the Entry information.
25 private JavaSpace space;
26 private static final String[] days = { "Monday" , "Tuesday" ,
27 "Wednesday" , "Thursday" , "Friday" };
28 private String output = "\n" ;
29
30 // constructor gets JavaSpace
31 public ReadOperation( String hostname )
32 {
33 // get JavaSpace
34 String jiniURL = "jini://" + hostname;
35 JavaSpaceFinder findtool = new JavaSpaceFinder( jiniURL );
Trang 2539 // read Entry from JavaSpace
40 public void readEntry( String day )
41 {
42 // specify matching template, read template
43 // from JavaSpace and output Entry information
44 try {
45
46 // read Entry from JavaSpace
47 AttendeeCounter counter = new AttendeeCounter( day );
48 AttendeeCounter resultCounter = ( AttendeeCounter )
49 space.read( counter, null, JavaSpace NO_WAIT ); 50
57 // get Entry information
58 output += "Count Information:\n" ;
59 output += " Day: " + resultCounter.day;
66 // handle exception network failure
67 catch ( RemoteException exception ) {
68 exception.printStackTrace();
69 }
70
71 // handle exception invalid transaction
72 catch ( TransactionException exception ) {
73 exception.printStackTrace();
74 }
75
76 // handle exception unusable Entry
77 catch ( UnusableEntryException exception ) {
78 exception.printStackTrace();
79 }
80
81 // handle exception interrupting
82 catch ( InterruptedException exception ) {
91 JTextArea outputArea = new JTextArea();
Fig 23.5 Reading an Entry from JavaSpaces service (part 2 of 3)
Trang 26The first argument to method read (lines 48–49) specifies an Entry that the plate-matching mechanism will use The second argument (null) indicates that this read operation does not use a Transaction The third argument (JavaSpace.NO_WAIT)
tem-specifies the period for which the read operations wait for the read operation to find a
matching Entry before simply returning null Our example sets the method read to JavaSpace.NO_WAIT, which equals zero If the template-matching mechanism does
not locate a matching Entry, the read operation returns null immediately Figure 23.6 shows the results of running the ReadOperation application.
This application takes a command-line argument that specifies the hostname of amachine that has the JavaSpaces service service running The following steps compile and
execute the ReadOperation application Ensure that your CLASSPATH includes jini-core.jar , jini-ext.jar and sun-util.jar Compile the java files in the com\deitel\advjhtp1\javaspace\read directory Run ReadOperation by
specifying the hostname of the Jini lookup service Do not forget to specify to the JVM thepolicy file with the proper permissions
111 // get user input day
112 String day = ( String ) JOptionPane.showInputDialog(
113 null, "Select Day" , "Day Selection" ,
114 JOptionPane QUESTION_MESSAGE , null, days, days[ 0 ] ); 115
Trang 27Software Engineering Observation 23.2
The read operation returns only a single matching Entry If multiple matching Entrys exist, the read operation may return different matching objects each time. 23.2
23.8.2 Take Operation
The take operation obtains an Entry and removes it from the JavaSpaces service ods take and takeIfExists perform the take operation Methods take and take- IfExists are similar to methods read and readIfExists The only difference is that the matching Entry returned by a take or takeIfExists operation is removed
Meth-from the JavaSpaces service
The TakeOperation application (Fig 23.7) uses class AttendeeCounter (Fig 23.2) and class JavaSpaceFinder (Fig 23.1) to demonstrate taking an Entry from a JavaSpaces service This application is similar to the ReadOperation applica- tion The only difference is that this application calls method take (lines 46–47) of inter- face JavaSpace to remove the AttendeeCounter from the JavaSpaces service A
seminar administrator could use this application to remove from the JavaSpaces service an
AttendeeCounter for a seminar that has already been given or for a seminar that was
cancelled Figure 23.8 shows the results of running the TakeOperation application.
This application takes a command-line argument that specifies the hostname of amachine that has the JavaSpaces service running The following steps compile and execute
the TakeOperation application Ensure that your CLASSPATH includes core.jar , jini-ext.jar and sun-util.jar Compile the java files in the com\deitel\advjhtp1\javaspace\take directory Run TakeOperation by
jini-specifying the hostname of the Jini lookup service Do not forget to specify to the JVM thepolicy file with the proper permissions
Fig 23.6 Results of running the ReadOperation application
Trang 289 // Jini extension package
23 private JavaSpace space = null;
24 private static final String[] days = { "Monday" , "Tuesday" ,
25 "Wednesday" , "Thursday" , "Friday" };
26 private String output = "\n" ;
27
28 // constructor gets JavaSpace
29 public TakeOperation( String hostname )
30 {
31 // get JavaSpace
32 String jiniURL = "jini://" + hostname;
33 JavaSpaceFinder findtool = new JavaSpaceFinder( jiniURL );
34 space = findtool.getJavaSpace();
35 }
36
37 // remove Entry from JavaSpace
38 public void TakeAnEntry( String day )
45 AttendeeCounter count = new AttendeeCounter( day );
46 resultCounter = ( AttendeeCounter ) space.take( count,
47 null, JavaSpace NO_WAIT );
48
49 if ( resultCounter == null) {
50 output += "No Entry for " + day
51 + " is available from the JavaSpace.\n" ;
52 }
53 else {
54 output += "Entry is taken away from " ;
55 output += "the JavaSpace successfully.\n" ;
Trang 2959 // handle exception network failure
60 catch ( RemoteException exception ) {
61 exception.printStackTrace();
62 }
63
64 // handle exception invalid transaction
65 catch ( TransactionException exception ) {
66 exception.printStackTrace();
67 }
68
69 // handle exception unusable entry
70 catch ( UnusableEntryException exception ) {
71 exception.printStackTrace();
72 }
73
74 // handle exception interrupt
75 catch ( InterruptedException exception ) {
103 // get user input day
104 String day = ( String ) JOptionPane.showInputDialog(
105 null, "Select Day" , "Day Selection" ,
106 JOptionPane QUESTION_MESSAGE , null, days, days[ 0 ] ); 107
Trang 30Software Engineering Observation 23.3
The take operation returns only a single matching Entry If multiple matching Entrys ist, the take operation can remove only one Entry from the JavaSpaces service each time.
ex-To take all the matching Entrys away from the JavaSpaces service, execute the
mes-sage that says “No Entry is available from the JavaSpaces service”. 23.3
23.9 Notify Operation
The notify operation asks the JavaSpaces service to send a notification to a listener when
a client writes a matching Entry into the JavaSpaces service Method notify takes five parameters—an Entry that specifies the matching template, a Transaction object, a listener that implements interface RemoteEventListener (package net.ji- ni.core.event ), a long value that specifies the lease time for the registration of the listener and a MarshalledObject (package java.rmi) that the JavaSpaces service
will pass to the remote listener as part of a notification This method may throw exceptions
of type RemoteException and TransactionException A tion occurs due to a network failure A TransactionException occurs when a no-
RemoteExcep-tify operation takes place as part of an invalid transaction
Class EntryListener (Fig 23.9) defines a listener that the JavaSpaces service will notify when an Entry matching the given template is written to the JavaSpaces service The EntryListener listens on the JavaSpaces service for a matching Entry written into the JavaSpaces service This listener must implement interface RemoteEventListener
(line 14) A person interested in attending a seminar on a particular day could use this
appli-cation to be notified when an AttendeeCounter is added for a seminar on a particular day The constructor takes one argument—a RemoteEventListener and exports the listener to the JavaSpaces service so that when a client writes a matching Entry into the JavaSpaces service, the JavaSpaces service will call notify Method notify (lines 35– 40) forwards the notification to the NotifyOperation application (Fig 23.10)
112 take.showOutput();
113
114 } // end method main
115 }
Fig 23.8 Results of running the TakeOperation application
Fig 23.7 Taking an Entry from a JavaSpaces service (part 4 of 4)
Trang 31The NotifyOperation application (Fig 23.10) demonstrates how to write a gram that receives a notification when a matching Entry is written into a JavaSpaces ser-
pro-vice Lines 30–36 define the constructor, which gets a JavaSpaces serpro-vice In method
notifyEntry (lines 39–61), line 42 gets an EntryListener that listens on the aSpaces service for matching Entrys This EntryListener will be passed to method notify of interface JavaSpace Line 48 creates the matching template Lines 50–51
Jav-define the object to send to the listener when a notification occurs Lines 52–53 call the
notify method of the JavaSpace interface The first argument (counter) specifies
an Entry that is used as a matching template The second argument (null) indicates that
28 // handle exception exporting stub
29 catch ( RemoteException remoteException ) {
35 public void notify( RemoteEvent remoteEvent )
36 throws UnknownEventException, RemoteException
Trang 32the notify operation does not occur within a transaction The third argument tener) is an instance of the EntryListener class The fourth argument (600000)
(specifies the number of milliseconds requested for the lease After the expiration of the
lis-tener’s granted lease, the listener will cease to be active The last argument (handback—
a reference to a MarshalledObject) is an object that the JavaSpaces service provides
to the remote listener as part of the notification
1 // NotifyOperation.java
2 // This application receives a notification when a matching entry
3 // is written to the JavaSpace.
25 private JavaSpace space;
26 private static final String[] days = { "Monday" , "Tuesday" ,
27 "Wednesday" , "Thursday" , "Friday" };
28
29 // constructor gets JavaSpace
30 public NotifyOperation( String hostname )
31 {
32 // get JavaSpace
33 String jiniURL = "jini://" + hostname;
34 JavaSpaceFinder findtool = new JavaSpaceFinder( jiniURL );
35 space = findtool.getJavaSpace();
36 }
37
38 // call notify method of JavaSpace
39 public void notifyEntry( String day )
40 {
41 // get Entry listener
42 EntryListener listener = new EntryListener( this );
43
Fig 23.10
Fig 23.10 Receiving notifications when matching Entrys are written into
JavaSpace (part 1 of 3).
Trang 3344 // specify matching template, asks JavaSpace to
45 // send notification when matching entry is written
56 // handle exception notifying space
57 catch ( Exception exception ) {
80 output += "id: " + remoteEvent.getID() + "\n" ;
81 output += "sequence number: "
91 // handle exception getting handback
92 catch ( Exception exception ) {
Trang 34The following steps execute the NotifyOperation application Ensure that your CLASSPATH includes jini-core.jar, jini-ext.jar and sun-util.jar Compile the source files in the com\deitel\advjhtp1\javaspace\notify directory Start a Web server Generate a stub for class EntryListener (Fig 23.9) Create a JAR file for EntryListener_Stub.class and place it in the Web server’s document directory Run NotifyOperation by specifying the hostname of the Jini
lookup service Do not forget to specify to the JVM the codebase and the policy file withthe proper permissions
Figure 23.11 shows sample outputs of this application To test this application, execute
several WriteOperation applications
107 // get user input day
108 String day = ( String ) JOptionPane.showInputDialog(
109 null, "Select Day" , "Day Selection" ,
110 JOptionPane QUESTION_MESSAGE , null, days, days[ 0 ] ); 111
Trang 35Software Engineering Observation 23.4
JavaSpaces service notifications are not guaranteed to be delivered, as network problems
23.10 Method snapshot
Method snapshot optimizes interactions with a JavaSpaces service by reducing the head of continually serializing Entrys Every time we pass a matching template to methods
over-in the JavaSpace over-interface, the template must be serialized before it is moved to the
Jav-aSpaces service When the same template is passed to a JavJav-aSpaces service repeatedly, it is
preferable to avoid multiple serializations of the same Entry Fortunately, method shot provides such a mechanism Method snapshot takes a matching template and re-
snap-turns a specialized representation of the Entry (a snapshot Entry) This snapshot Entry
can be used only in the JavaSpaces service that generated it For example, to remove all the
seminar Entrys for Monday from the JavaSpaces service, we call the snapshot method
to create a snapshot Entry, then pass this snapshot Entry to the take method repeatedly The SnapshotUsage application (Fig 23.12) removes Entrys from the Jav- aSpaces service and uses method snapshot to avoid repeated serialization of the
matching template Line 49 defines the original matching template We do not pass this
original template to method take Instead, we pass the snapshot to the take method Line
50 calls method snapshot to get the snapshot Entry of the original template
Trang 3626 private static final String[] days = { "Monday" , "Tuesday" ,
27 "Wednesday" , "Thursday" , "Friday" };
28 private String output = "\n" ;
29
30 // constructor gets JavaSpace
31 public SnapshotUsage( String hostname )
32 {
33 // get JavaSpace
34 String jiniURL = "jini://" + hostname;
35 JavaSpaceFinder findtool = new JavaSpaceFinder( jiniURL );
36 space = findtool.getJavaSpace();
37 }
38
39 // create snapshot Entry, pass this object as
40 // Entry parameter to take method
41 public void snapshotEntry( String day )
42 {
43 // specify matching template, snapshot template
44 // and remove matching entries from JavaSpace using
45 // snapshot entry
46 try {
47 AttendeeCounter counter = new AttendeeCounter( day );
48 Entry snapshotentry = space.snapshot( counter );
49 AttendeeCounter resultCounter = ( AttendeeCounter )
50 space.take( snapshotentry, null, JavaSpace NO_WAIT ); 51
52 // keep removing entries until no more entry exists
53 // in space
54 while ( resultCounter != null ) {
55 output += "Removing an entry \n" ;
56 resultCounter = ( AttendeeCounter ) space.take(
57 snapshotentry, null, JavaSpace NO_WAIT );
63 // handle exception network failure
64 catch ( RemoteException remoteException ) {
65 remoteException.printStackTrace();
66 }
67
68 // handle exception invalid transaction
69 catch ( TransactionException transactionException ) {
70 transactionException.printStackTrace();
71 }
72
73 // handle exception unusable entry
74 catch ( UnusableEntryException unusableEntryException ) {
Trang 37The only argument of method snapshot (line 48) specifies the template to serialize Method snapshot returns a snapshot Entry that represents the matching template Lines 49–51 call method take to remove the Entrys that match the template from the JavaSpaces service Lines 54–58 remove all matching Entrys in the JavaSpaces service Figure 23.13 shows the output of running the SnapshotUsage application This output indicates that there are three matching Entrys in the JavaSpaces service The take opera- tion removes all three matching Entrys from the JavaSpaces service
78 // handle exception interrupt
79 catch ( InterruptedException interruptedException ) {
108 // get user input day
109 String day = ( String ) JOptionPane.showInputDialog(
110 null, "Select Day" , "Day Selection" ,
111 JOptionPane QUESTION_MESSAGE , null, days, days[ 0 ] ); 112
Trang 38The following steps compile and execute the SnapshotUsage application Make sure your CLASSPATH includes jini-core.jar, jini-ext.jar and sun-util.jar Compile the java files in the com\deitel\advjhtp1\javaspace\snapshot direc- tory Run SnapshotUsage by specifying the hostname of the Jini lookup service Do not
forget to specify to the JVM the policy file with the proper permissions
Software Engineering Observation 23.5
Using the snapshot Entry is equivalent to using the original Entry, as long as all
opera-tions take place on the same JavaSpaces service that generated the snapshot. 23.5
23.11 Updating Entries with Jini Transaction Service
We cannot modify an Entry in a JavaSpaces service directly Instead, we must take the Entry away from the JavaSpaces service, change the values of the Entry fields, then place the Entry back into the JavaSpaces service To ensure that the JavaSpaces service does not lose the Entry when a process takes that Entry away, we can perform the take,
update and write processes in a transaction If all these processes succeed, the transaction
completes Otherwise, the transaction fails and the JavaSpaces service returns the Entry
to its state prior to the transaction
Assume a distributed system in which dedicated nodes take Entrys from a aSpaces service, process each Entry, and write them back to the JavaSpaces service
Jav-when finished What happens if a problem occurs and one of the dedicated nodes never
returns a processed Entry? The information that node processed could be permanently lost Furthermore, because the processing node removed the Entry from the JavaSpaces service, the unprocessed Entry is also lost The use of a transaction manager protects a
JavaSpaces service from these situations When a transaction fails, the transaction manager
restores the Entry to its previous state—as if the client never took the Entry.
Our next example demonstrates how to update an Entry in a JavaSpaces service The application takes an AttendeeCounter Entry from the JavaSpaces service, updates the count variable and reinserts the Entry back into the JavaSpaces service A seminar
administrator could use this application to register a new attendee for a seminar and update
the appropriate AttendeeCounter We have to ensure that if a client takes an Entry from the JavaSpaces service, it will write the Entry back into the JavaSpaces service later.
In this example, we use the Jini transaction manager to guarantee that only one client at a
time can update a seminar Entry Otherwise, one client potentially could overwrite a viously written Entry, thus corrupting the proper count of the number of people who will
pre-attend a seminar
Fig 23.13
Fig 23.13 SnapshotUsage Output window.
Trang 3923.11.1 Defining the User Interface
This section defines the user interface for the application To update an Entry, the gram must know which AttendeeCounter to update and the number to add to the counter Class UpdateInputWindow (Fig 23.14) prompts the user for the day of the
pro-week to update and the number of people who will attend the seminar on that day
1 // UpdateInputWindow.java
2 // This application is an user interface used
3 // to get the input data.
15 private String[] dates = { "Monday" , "Tuesday" ,
16 "Wednesday" , "Thursday" , "Friday" };
17 private JButton okButton;
18 private JComboBox dateComboBox;
19 private JLabel firstLabel;
20 private JTextField numberText;
21 private String date = "Monday" ;
22 private int count = 0
23 private String hostname;
32 // define center panel
33 JPanel centerPanel = new JPanel();
34 centerPanel.setLayout( new GridLayout( 2 2 0 5 ) ); 35
41 // add combo box
42 dateComboBox = new JComboBox( dates );
Trang 4046 // install listener to combo box
59 JLabel numberLabel = new JLabel(
60 "Please specify a number:" , SwingConstants CENTER );
61 centerPanel.add( numberLabel );
62
63 // add text field
64 numberText = new JTextField( 10 );
80 // define button panel
81 JPanel buttonPanel = new JPanel();
82 buttonPanel.setLayout( new GridLayout( 1 1 0 5 ) ); 83
95 // get user input
96 count = Integer.parseInt( numberText.getText() ); 97
Fig 23.14 UpdateInputWindow user interface (part 2 of 3)