You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@river.apache.org by th...@apache.org on 2010/12/09 17:26:40 UTC

svn commit: r1044022 - /incubator/river/site/trunk/content/river/docs/specs/discoveryutil-spec.mdtext

Author: thobbs
Date: Thu Dec  9 16:26:40 2010
New Revision: 1044022

URL: http://svn.apache.org/viewvc?rev=1044022&view=rev
Log:
Modified for CMS markup

Modified:
    incubator/river/site/trunk/content/river/docs/specs/discoveryutil-spec.mdtext

Modified: incubator/river/site/trunk/content/river/docs/specs/discoveryutil-spec.mdtext
URL: http://svn.apache.org/viewvc/incubator/river/site/trunk/content/river/docs/specs/discoveryutil-spec.mdtext?rev=1044022&r1=1044021&r2=1044022&view=diff
==============================================================================
--- incubator/river/site/trunk/content/river/docs/specs/discoveryutil-spec.mdtext (original)
+++ incubator/river/site/trunk/content/river/docs/specs/discoveryutil-spec.mdtext Thu Dec  9 16:26:40 2010
@@ -1,1735 +1,1102 @@
-<!--
- ! Licensed to the Apache Software Foundation (ASF) under one
- ! or more contributor license agreements.  See the NOTICE file
- ! distributed with this work for additional information
- ! regarding copyright ownership. The ASF licenses this file
- ! to you under the Apache License, Version 2.0 (the
- ! "License"); you may not use this file except in compliance
- ! with the License. You may obtain a copy of the License at
- ! 
- !      http://www.apache.org/licenses/LICENSE-2.0
- ! 
- ! Unless required by applicable law or agreed to in writing, software
- ! distributed under the License is distributed on an "AS IS" BASIS,
- ! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ! See the License for the specific language governing permissions and
- ! limitations under the License.
- !-->
-
-<html>
-
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
-<meta name="GENERATOR" content="Quadralay WebWorks Publisher 5.0.4">
-<meta name="TEMPLATEBASE" content="JiniSpec1.1alpha">
-<meta name="LASTUPDATED" content="Mar 5, 2003">
-<link rel="StyleSheet" href="standard.css" type="text/css" media="screen">
-<title>Jini Discovery Utilities Specification - DU </title>
-</head>
-
-<body bgcolor="#ffffff">
-
-<p> </p>
-<a href="#skip" title="Skip navigation bar"></a>
-<table width="100%"><td align=left><tr>
-<td align=left><a href="../../spec-index.html">Spec Index</a></td>
-<td align=right><i>A Collection of Jini Technology Helper Utilities and Services Specifications
-</i></td>
-</tr>
-</table>
-<a name="skip"></a>
-<br clear="all">
-
-
-<hr align="left">
-<table width="90%">
-<tr>
-<td align="right" font size="4"><b>Version 3.0</b></td>
-</tr>
-</table>
-
-<blockquote>
-<h2>
-  <a name="1022667"> </a>DU - Jini<font size="-1"><sup>TM</sup></font> Discovery Utilities Specification
-</h2>
-<h3 class="Heading2">
-  <a name="1022668"> </a>DU.1	 Introduction
-</h3>
-<p class="Body">
-  <a name="1022672"> </a>Each discovering entity in a Java<font size="-1"><sup>TM</sup></font> virtual machine (JVM)<a href="#1022671"><sup>1</sup></a> on a given host is independently responsible for obtaining references to lookup services. In this specification we first cover a set of <em class="Emphasis">discovery management interfaces</em> that define the policies to apply when implementing helper utilities that manage an entity's discovery duties: in particular, the management of multicast (group) discovery and unicast (locator) discovery. After the discovery management interfaces are defined, a set of standard helper utility classes that implement one or more of those interfaces is presented. A utility for performing unicast discovery controlled by constraints is also described. This specification closes with a discussion of a set of lower-level utility classes that can be useful when applying the discovery management policies to build higher-level helper utilities for
  discovery.
-</p>
-<h3 class="Heading3">
-  <a name="997296"> </a>DU.1.1	 Dependencies
-</h3
-<p class="Body">
-  <a name="997297"> </a>This specification relies on the following other specifications:
-</p>
-<ul>
-
-  <li class="SmartList1"><a name="997299"> </a><em class="Emphasis">Java<font size="-1"><sup>TM</sup></font> Object Serialization Specification</em> <p>
-  <li class="SmartList1"><a name="1009473"> </a><em class="Emphasis"><a href="discovery-spec.html">Jini<font size="-1"><sup>TM</sup></font> Discovery and Join Specification</a></em><p>
-  <li class="SmartList1"><a name="1009473"> </a><em class="Emphasis"><a href="lookup-spec.html">Jini<font size="-1"><sup>TM</sup></font> Lookup Service Specification</a></em><p>
-</ul>
-
-<h3 class="Heading2">
-  <a name="1022214"> </a>DU.2	 The Discovery Management Interfaces
-</h3>
-<h4 class="Heading3">
-  <a name="1022215"> </a>DU.2.1	 Overview
-</h4>
-<p class="Body">
-  <a name="1022216"> </a>Discovery is one behavior that is common to all entities wishing to interact with a Jini lookup service. Whether an entity is a client, a service, or a service acting as a client, the entity must first discover a lookup service, before the entity can begin interacting with that lookup service.
-</p>
-<p class="Body">
-  <a name="1022217"> </a>The interfaces collectively referred to as the <em class="Emphasis">discovery management</em> interfaces specify sets of methods that define a mechanism that may be used to manage various aspects of the discovery duties of entities that wish to participate in an application environment for Jini technology (a <em class="Emphasis">Jini application environment</em>). These interfaces provide a uniform way to define utility classes that perform the necessary discovery-related management duties on behalf of a client or service. Currently, there are three discovery management interfaces belonging to the package <code>net.jini.discovery</code>:
-</p>
-<ul>
-
-  <li class="SmartList1"><a name="1022218"> </a><code>DiscoveryManagement</code><p>
-  <li class="SmartList1"><a name="1022219"> </a><code>DiscoveryGroupManagement</code><p>
-  <li class="SmartList1"><a name="1022220"> </a><code>DiscoveryLocatorManagement</code>
-</ul>
-
-<p class="Body">
-  <a name="1022221"> </a>The <code>DiscoveryManagement</code> interface defines semantics for methods related to the discovery event mechanism and discovery process termination. Through this interface, an entity can register or un-register for discovery events, discard a lookup service, or terminate the discovery process.
-</p>
-<p class="Body">
-  <a name="1022222"> </a>The <code>DiscoveryGroupManagement</code> interface defines methods related to the management of the sets of lookup services that are to be discovered using the multicast discovery protocols (see the <a href="discovery-spec.html"><em class="Emphasis">Jini Discovery and Join Specification</em></a>). The methods of this interface define how an entity accesses or modifies the set of groups whose members are lookup services that the entity is interested in discovering through group discovery.
-</p>
-<p class="Body">
-  <a name="1022223"> </a>The <code>DiscoveryLocatorManagement</code> interface defines methods related to the management of the set of lookup services that are to be discovered using the unicast discovery protocol (as defined in the <a href="discovery-spec.html"><em class="Emphasis">Jini Discovery and Join Specification</em></a>). The methods of this interface define how an entity accesses or modifies the contents of the set of <code>LookupLocator</code> objects corresponding to the specific lookup services the entity has targeted for locator discovery.
-</p>
-<p class="Body">
-  <a name="1022224"> </a>Although each interface defines semantics for methods involved in the management of the discovery process, the individual roles each interface plays in that process are independent of each other. Because of this independence, there may be scenarios where it is desirable to implement some subset of these interfaces.
-</p>
-<p class="Body">
-  <a name="1022225"> </a>For example, a class may wish to implement the functionality defined in <code>DiscoveryManagement</code>, but may not wish to allow entities to modify the groups and locators associated with the lookup services to be discovered. Such a class may have a "hard-coded" list of the groups and locators that it internally registers with the discovery process. For this case, the class would implement only <code>DiscoveryManagement</code>.
-</p>
-<p class="Body">
-  <a name="1029478"> </a>Alternatively, another class may not wish to allow the entity to register more than one listener with the discovery event mechanism; nor may it wish to allow the entity to terminate discovery. It may simply wish to allow the entity to modify the sets of lookup services that will be discovered. Such a class would implement both <code>DiscoveryGroupManagement</code> and <code>DiscoveryLocatorManagement</code>, but not <code>DiscoveryManagement</code>.
-</p>
-<p class="Body">
-  <a name="1029479"> </a>A specific example of a class that implements only a subset of the set of interfaces specified here is the <code>LookupDiscovery</code> utility class defined later in this specification. That class implements both the <code>DiscoveryManagement</code> and <code>DiscoveryGroupManagement</code> interfaces, but not the <code>DiscoveryLocatorManagement</code> interface.
-</p>
-<p class="Body">
-  <a name="1022228"> </a>Throughout this discussion of the discovery management interfaces, the phrase <em class="Emphasis">implementation class</em> refers to any concrete class that implements one or more of those interfaces. The phrase <em class="Emphasis">implementation object</em> should be understood to mean an instance of such an implementation class. Additionally, whenever a description refers to the <em class="Emphasis">discovering entity</em> (or simply, the <em class="Emphasis">entity</em><em class="Emphasis">), </em>that phrase is intended to be interpreted as the object (the client or service) that has created an implementation object, and which wishes to use the public methods specified by these interfaces and provided by that object.
-</p>
-<h4 class="Heading3">
-  <a name="1022229"> </a>DU.2.2	 Other Types
-</h4>
-<p class="Body">
-  <a name="1022230"> </a>The types defined in the specification of the discovery management interfaces are in the <code>net.jini.discovery</code> package. The following additional types may also be referenced in this specification. Whenever referenced, these object types will be referenced in unqualified form:
-</p>
-<pre  class="Preformatted">
-net.jini.core.discovery.LookupLocator
-net.jini.core.lookup.ServiceRegistrar
-net.jini.discovery.DiscoveryEvent
-net.jini.discovery.DiscoveryListener
-net.jini.discovery.DiscoveryChangeListener
-net.jini.discovery.LookupDiscovery
-net.jini.discovery.LookupDiscoveryManager
-java.io.IOException
-java.security.Permission
-java.util.EventListener
-java.util.EventObject
-java.util.Map
-</code></pre>
-<h4 class="Heading3">
-  <a name="1022232"> </a>DU.2.3	 The <code>DiscoveryManagement</code> Interface
-</h4>
-<p class="Body">
-  <a name="1022233"> </a>The public methods specified by the <code>DiscoveryManagement</code> interface are:
-</p>
-<pre  class="Preformatted">
-package net.jini.discovery;
-
-public interface DiscoveryManagement {
-    public void addDiscoveryListener
-                                 (DiscoveryListener listener);
-    public void removeDiscoveryListener
-                                 (DiscoveryListener listener);
-    public ServiceRegistrar[] getRegistrars();
-    public void discard(ServiceRegistrar proxy);
-    public void terminate();
-}
-</code></pre>
-<h5 class="Heading4">
-  <a name="1022235"> </a>DU.2.3.1	 The Semantics
-</h5>
-<p class="Body">
-  <a name="1022236"> </a>The <code>DiscoveryManagement</code> interface defines methods related to the discovery event mechanism and discovery process termination. Through this interface, an entity can register or un-register <code>DiscoveryListener</code> objects to receive discovery events (instances of <code>DiscoveryEvent</code>), retrieve proxies to the currently discovered lookup services, discard a lookup service so that it is eligible for re-discovery, or terminate the discovery process.
-</p>
-<p class="Body">
-  <a name="1022237"> </a>Implementation classes of this interface may impose additional semantics on any method. For example, such a class may choose to require that rather than simply terminate discovery processing, the <code>terminate</code> method additionally should cancel all leases held by the implementation object and terminate all lease management being performed on behalf of the entity.
-</p>
-<p class="Body">
-  <a name="1029495"> </a>For information on any additional semantics imposed on a method of this interface, refer to the specification of the particular implementation class.
-</p>
-<p class="Body">
-  <a name="1029496"> </a>The <code>DiscoveryEvent</code>, <code>DiscoveryListener</code>, and <code>DiscoveryChangeListener</code> classes are defined later in this specification.
-</p>
-<p class="Body">
-  <a name="1022240"> </a>The <code>addDiscoveryListener</code> method adds a listener to the set of objects listening for discovery events. This method takes a single argument as input: an instance of <code>DiscoveryListener</code> corresponding to the listener to add to the set.
-</p>
-<p class="Body">
-  <a name="1022241"> </a>Once a listener is registered, it will be notified of all lookup services discovered to date, and will then be notified as new lookup services are discovered or existing lookup services are discarded.
-</p>
-<p class="Body">
-  <a name="1022758"> </a>If the added listener is also an instance of <code>DiscoveryChangeListener</code> (a subclass of <code>DiscoveryListener</code>), then in addition to receiving events related to discovered and discarded lookup services, that listener will also be notified of group membership changes that occur in any of the lookup services targeted for at least group discovery.
-</p>
-<p class="Body">
-  <a name="1022242"> </a>If <code>null</code> is input to this method, a <code>NullPointerException</code> is thrown. If the <code>listener</code> input to this method duplicates (using the <code>equals</code> method) another element in the set of listeners, no action is taken.
-</p>
-<p class="Body">
-  <a name="1028666"> </a>Implementations of the <code>DiscoveryManagement</code> interface must guarantee reentrancy with respect to <code>DiscoveryListener</code> objects registered through this method. Should the instance of <code>DiscoveryManagement</code> invoke a method on a registered listener (a local call), calls from that method to any method of the <code>DiscoveryManagement</code> instance are guaranteed not to result in a deadlock condition.
-</p>
-<p class="Body">
-  <a name="1022243"> </a>The <code>removeDiscoveryListener</code> method removes a listener from the set of objects listening for discovery events. This method takes a single argument as input: an instance of <code>DiscoveryListener</code> corresponding to the listener to remove from the set.
-</p>
-<p class="Body">
-  <a name="1028673"> </a>If the listener object input to this method does not exist in the set of listeners maintained by the implementation class, then this method will take no action.
-</p>
-<p class="Body">
-  <a name="1022246"> </a>The <code>getRegistrars</code> method returns an array consisting of instances of the <code>ServiceRegistrar</code> interface. Each element in the returned set is a proxy to one of the currently discovered lookup services. Each time this method is invoked, a new array is returned. If no lookup services have been discovered, an empty array is returned. This method takes no arguments as input.
-</p>
-<p class="Body">
-  <a name="1022247"> </a>The <code>discard</code> method removes a particular lookup service from the managed set of lookup services, and makes that lookup service eligible to be re-discovered. This method takes a single argument as input: an instance of the <code>ServiceRegistrar</code> interface corresponding to the proxy to the lookup service to discard.
-</p>
-<p class="Body">
-  <a name="1029504"> </a>If the proxy input to this method is <code>null</code>, or if it matches (using the <code>equals</code> method) none of the lookup services in the managed set, this method takes no action.
-</p>
-<p class="Body">
-  <a name="1029505"> </a>Currently, there exist utilities such as the <code>LookupDiscovery</code> and <code>LookupDiscoveryManager</code> helper utilities that will, on behalf of a discovering entity, automatically discard a lookup service upon determining that the lookup service has become unreachable or uninteresting. Although most entities will typically employ such a utility to help with both its discovery as well as its discard duties, it is important to note that if the entity itself determines that the lookup service is unavailable, it is the responsibility of the entity to invoke the <code>discard</code> method. This scenario usually happens when the entity attempts to interact with a lookup service, but encounters an exceptional condition (for example, a communication failure). When the entity actively discards a lookup service, the discarded lookup service becomes eligible to be re-discovered. Allowing unreachable lookup services to remain in the managed set can r
 esult in repeated and unnecessary attempts to interact with lookup services with which the entity can no longer communicate. Thus, the mechanism provided by this method is intended to provide a way to remove such "stale" lookup service references from the managed set.
-</p>
-<p class="Body">
-  <a name="1022250"> </a>Invoking the <code>discard</code> method defined by the <code>DiscoveryManagement</code> interface will result in the flushing of the lookup service from the appropriate cache, ultimately causing a discard notification--referred to as a <em class="Emphasis">discarded</em> <em class="Emphasis">event--</em>to be sent to all listeners registered with the implementation object. When this method completes successfully, the lookup service is guaranteed to have been removed from the managed set, and the lookup service is then said to have been "discarded". No such guarantee is made with respect to when the discarded event is sent to the registered listeners. That is, the event notifying the listeners that the lookup service has been discarded may or may not be sent asynchronously.
-</p>
-<p class="Body">
-  <a name="1022251"> </a>The <code>terminate</code> method ends all discovery processing being performed on behalf of the entity. This method takes no input arguments.
-</p>
-<p class="Body">
-  <a name="1022252"> </a>After this method has been invoked, no new lookup services will be discovered, and the effect of any new operations performed on the current implementation object are undefined.
-</p>
-<p class="Body">
-  <a name="1022253"> </a>Any additional termination semantics must be defined by the implementation class.
-</p>
-<h4 class="Heading3">
-  <a name="1022254"> </a>DU.2.4	 The <code>DiscoveryGroupManagement</code> Interface
-</h4>
-<p class="Body">
-  <a name="1022255"> </a>The public methods specified by the <code>DiscoveryGroupManagement</code> interface are as follows:
-</p>
-<pre  class="Preformatted">
-package net.jini.discovery;
-
-public interface DiscoveryGroupManagement {
-    public static final String[] ALL_GROUPS = null;
-    public static final String[] NO_GROUPS = new String[0];
-    	 
-    public String[] getGroups();
-    public void addGroups(String[] groups) throws IOException;
-    public void setGroups(String[] groups) throws IOException;
-    public void removeGroups(String[] groups);
-}
-</code></pre>
-<h5 class="Heading4">
-  <a name="1022257"> </a>DU.2.4.1	 The Semantics
-</h5>
-<p class="Body">
-  <a name="1025531"> </a>The <code>DiscoveryGroupManagement</code> interface defines methods and constants related to the management of the set containing the names of the groups whose members are the lookup services that are to be discovered using the multicast discovery protocols; that is, lookup services that are discovered by way of group discovery. The methods of this interface define how an entity retrieves or modifies the managed set of groups to discover, where phrases such as "the groups to discover" or "discovering the desired groups" refer to the discovery of the lookup services that are members of those groups.
-</p>
-<p class="Body">
-  <a name="1022259"> </a>The methods that modify the managed set of groups each take a single input parameter: a <code>String</code> array, none of whose elements may be <code>null</code>. Each of these methods throws a <code>NullPointerException</code> when at least one element of the input array is <code>null</code>.
-</p>
-<p class="Body">
-  <a name="1022260"> </a>The empty set is denoted by an empty array, and "no set" is indicated by <code>null</code>. Invoking any of these methods with an input array that contains duplicate group names is equivalent to performing the invocation with the duplicates removed from the array.
-</p>
-<p class="Body">
-  <a name="1022261"> </a>The <code>ALL_GROUPS</code> and the <code>NO_GROUPS</code> constants are defined for convenience, and represent no set and the empty set respectively. 
-</p>
-<p class="Body">
-  <a name="1022262"> </a>The <code>getGroups</code> method returns an array consisting of the names of the groups in the managed set; that is, the names of the groups the implementation object is currently configured to discover.
-</p>
-<p class="Body">
-  <a name="1022263"> </a>If the managed set of groups is empty, this method will return an empty array. If there is no managed set of groups, then null (<code>ALL_GROUPS</code>) is returned, indicating that any lookup service within range--even those that have no group affiliation--are to be discovered.
-</p>
-<p class="Body">
-  <a name="1022918"> </a>If an empty array is returned, that array is guaranteed to be referentially equal to the <code>NO_GROUPS</code> constant; that is, the array returned from that method and the <code>NO_GROUPS</code> constant can be tested for equality using the <code>==</code> operator.
-</p>
-<p class="Body">
-  <a name="1022906"> </a>This method takes no arguments as input and, provided the managed set of groups currently exists, will return a new array upon each invocation.
-</p>
-<p class="Body">
-  <a name="1022264"> </a>The <code>addGroups</code> method adds a set of group names to the managed set. The array input to this method contains the group names to be added to the set.
-</p>
-<p class="Body">
-  <a name="1022267"> </a>This method throws <code>IOException</code> because an invocation of this method may result in the re-initiation of the discovery process, which can throw <code>IOException</code> when socket allocation occurs.
-</p>
-<p class="Body">
-  <a name="1022268"> </a>This method throws an <code>UnsupportedOperationException</code> if there is no managed set of groups to augment, and it throws a <code>NullPointerException</code> if <code>null</code> (<code>ALL_GROUPS</code>) is input. If an empty array (<code>NO_GROUPS</code>) is input, the managed set of groups will not change.
-</p>
-<p class="Body">
-  <a name="1022269"> </a>The <code>setGroups</code> method replaces all of the group names in the managed set with names from a new set. The array input to this method contains the group names with which to replace the current names in the managed set.
-</p>
-<p class="Body">
-  <a name="1022270"> </a>Once a new group name has been placed in the managed set, no event will be sent to the entity's listener for the lookup services belonging to that group that have already been discovered, although attempts to discover all (as yet) undiscovered lookup services belonging to that group will continue to be made.
-</p>
-<p class="Body">
-  <a name="1022271"> </a>If <code>null</code> (<code>ALL_GROUPS</code>) is input to <code>setGroups</code>, then attempts will be made to discover all (as yet) undiscovered lookup services located within the <em class="Emphasis">multicast radius (</em><a href="discoveryutil-spec.html#1003666">Section&nbsp;DU.3, "LookupDiscovery Utility"</a><em class="Emphasis">)</em> of the implementation object, regardless of group membership.
-</p>
-<p class="Body">
-  <a name="1026358"> </a>If an empty array (<code>NO_GROUPS</code>) is input to <code>setGroups</code>, then group discovery will be halted until the managed set of groups is changed--through a subsequent call to this method or to <code>addGroups</code>--to a set that is either a non-empty set of group names or <code>null</code> (<code>ALL_GROUPS</code>).
-</p>
-<p class="Body">
-  <a name="1026360"> </a>This method throws <code>IOException</code>. This is because an invocation of this method may result in the re-initiation of the discovery process, a process that can throw <code>IOException</code> when socket allocation occurs.
-</p>
-<p class="Body">
-  <a name="1022274"> </a>The <code>removeGroups</code> method deletes a set of group names from the managed set of groups. The array input to this method contains the group names to be removed from the managed set.
-</p>
-<p class="Body">
-  <a name="1022275"> </a>This method throws an <code>UnsupportedOperationException</code> if there is no managed set of groups from which to remove elements. If <code>null</code> (<code>ALL_GROUPS</code>) is input to <code>removeGroups</code>, a <code>NullPointerException</code> will be thrown. 
-</p>
-<p class="Body">
-  <a name="1022962"> </a>If any element of the set of groups to be removed is not contained in the managed set, <code>removeGroups</code> takes no action with respect to that element. If an empty array (<code>NO_GROUPS</code>) is input, the managed set of groups will not change.
-</p>
-<p class="Body">
-  <a name="1022975"> </a>Once a new group name is added to the managed set as a result of an invocation of either <code>addGroups</code> or <code>setGroups</code>, attempts will be made--using the multicast request protocol--to discover all (as yet) undiscovered lookup services that are members of that group. If there are no responses to the multicast requests, the implementation object will stop sending multicast requests, and will simply listen for multicast announcements containing the new groups of interest.
-</p>
-<p class="Body">
-  <a name="1022276"> </a>Any already discovered lookup service that is a member of one or more of the groups removed from the managed set as a result of an invocation of either <code>setGroups</code> or <code>removeGroups</code> will be discarded and will no longer be eligible for discovery, but only if that lookup service satisfies both of the following conditions:
-</p>
-<ul>
-
-  <li class="SmartList1"><a name="1022277"> </a>the lookup service is not a member of any group in the new managed set that resulted from the invocation of <code>setGroups</code> or <code>removeGroups</code>, and<p>
-  <li class="SmartList1"><a name="1022278"> </a>the lookup service is not currently eligible for discovery through other means (such as locator discovery).
-</ul>
-
-<h4 class="Heading3">
-  <a name="1022279"> </a>DU.2.5	 The <code>DiscoveryLocatorManagement</code> Interface
-</h4>
-<p class="Body">
-  <a name="1022280"> </a>The public methods specified by the <code>DiscoveryLocatorManagement</code> interface are as follows:
-</p>
-<pre  class="Preformatted">
-package net.jini.discovery;
-
-public interface DiscoveryLocatorManagement {
-    public LookupLocator[] getLocators();
-    public void addLocators(LookupLocator[] locators);
-    public void setLocators(LookupLocator[] locators);
-    public void removeLocators(LookupLocator[] locators);
-}
-</code></pre>
-<h5 class="Heading4">
-  <a name="1022282"> </a>DU.2.5.1	 The Semantics
-</h5>
-<p class="Body">
-  <a name="1025588"> </a>The <code>DiscoveryLocatorManagement</code> interface defines methods related to the management of the set of <code>LookupLocator</code> objects corresponding to the specific lookup services that are to be discovered using the unicast discovery protocol; that is, lookup services that are discovered by way of locator discovery. The methods of this interface define how an entity retrieves or modifies the managed set of locators to discover. Phrases such as "the locators to discover" and "discovering the desired locators" refer to the discovery of the lookup services that are associated with those locators.
-</p>
-<p class="Body">
-  <a name="1022284"> </a>The methods that modify the managed set of locators each take a single input parameter: an array of <code>LookupLocator</code> objects, none of whose elements may be <code>null</code>. Each of these methods throws a <code>NullPointerException</code> when at least one element of the input array is <code>null</code>.
-</p>
-<p class="Body">
-  <a name="1022285"> </a>Invoking any of these methods with an input array that contains duplicate locators (as determined by <code>LookupLocator.equals</code>) is equivalent to performing the invocation with the duplicates removed from the array.
-</p>
-<p class="Body">
-  <a name="1023019"> </a>The <code>getLocators</code> method returns an array containing the set of <code>LookupLocator</code> objects in the managed set of locators; that is, the locators of the specific lookup services that the implementation object is currently interested in discovering.
-</p>
-<p class="Body">
-  <a name="1023037"> </a>The returned set includes both the set of locators corresponding to lookup services that have already been discovered and the set of those that have not yet been discovered.
-</p>
-<p class="Body">
-  <a name="1023041"> </a>If the managed set is empty, this method returns an empty array. This method takes no arguments as input, and returns a new array upon each invocation.
-</p>
-<p class="Body">
-  <a name="1023020"> </a>The <code>addLocators</code> method adds a set of locators to the managed set. The array input to this method contains the set of <code>LookupLocator</code> objects to add to the managed set.
-</p>
-<p class="Body">
-  <a name="1023058"> </a>If <code>null</code> is input to <code>addLocators</code>, a <code>NullPointerException</code> will be thrown. If an empty array is input, the managed set of locators will not change.
-</p>
-<p class="Body">
-  <a name="1022289"> </a>The <code>setLocators</code> method replaces all of the locators in the managed set with <code>LookupLocator</code> objects from a new set. The array input to this method contains the set of <code>LookupLocator</code> objects with which to replace the current locators in the managed set.
-</p>
-<p class="Body">
-  <a name="1026284"> </a>If <code>null</code> is input to <code>setLocators</code>, a <code>NullPointerException</code> will be thrown.
-</p>
-<p class="Body">
-  <a name="1026376"> </a>If an empty array is input to <code>setLocators</code>, then locator discovery will be halted until the managed set of locators is changed--through a subsequent call to this method or to <code>addLocators</code>--to a set that is non-null and non-empty.
-</p>
-<p class="Body">
-  <a name="1022291"> </a>The <code>removeLocators</code> method deletes a set of locators from the managed set. The array input to this method contains the set of <code>LookupLocator</code> objects to remove from the managed set.
-</p>
-<p class="Body">
-  <a name="1022292"> </a>If <code>null</code> is input to <code>removeLocators</code>, a <code>NullPointerException</code> will be thrown. 
-</p>
-<p class="Body">
-  <a name="1023074"> </a>If any element of the set of locators to remove is not contained in the managed set, <code>removeLocators</code> takes no action with respect to that element. If an empty array is input, the managed set of locators will not change.
-</p>
-<p class="Body">
-  <a name="1023095"> </a>Any already discovered lookup service, corresponding to a locator that is a member of the set of locators removed from the managed set as a result of an invocation of either <code>setLocators</code> or <code>removeLocators</code>, will be discarded and will no longer be eligible for discovery, but only if it is not currently eligible for discovery through other means (such as group discovery).
-</p>
-<h4 class="Heading3">
-  <a name="1023110"> </a>DU.2.6	 Supporting Interfaces and Classes
-</h4>
-<p class="Body">
-  <a name="1023111"> </a>Discovery management depends on the interfaces <code>DiscoveryListener</code> and <code>DiscoveryChangeListener</code>, and on the concrete class <code>DiscoveryEvent</code>.
-</p>
-<h5 class="Heading4">
-  <a name="1023113"> </a>DU.2.6.1	 The <code>DiscoveryListener</code> Interface
-</h5>
-<p class="Body">
-  <a name="1023163"> </a>The public methods specified by the <code>DiscoveryListener</code> interface are as follows:
-</p>
-<pre  class="Preformatted">
-package net.jini.discovery;
-
-public interface DiscoveryListener extends EventListener {
-    public void discovered(DiscoveryEvent e);
-    public void discarded(DiscoveryEvent e);
-}
-</code></pre>
-<p class="Body">
-  <a name="1023634"> </a>When an entity employs an object that implements one or more of the discovery management interfaces to perform and manage the entity's discovery duties, the entity often will want that object--generally referred to as a <em class="Emphasis">discovery utility--</em>to notify the entity when a desired lookup service is either discovered or discarded. The <code>DiscoveryListener</code> interface defines a mechanism through which an entity may receive such notifications from a discovery utility. When an entity registers interest in these notifications, an implementation of this interface must be provided to the discovery utility being employed. Through this registered listener, the entity may then receive instances of the <code>DiscoveryEvent</code> class, which encapsulate the required information associated with the desired notifications.
-</p>
-<div style="color: #000000; font-family: Times; font-size: 11pt; font-style: normal; font-weight: bold; margin-bottom: 8pt; margin-left: 36pt; margin-right: 0pt; margin-top: 13pt; text-align: left; text-decoration: none; text-indent: -36pt; text-transform: none; vertical-align: baseline">
-<a name="1023707"> </a>The Semantics<br>
-</div>
-<p class="Body">
-  <a name="1023708"> </a>The events received by listeners implementing the <code>DiscoveryListener</code> interface can be the result of either group discovery or locator discovery. These events contain the discovered or discarded registrars, as well as the set of member groups corresponding to each registrar (see the specification of the <code>DiscoveryEvent</code> class).
-</p>
-<p class="Body">
-  <a name="1023722"> </a>The <code>discovered</code> method is called whenever a new lookup service is discovered or a discarded lookup service is re-discovered.
-</p>
-<p class="Body">
-  <a name="1023791"> </a>The <code>discarded</code> method is called whenever a previously discovered lookup service is discarded because the lookup service was determined to be either unreachable or no longer interesting to the entity, and the discard process was initiated by either the entity itself (an <em class="Emphasis">active</em> discard) or the discovery utility employed by the entity (a <em class="Emphasis">passive</em> discard).
-</p>
-<p class="Body">
-  <a name="1029102"> </a>The <code>DiscoveryGroupManagement</code> interface makes the following concurrency guarantee: for any given listener object that implements this interface or any sub-interface, no two methods defined by the interface or sub-interface will be invoked at the same time. This applies to different invocations of the same or different methods, on the same or different listeners registered with a single <code>DiscoveryManagement</code> instance. For example, the <code>discovered</code> method of one listener will not be invoked while the invocation of another listener's <code>discovered</code> or <code>discarded</code> method is in progress. Similarly, the one listener's <code>discovered</code> method will not be invoked while that same listener's <code>discard</code> method is in progress.
-</p>
-<h5 class="Heading4">
-  <a name="1023759"> </a>DU.2.6.2	 The <code>DiscoveryChangeListener</code> Interface
-</h5>
-<p class="Body">
-  <a name="1023782"> </a>The <code>DiscoveryChangeListener</code> interface specifies only one public method:
-</p>
-<pre  class="Preformatted">
-package net.jini.discovery;
-
-public interface DiscoveryChangeListener
-                 extends DiscoveryListener
-{
-    public void changed(DiscoveryEvent e);
-}
-</pre>
-<p class="Body">
-  <a name="1023762"> </a>In addition to being notified when a desired lookup service is discovered or discarded, some entities may also wish to be notified when a lookup service experiences changes in its group membership. The <code>DiscoveryChangeListener</code> interface defines an extension to the <code>DiscoveryListener</code> interface, providing a mechanism through which an entity may receive these additional notifications--referred to as <em class="Emphasis">changed</em> <em class="Emphasis">events</em>. As with the <code>DiscoveryListener</code> interface, when an entity wishes to receive changed events in addition to discovered and discarded events, an implementation of this interface must be provided to the discovery utility being employed. It is through that registered listener that the entity receives the desired notifications encapsulated in instances of the <code>DiscoveryEvent</code> class.
-</p>
-<div style="color: #000000; font-family: Times; font-size: 11pt; font-style: normal; font-weight: bold; margin-bottom: 8pt; margin-left: 36pt; margin-right: 0pt; margin-top: 13pt; text-align: left; text-decoration: none; text-indent: -36pt; text-transform: none; vertical-align: baseline">
-<a name="1023877"> </a>The Semantics<br>
-</div>
-<p class="Body">
-  <a name="1023878"> </a>When the entity receives a <code>DiscoveryEvent</code> object through an instance of the <code>DiscoveryChangeListener</code> interface, the event contains the discovered, discarded, or changed registrars, as well as the set of member groups corresponding to each registrar. In the case of a changed event, each set of groups referenced in the event contains the new groups in which the corresponding registrar is a member.
-</p>
-<p class="Body">
-  <a name="1023765"> </a>The <code>changed</code> method is called whenever the discovery utility encounters changes in the set of groups in which a previously discovered lookup service is a member.
-</p>
-<p class="Body">
-  <a name="1024039"> </a>It is important to note that instances of this interface are eligible to receive changed events for only those lookup services that the entity has requested be discovered by (at least) group discovery. That is, if the entity requests that <em class="Emphasis">only</em> locator discovery be used to discover a specific lookup service, the listener will receive no changed events for that lookup service. This is because the semantics of this interface assume that since the entity expressed no interest in <em class="Emphasis">discovering</em> the lookup service through its group membership, it must also have no interest in any <em class="Emphasis">changes</em> in that lookup service's group membership. Thus, if an entity wishes to receive changed events for one or more lookup services, the entity must request that those lookup services be discovered by either group discovery alone, or by both group and locator discovery.
-</p>
-<h5 class="Heading4">
-  <a name="1023120"> </a>DU.2.6.3	 The <code>DiscoveryEvent</code> Class
-</h5>
-<p class="Body">
-  <a name="1023294"> </a>The public methods provided by the <code>DiscoveryEvent</code> class are as follows:
-</p>
-<pre  class="Preformatted">
-package net.jini.discovery;
-
-public class DiscoveryEvent extends EventObject {
-    public DiscoveryEvent(Object source, Map groups) {...}
-    public DiscoveryEvent(Object source, 
-                          ServiceRegistrar[] regs) {...}
-    public Map getGroups() {...}
-    public ServiceRegistrar[] getRegistrars() {...}
-}
-</pre>
-<p class="Body">
-  <a name="1023597"> </a>The <code>DiscoveryEvent</code> class provides an encapsulation of event information that discovery utilities can use to notify an entity of the occurrence of an event involving one or more <code>ServiceRegistrar</code> objects (lookup services) in which the entity has registered interest. Discovery utilities pass an instance of this class to the entity's discovery listener(s) when one of the following events occurs:
-</p>
-<ul>
-
-  <li class="SmartList1"><a name="1024126"> </a>Each lookup service referenced in the event has been discovered for the first time, or re-discovered after having been discarded.<p>
-  <li class="SmartList1"><a name="1024130"> </a>Each lookup service referenced in the event has been either actively or passively discarded.<p>
-  <li class="SmartList1"><a name="1024178"> </a>For each lookup service referenced in the event, the set of groups in which the lookup service is a member has changed.
-</ul>
-
-<p class="Body">
-  <a name="1024179"> </a>The <code>DiscoveryEvent</code> class is a subclass of <code>EventObject</code>, adding the following additional items of abstract state: a set of <code>ServiceRegistrar</code> instances (<em class="Emphasis">registrars</em>) referencing the affected lookup services, and a mapping from each of those registrars to their current set of member groups. Methods are defined through which this additional state may be retrieved upon receipt of an instance of this class.
-</p>
-<div style="color: #000000; font-family: Times; font-size: 11pt; font-style: normal; font-weight: bold; margin-bottom: 8pt; margin-left: 36pt; margin-right: 0pt; margin-top: 13pt; text-align: left; text-decoration: none; text-indent: -36pt; text-transform: none; vertical-align: baseline">
-<a name="1024079"> </a>The Semantics<br>
-</div>
-<p class="Body">
-  <a name="1024215"> </a>The <code>equals</code> method for this class returns <code>true</code> if and only if two instances of this class refer to the same object. That is, <code>x</code> and <code>y</code> are equal instances of this class if and only if <code>x</code> <code>==</code> <code>y</code> has the value <code>true</code>.
-</p>
-<p class="Body">
-  <a name="1024384"> </a>The constructor for this class has two forms, where both forms expect two input parameters. Each form of the constructor takes, as its first input parameter, a reference to the source of the event; that is, the discovery utility object that created the event instance and sent it to the entity's listener(s) through the invocation of the <code>discovered</code>, <code>discarded</code>, or <code>changed</code> method on each listener. Note that neither form of the constructor makes a copy of the second parameter. That is, the reference input to the second parameter is shared with the invoking entity.
-</p>
-<p class="Body">
-  <a name="1028739"> </a>Depending on the constructor employed, the second parameter is one of the following:
-</p>
-<ul>
+#DU - Jini<font size="-1"><sup>TM</sup></font> Discovery Utilities Specification
+
+##DU.1	 Introduction
+
+Each discovering entity in a Java<font size="-1"><sup>TM</sup></font> virtual machine (JVM)<sup>1</sup> on a given host is independently responsible for obtaining references to lookup services. In this specification we first cover a set of _discovery management interfaces_ that define the policies to apply when implementing helper utilities that manage an entity's discovery duties: in particular, the management of multicast (group) discovery and unicast (locator) discovery. After the discovery management interfaces are defined, a set of standard helper utility classes that implement one or more of those interfaces is presented. A utility for performing unicast discovery controlled by constraints is also described. This specification closes with a discussion of a set of lower-level utility classes that can be useful when applying the discovery management policies to build higher-level helper utilities for discovery.
+
+###DU.1.1	 Dependencies
+
+This specification relies on the following other specifications:
+
+  - _Java<font size="-1"><sup>TM</sup></font> Object Serialization Specification_ 
+  - _Jini<font size="-1"><sup>TM</sup></font> Discovery and Join Specification_
+  - _Jini<font size="-1"><sup>TM</sup></font> Lookup Service Specification_
+
+##DU.2	 The Discovery Management Interfaces
+
+###DU.2.1	 Overview
+
+Discovery is one behavior that is common to all entities wishing to interact with a Jini lookup service. Whether an entity is a client, a service, or a service acting as a client, the entity must first discover a lookup service, before the entity can begin interacting with that lookup service.
+
+The interfaces collectively referred to as the _discovery management_ interfaces specify sets of methods that define a mechanism that may be used to manage various aspects of the discovery duties of entities that wish to participate in an application environment for Jini technology (a _Jini application environment_). These interfaces provide a uniform way to define utility classes that perform the necessary discovery-related management duties on behalf of a client or service. Currently, there are three discovery management interfaces belonging to the package `net.jini.discovery`:
+
+  - `DiscoveryManagement`
+  - `DiscoveryGroupManagement`
+  - `DiscoveryLocatorManagement`
+
+The `DiscoveryManagement` interface defines semantics for methods related to the discovery event mechanism and discovery process termination. Through this interface, an entity can register or un-register for discovery events, discard a lookup service, or terminate the discovery process.
+
+The `DiscoveryGroupManagement` interface defines methods related to the management of the sets of lookup services that are to be discovered using the multicast discovery protocols (see the _Jini Discovery and Join Specification_). The methods of this interface define how an entity accesses or modifies the set of groups whose members are lookup services that the entity is interested in discovering through group discovery.
+
+The `DiscoveryLocatorManagement` interface defines methods related to the management of the set of lookup services that are to be discovered using the unicast discovery protocol (as defined in the _Jini Discovery and Join Specification_). The methods of this interface define how an entity accesses or modifies the contents of the set of `LookupLocator` objects corresponding to the specific lookup services the entity has targeted for locator discovery.
+
+Although each interface defines semantics for methods involved in the management of the discovery process, the individual roles each interface plays in that process are independent of each other. Because of this independence, there may be scenarios where it is desirable to implement some subset of these interfaces.
+
+For example, a class may wish to implement the functionality defined in `DiscoveryManagement`, but may not wish to allow entities to modify the groups and locators associated with the lookup services to be discovered. Such a class may have a "hard-coded" list of the groups and locators that it internally registers with the discovery process. For this case, the class would implement only `DiscoveryManagement`.
+
+Alternatively, another class may not wish to allow the entity to register more than one listener with the discovery event mechanism; nor may it wish to allow the entity to terminate discovery. It may simply wish to allow the entity to modify the sets of lookup services that will be discovered. Such a class would implement both `DiscoveryGroupManagement` and `DiscoveryLocatorManagement`, but not `DiscoveryManagement`.
+
+A specific example of a class that implements only a subset of the set of interfaces specified here is the `LookupDiscovery` utility class defined later in this specification. That class implements both the `DiscoveryManagement` and `DiscoveryGroupManagement` interfaces, but not the `DiscoveryLocatorManagement` interface.
+
+Throughout this discussion of the discovery management interfaces, the phrase _implementation class_ refers to any concrete class that implements one or more of those interfaces. The phrase _implementation object_ should be understood to mean an instance of such an implementation class. Additionally, whenever a description refers to the _discovering entity_ (or simply, the _entity__), _that phrase is intended to be interpreted as the object (the client or service) that has created an implementation object, and which wishes to use the public methods specified by these interfaces and provided by that object.
+
+###DU.2.2	 Other Types
+
+The types defined in the specification of the discovery management interfaces are in the `net.jini.discovery` package. The following additional types may also be referenced in this specification. Whenever referenced, these object types will be referenced in unqualified form:
+
+    net.jini.core.discovery.LookupLocator
+    net.jini.core.lookup.ServiceRegistrar
+    net.jini.discovery.DiscoveryEvent
+    net.jini.discovery.DiscoveryListener
+    net.jini.discovery.DiscoveryChangeListener
+    net.jini.discovery.LookupDiscovery
+    net.jini.discovery.LookupDiscoveryManager
+    java.io.IOException
+    java.security.Permission
+    java.util.EventListener
+    java.util.EventObject
+    java.util.Map
+
+###DU.2.3	 The `DiscoveryManagement` Interface
+
+The public methods specified by the `DiscoveryManagement` interface are:
+
+    package net.jini.discovery;
+    
+    public interface DiscoveryManagement {
+        public void addDiscoveryListener(DiscoveryListener listener);
+        public void removeDiscoveryListener(DiscoveryListener listener);
+        public ServiceRegistrar[] getRegistrars();
+        public void discard(ServiceRegistrar proxy);
+        public void terminate();
+    }
+    
+####DU.2.3.1	 The Semantics
+
+The `DiscoveryManagement` interface defines methods related to the discovery event mechanism and discovery process termination. Through this interface, an entity can register or un-register `DiscoveryListener` objects to receive discovery events (instances of `DiscoveryEvent`), retrieve proxies to the currently discovered lookup services, discard a lookup service so that it is eligible for re-discovery, or terminate the discovery process.
+
+Implementation classes of this interface may impose additional semantics on any method. For example, such a class may choose to require that rather than simply terminate discovery processing, the `terminate` method additionally should cancel all leases held by the implementation object and terminate all lease management being performed on behalf of the entity.
+
+For information on any additional semantics imposed on a method of this interface, refer to the specification of the particular implementation class.
+
+The `DiscoveryEvent`, `DiscoveryListener`, and `DiscoveryChangeListener` classes are defined later in this specification.
+
+The `addDiscoveryListener` method adds a listener to the set of objects listening for discovery events. This method takes a single argument as input: an instance of `DiscoveryListener` corresponding to the listener to add to the set.
+
+Once a listener is registered, it will be notified of all lookup services discovered to date, and will then be notified as new lookup services are discovered or existing lookup services are discarded.
+
+If the added listener is also an instance of `DiscoveryChangeListener` (a subclass of `DiscoveryListener`), then in addition to receiving events related to discovered and discarded lookup services, that listener will also be notified of group membership changes that occur in any of the lookup services targeted for at least group discovery.
+
+If `null` is input to this method, a `NullPointerException` is thrown. If the `listener` input to this method duplicates (using the `equals` method) another element in the set of listeners, no action is taken.
+
+Implementations of the `DiscoveryManagement` interface must guarantee reentrancy with respect to `DiscoveryListener` objects registered through this method. Should the instance of `DiscoveryManagement` invoke a method on a registered listener (a local call), calls from that method to any method of the `DiscoveryManagement` instance are guaranteed not to result in a deadlock condition.
+
+The `removeDiscoveryListener` method removes a listener from the set of objects listening for discovery events. This method takes a single argument as input: an instance of `DiscoveryListener` corresponding to the listener to remove from the set.
+
+If the listener object input to this method does not exist in the set of listeners maintained by the implementation class, then this method will take no action.
+
+The `getRegistrars` method returns an array consisting of instances of the `ServiceRegistrar` interface. Each element in the returned set is a proxy to one of the currently discovered lookup services. Each time this method is invoked, a new array is returned. If no lookup services have been discovered, an empty array is returned. This method takes no arguments as input.
+
+The `discard` method removes a particular lookup service from the managed set of lookup services, and makes that lookup service eligible to be re-discovered. This method takes a single argument as input: an instance of the `ServiceRegistrar` interface corresponding to the proxy to the lookup service to discard.
+
+If the proxy input to this method is `null`, or if it matches (using the `equals` method) none of the lookup services in the managed set, this method takes no action.
+
+Currently, there exist utilities such as the `LookupDiscovery` and `LookupDiscoveryManager` helper utilities that will, on behalf of a discovering entity, automatically discard a lookup service upon determining that the lookup service has become unreachable or uninteresting. Although most entities will typically employ such a utility to help with both its discovery as well as its discard duties, it is important to note that if the entity itself determines that the lookup service is unavailable, it is the responsibility of the entity to invoke the `discard` method. This scenario usually happens when the entity attempts to interact with a lookup service, but encounters an exceptional condition (for example, a communication failure). When the entity actively discards a lookup service, the discarded lookup service becomes eligible to be re-discovered. Allowing unreachable lookup services to remain in the managed set can result in repeated and unnecessary attempts to interact wit
 h lookup services with which the entity can no longer communicate. Thus, the mechanism provided by this method is intended to provide a way to remove such "stale" lookup service references from the managed set.
+
+Invoking the `discard` method defined by the `DiscoveryManagement` interface will result in the flushing of the lookup service from the appropriate cache, ultimately causing a discard notification--referred to as a _discarded_ _event--_to be sent to all listeners registered with the implementation object. When this method completes successfully, the lookup service is guaranteed to have been removed from the managed set, and the lookup service is then said to have been "discarded". No such guarantee is made with respect to when the discarded event is sent to the registered listeners. That is, the event notifying the listeners that the lookup service has been discarded may or may not be sent asynchronously.
+
+The `terminate` method ends all discovery processing being performed on behalf of the entity. This method takes no input arguments.
+
+After this method has been invoked, no new lookup services will be discovered, and the effect of any new operations performed on the current implementation object are undefined.
+
+Any additional termination semantics must be defined by the implementation class.
+
+###DU.2.4	 The `DiscoveryGroupManagement` Interface
+
+The public methods specified by the `DiscoveryGroupManagement` interface are as follows:
+
+    package net.jini.discovery;
+    
+    public interface DiscoveryGroupManagement {
+        public static final String[] ALL_GROUPS = null;
+        public static final String[] NO_GROUPS = new String[0];
+    	     
+        public String[] getGroups();
+        public void addGroups(String[] groups) throws IOException;
+        public void setGroups(String[] groups) throws IOException;
+        public void removeGroups(String[] groups);
+    }
+
+####DU.2.4.1	 The Semantics
+
+The `DiscoveryGroupManagement` interface defines methods and constants related to the management of the set containing the names of the groups whose members are the lookup services that are to be discovered using the multicast discovery protocols; that is, lookup services that are discovered by way of group discovery. The methods of this interface define how an entity retrieves or modifies the managed set of groups to discover, where phrases such as "the groups to discover" or "discovering the desired groups" refer to the discovery of the lookup services that are members of those groups.
+
+The methods that modify the managed set of groups each take a single input parameter: a `String` array, none of whose elements may be `null`. Each of these methods throws a `NullPointerException` when at least one element of the input array is `null`.
+
+The empty set is denoted by an empty array, and "no set" is indicated by `null`. Invoking any of these methods with an input array that contains duplicate group names is equivalent to performing the invocation with the duplicates removed from the array.
+
+The `ALL_GROUPS` and the `NO_GROUPS` constants are defined for convenience, and represent no set and the empty set respectively. 
+
+The `getGroups` method returns an array consisting of the names of the groups in the managed set; that is, the names of the groups the implementation object is currently configured to discover.
+
+If the managed set of groups is empty, this method will return an empty array. If there is no managed set of groups, then null (`ALL_GROUPS`) is returned, indicating that any lookup service within range--even those that have no group affiliation--are to be discovered.
+
+If an empty array is returned, that array is guaranteed to be referentially equal to the `NO_GROUPS` constant; that is, the array returned from that method and the `NO_GROUPS` constant can be tested for equality using the `==` operator.
+
+This method takes no arguments as input and, provided the managed set of groups currently exists, will return a new array upon each invocation.
+
+The `addGroups` method adds a set of group names to the managed set. The array input to this method contains the group names to be added to the set.
+
+This method throws `IOException` because an invocation of this method may result in the re-initiation of the discovery process, which can throw `IOException` when socket allocation occurs.
+
+This method throws an `UnsupportedOperationException` if there is no managed set of groups to augment, and it throws a `NullPointerException` if `null` (`ALL_GROUPS`) is input. If an empty array (`NO_GROUPS`) is input, the managed set of groups will not change.
+
+The `setGroups` method replaces all of the group names in the managed set with names from a new set. The array input to this method contains the group names with which to replace the current names in the managed set.
+
+Once a new group name has been placed in the managed set, no event will be sent to the entity's listener for the lookup services belonging to that group that have already been discovered, although attempts to discover all (as yet) undiscovered lookup services belonging to that group will continue to be made.
+
+If `null` (`ALL_GROUPS`) is input to `setGroups`, then attempts will be made to discover all (as yet) undiscovered lookup services located within the _multicast radius (_DU.3, "LookupDiscovery Utility")_ of the implementation object, regardless of group membership.
+
+If an empty array (`NO_GROUPS`) is input to `setGroups`, then group discovery will be halted until the managed set of groups is changed--through a subsequent call to this method or to `addGroups`--to a set that is either a non-empty set of group names or `null` (`ALL_GROUPS`).
+
+This method throws `IOException`. This is because an invocation of this method may result in the re-initiation of the discovery process, a process that can throw `IOException` when socket allocation occurs.
+
+The `removeGroups` method deletes a set of group names from the managed set of groups. The array input to this method contains the group names to be removed from the managed set.
+
+This method throws an `UnsupportedOperationException` if there is no managed set of groups from which to remove elements. If `null` (`ALL_GROUPS`) is input to `removeGroups`, a `NullPointerException` will be thrown. 
+
+If any element of the set of groups to be removed is not contained in the managed set, `removeGroups` takes no action with respect to that element. If an empty array (`NO_GROUPS`) is input, the managed set of groups will not change.
+
+Once a new group name is added to the managed set as a result of an invocation of either `addGroups` or `setGroups`, attempts will be made--using the multicast request protocol--to discover all (as yet) undiscovered lookup services that are members of that group. If there are no responses to the multicast requests, the implementation object will stop sending multicast requests, and will simply listen for multicast announcements containing the new groups of interest.
+
+Any already discovered lookup service that is a member of one or more of the groups removed from the managed set as a result of an invocation of either `setGroups` or `removeGroups` will be discarded and will no longer be eligible for discovery, but only if that lookup service satisfies both of the following conditions:
+
+  - the lookup service is not a member of any group in the new managed set that resulted from the invocation of `setGroups` or `removeGroups`, and
+  - the lookup service is not currently eligible for discovery through other means (such as locator discovery).
+
+###DU.2.5	 The `DiscoveryLocatorManagement` Interface
+
+The public methods specified by the `DiscoveryLocatorManagement` interface are as follows:
+
+    package net.jini.discovery;
+    
+    public interface DiscoveryLocatorManagement {
+        public LookupLocator[] getLocators();
+        public void addLocators(LookupLocator[] locators);
+        public void setLocators(LookupLocator[] locators);
+        public void removeLocators(LookupLocator[] locators);
+    }
+
+####DU.2.5.1	 The Semantics
+
+The `DiscoveryLocatorManagement` interface defines methods related to the management of the set of `LookupLocator` objects corresponding to the specific lookup services that are to be discovered using the unicast discovery protocol; that is, lookup services that are discovered by way of locator discovery. The methods of this interface define how an entity retrieves or modifies the managed set of locators to discover. Phrases such as "the locators to discover" and "discovering the desired locators" refer to the discovery of the lookup services that are associated with those locators.
+
+The methods that modify the managed set of locators each take a single input parameter: an array of `LookupLocator` objects, none of whose elements may be `null`. Each of these methods throws a `NullPointerException` when at least one element of the input array is `null`.
+
+Invoking any of these methods with an input array that contains duplicate locators (as determined by `LookupLocator.equals`) is equivalent to performing the invocation with the duplicates removed from the array.
+
+The `getLocators` method returns an array containing the set of `LookupLocator` objects in the managed set of locators; that is, the locators of the specific lookup services that the implementation object is currently interested in discovering.
+
+The returned set includes both the set of locators corresponding to lookup services that have already been discovered and the set of those that have not yet been discovered.
+
+If the managed set is empty, this method returns an empty array. This method takes no arguments as input, and returns a new array upon each invocation.
+
+The `addLocators` method adds a set of locators to the managed set. The array input to this method contains the set of `LookupLocator` objects to add to the managed set.
+
+If `null` is input to `addLocators`, a `NullPointerException` will be thrown. If an empty array is input, the managed set of locators will not change.
+
+The `setLocators` method replaces all of the locators in the managed set with `LookupLocator` objects from a new set. The array input to this method contains the set of `LookupLocator` objects with which to replace the current locators in the managed set.
+
+If `null` is input to `setLocators`, a `NullPointerException` will be thrown.
+
+If an empty array is input to `setLocators`, then locator discovery will be halted until the managed set of locators is changed--through a subsequent call to this method or to `addLocators`--to a set that is non-null and non-empty.
+
+The `removeLocators` method deletes a set of locators from the managed set. The array input to this method contains the set of `LookupLocator` objects to remove from the managed set.
+
+If `null` is input to `removeLocators`, a `NullPointerException` will be thrown. 
+
+If any element of the set of locators to remove is not contained in the managed set, `removeLocators` takes no action with respect to that element. If an empty array is input, the managed set of locators will not change.
+
+Any already discovered lookup service, corresponding to a locator that is a member of the set of locators removed from the managed set as a result of an invocation of either `setLocators` or `removeLocators`, will be discarded and will no longer be eligible for discovery, but only if it is not currently eligible for discovery through other means (such as group discovery).
+
+###DU.2.6	 Supporting Interfaces and Classes
+
+Discovery management depends on the interfaces `DiscoveryListener` and `DiscoveryChangeListener`, and on the concrete class `DiscoveryEvent`.
+
+####DU.2.6.1	 The `DiscoveryListener` Interface
+
+The public methods specified by the `DiscoveryListener` interface are as follows:
+
+    package net.jini.discovery;
+    
+    public interface DiscoveryListener extends EventListener {
+        public void discovered(DiscoveryEvent e);
+        public void discarded(DiscoveryEvent e);
+    }
+
+When an entity employs an object that implements one or more of the discovery management interfaces to perform and manage the entity's discovery duties, the entity often will want that object--generally referred to as a _discovery utility--_to notify the entity when a desired lookup service is either discovered or discarded. The `DiscoveryListener` interface defines a mechanism through which an entity may receive such notifications from a discovery utility. When an entity registers interest in these notifications, an implementation of this interface must be provided to the discovery utility being employed. Through this registered listener, the entity may then receive instances of the `DiscoveryEvent` class, which encapsulate the required information associated with the desired notifications.
+
+#####The Semantics
+
+The events received by listeners implementing the `DiscoveryListener` interface can be the result of either group discovery or locator discovery. These events contain the discovered or discarded registrars, as well as the set of member groups corresponding to each registrar (see the specification of the `DiscoveryEvent` class).
+
+The `discovered` method is called whenever a new lookup service is discovered or a discarded lookup service is re-discovered.
+
+The `discarded` method is called whenever a previously discovered lookup service is discarded because the lookup service was determined to be either unreachable or no longer interesting to the entity, and the discard process was initiated by either the entity itself (an _active_ discard) or the discovery utility employed by the entity (a _passive_ discard).
 
-  <li class="SmartList1"><a name="1024385"> </a>A <code>Map</code> instance in which each element of the map's key set is a <code>ServiceRegistrar</code> instance that references one of the lookup services to be associated with the event being constructed. Each element of the map's value set is a <code>String</code> array, containing the names of the groups in which the corresponding lookup service is a member.<p>
-  <li class="SmartList1"><a name="1024277"> </a>An array of <code>ServiceRegistrar</code> instances in which each element references one of the lookup services to be associated with the event being constructed.<p>
+The `DiscoveryGroupManagement` interface makes the following concurrency guarantee: for any given listener object that implements this interface or any sub-interface, no two methods defined by the interface or sub-interface will be invoked at the same time. This applies to different invocations of the same or different methods, on the same or different listeners registered with a single `DiscoveryManagement` instance. For example, the `discovered` method of one listener will not be invoked while the invocation of another listener's `discovered` or `discarded` method is in progress. Similarly, the one listener's `discovered` method will not be invoked while that same listener's `discard` method is in progress.
+
+####DU.2.6.2	 The `DiscoveryChangeListener` Interface
+
+The `DiscoveryChangeListener` interface specifies only one public method:
+
+    package net.jini.discovery;
+    
+    public interface DiscoveryChangeListener
+                     extends DiscoveryListener
+    {
+        public void changed(DiscoveryEvent e);
+    }
+
+In addition to being notified when a desired lookup service is discovered or discarded, some entities may also wish to be notified when a lookup service experiences changes in its group membership. The `DiscoveryChangeListener` interface defines an extension to the `DiscoveryListener` interface, providing a mechanism through which an entity may receive these additional notifications--referred to as _changed_ _events_. As with the `DiscoveryListener` interface, when an entity wishes to receive changed events in addition to discovered and discarded events, an implementation of this interface must be provided to the discovery utility being employed. It is through that registered listener that the entity receives the desired notifications encapsulated in instances of the `DiscoveryEvent` class.
+
+#####The Semantics<br>
+
+When the entity receives a `DiscoveryEvent` object through an instance of the `DiscoveryChangeListener` interface, the event contains the discovered, discarded, or changed registrars, as well as the set of member groups corresponding to each registrar. In the case of a changed event, each set of groups referenced in the event contains the new groups in which the corresponding registrar is a member.
+
+The `changed` method is called whenever the discovery utility encounters changes in the set of groups in which a previously discovered lookup service is a member.
+
+It is important to note that instances of this interface are eligible to receive changed events for only those lookup services that the entity has requested be discovered by (at least) group discovery. That is, if the entity requests that _only_ locator discovery be used to discover a specific lookup service, the listener will receive no changed events for that lookup service. This is because the semantics of this interface assume that since the entity expressed no interest in _discovering_ the lookup service through its group membership, it must also have no interest in any _changes_ in that lookup service's group membership. Thus, if an entity wishes to receive changed events for one or more lookup services, the entity must request that those lookup services be discovered by either group discovery alone, or by both group and locator discovery.
+
+####DU.2.6.3	 The `DiscoveryEvent` Class
+
+The public methods provided by the `DiscoveryEvent` class are as follows:
+
+    package net.jini.discovery;
+    
+    public class DiscoveryEvent extends EventObject {
+        public DiscoveryEvent(Object source, Map groups) {...}
+        public DiscoveryEvent(Object source, 
+                              ServiceRegistrar[] regs) {...}
+        public Map getGroups() {...}
+        public ServiceRegistrar[] getRegistrars() {...}
+    }
+
+The `DiscoveryEvent` class provides an encapsulation of event information that discovery utilities can use to notify an entity of the occurrence of an event involving one or more `ServiceRegistrar` objects (lookup services) in which the entity has registered interest. Discovery utilities pass an instance of this class to the entity's discovery listener(s) when one of the following events occurs:
+
+  - Each lookup service referenced in the event has been discovered for the first time, or re-discovered after having been discarded.
+  - Each lookup service referenced in the event has been either actively or passively discarded.
+  - For each lookup service referenced in the event, the set of groups in which the lookup service is a member has changed.
+
+The `DiscoveryEvent` class is a subclass of `EventObject`, adding the following additional items of abstract state: a set of `ServiceRegistrar` instances (_registrars_) referencing the affected lookup services, and a mapping from each of those registrars to their current set of member groups. Methods are defined through which this additional state may be retrieved upon receipt of an instance of this class.
+
+#####The Semantics<br>
+
+The `equals` method for this class returns `true` if and only if two instances of this class refer to the same object. That is, `x` and `y` are equal instances of this class if and only if `x` `==` `y` has the value `true`.
+
+The constructor for this class has two forms, where both forms expect two input parameters. Each form of the constructor takes, as its first input parameter, a reference to the source of the event; that is, the discovery utility object that created the event instance and sent it to the entity's listener(s) through the invocation of the `discovered`, `discarded`, or `changed` method on each listener. Note that neither form of the constructor makes a copy of the second parameter. That is, the reference input to the second parameter is shared with the invoking entity.
+
+Depending on the constructor employed, the second parameter is one of the following:
+
+  - A `Map` instance in which each element of the map's key set is a `ServiceRegistrar` instance that references one of the lookup services to be associated with the event being constructed. Each element of the map's value set is a `String` array, containing the names of the groups in which the corresponding lookup service is a member.
+  - An array of `ServiceRegistrar` instances in which each element references one of the lookup services to be associated with the event being constructed.
   
-It is important to note that when this form of the constructor is used to construct a <code>DiscoveryEvent</code>, although the resulting event contains a <code>non-null</code> registrars array, the registrars-to-groups map is <code>null</code>. Therefore, discovery utilities should no longer use this constructor to instantiate the events they send.
-</ul>
+It is important to note that when this form of the constructor is used to construct a `DiscoveryEvent`, although the resulting event contains a `non-null` registrars array, the registrars-to-groups map is `null`. Therefore, discovery utilities should no longer use this constructor to instantiate the events they send.
+
+The `getGroups` method returns the mapping from each registrar referenced by the event to the registrar's current set of member groups. If the event was instantiated using the constructor whose second parameter is an array of `ServiceRegistrar` instances, this method will return `null`.
+
+The returned map's key set is made up of `ServiceRegistrar` instances corresponding to the lookup services for which the event was constructed and sent. Each element of the returned map's value set is a `String` array, containing the names of the member groups of the corresponding lookup service.
+
+On each invocation of this method, the same `Map` object is returned; that is, a copy is not made.
+
+The `getRegistrars` method returns an array of `ServiceRegistrar` instances, in which each element references one of the lookup services for which the event was constructed and sent.
+
+
+
+###DU.2.7	 Serialized Forms
+|Class|`serialVersionUID`|Serialized Fields|
+|`DiscoveryEvent`|5280303374696501479L|`ServiceRegistrar[] regs`   `Map groups`|
+
+##DU.3	 `LookupDiscovery` Utility
+
+###DU.3.1	 Overview
+
+In a Jini application environment the multicast discovery protocols are often collectively referred to as multicast discovery or group discovery. The entities that participate in the multicast discovery protocol are a _discovering entity_ (Jini client or service) and a Jini lookup service, which acts as the entity that is to be discovered. When the discovering entity starts, it uses the multicast request protocol to announce its interest in finding lookup services within range. After a specified amount of time, the entity stops sending multicast requests, and simply listens for multicast announcements from any lookup services within range that may be broadcasting their availability. Through either of these protocols, the discovering entity can obtain references to lookup services belonging to member group in which the entity is interested. For the details of the multicast discovery protocols, refer to the _Jini Discovery and Join Specification_.
+
+The `LookupDiscovery` helper utility in the package `net.jini.discovery` encapsulates the functionality required of an entity that wishes to employ multicast discovery to discover a lookup service located within the entity's _multicast radius_ (roughly, the number of hops beyond which neither the multicast requests from the entity, nor the multicast announcements from the lookup service, will propagate). This utility provides an implementation that makes the process of acquiring lookup service instances, based on no information other than group membership, much simpler for both services and clients.
+
+###DU.3.2	 Other Types
+
+The types defined in the specification of the `LookupDiscovery` utility class are in the `net.jini.discovery` package. The following additional types may also be referenced in this specification. Whenever referenced, these object types will be referenced in unqualified form:
+
+    net.jini.core.discovery.LookupLocator
+    net.jini.config.Configuration
+    net.jini.config.ConfigurationException
+    net.jini.discovery.DiscoveryManagement
+    net.jini.discovery.DiscoveryGroupManagement
+    net.jini.discovery.DiscoveryPermission
+    java.io.IOException
+    java.io.Serializable
+    java.security.Permission
+    
+###DU.3.3	 The Interface
+
+The public methods provided by the `LookupDiscovery` class are as follows:
+
+    package net.jini.discovery;
+    
+    public class LookupDiscovery 
+                            implements DiscoveryManagement,
+                                       DiscoveryGroupManagement
+    {
+        public static final String[] ALL_GROUPS 
+                          = DiscoveryGroupManagement.ALL_GROUPS;
+        public static final String[] NO_GROUPS 
+                          = DiscoveryGroupManagement.NO_GROUPS;
+    
+        public LookupDiscovery(String[] groups)
+                                          throws IOException {...}
+        public LookupDiscovery(String[] groups,
+                               ConFiguration config)
+                  throws IOException, ConfigurationException {...}
+    
+    }
+
+###DU.3.4	 The Semantics
+
+The only new public method of the `LookupDiscovery` helper utility class is the constructor. All other public methods implemented by this class are specified in the `DiscoveryManagement` and the `DiscoveryGroupManagement` interfaces.
+
+Each instance of the `LookupDiscovery` class must behave as if it operates independently of all other instances.
+
+The `equals` method for this class returns `true` if and only if two instances of this class refer to the same object. That is, `x` and `y` are equal instances of this class if and only if `x` `==` `y` has the value `true`.
+
+For convenience, this class defines the constants `ALL_GROUPS` and `NO_GROUPS`, which represent no set and the empty set respectively. For more information on these constants, refer to the specification of the `DiscoveryGroupManagement` interface.
+
+The constructor for the `LookupDiscovery` class has two versions. Each version of the constructor throws `IOException` because construction of a `LookupDiscovery` object can cause the initiation of the multicast discovery process, a process that can throw `IOException`.
+The only difference between the two versions of the constructor is the absence or presence of a parameter of type `Configuration`, which is used to classify the constructors as either _non-configurable_ or _configurable_, respectively.
+
+Constructing this class using an input array that contains duplicate group names is equivalent to constructing the class using an array with the duplicates removed.
+
+If `null` (`ALL_GROUPS`) is input to the constructor, then attempts will be made to discover all lookup services located within the current multicast radius, regardless of group membership.
+
+Although discovery events will not be sent by this class until a listener is added through an invocation of the `addListener` method, discovery processing usually starts as soon as an instance of this class is constructed. However, if an empty array (`NO_GROUPS`) is passed to the constructor, discovery will not be started until the `addGroups` or `setGroups` method is called to change the initial empty set of groups to either a non-empty set, or `null` (`ALL_GROUPS`).
+
+As noted, the configurable version of the constructor is characterized by an additional parameter of type `Configuration`. Through that parameter, the configurable version of the constructor can be used to customize the behavior of the resulting `LookupDiscovery` instance. Such customizations are implementation dependent. A `NullPointerException` is thrown if `null` is passed as the value of that parameter. A `ConfigurationException` is thrown to indicate that a problem occurred while attempting to retrieve an item from the given `Configuration`.
+
+Creating a `LookupDiscovery` object using the non-configurable version of the constructor will result in an instance of `LookupDiscovery` having only basic, default behavior. Thus, the use of the configurable version of the constructor is strongly encouraged.
+
+###DU.3.5	 Supporting Interfaces and Classes
+
+The `LookupDiscovery` helper utility class depends on the interfaces `DiscoveryManagement` and `DiscoveryGroupManagement`, and on the concrete class `DiscoveryPermission`.
+
+####DU.3.5.1	 The `DiscoveryManagement` Interfaces
+
+The `LookupDiscovery` class implements both the `DiscoveryManagement` and the `DiscoveryGroupManagement` interfaces, which together define methods related to the coordination and management of all group discovery processing. See DU.2 "The Discovery Management Interfaces" for more information on those interfaces.
+
+####DU.3.5.2	 Security and Multicast Discovery: The `DiscoveryPermission` Class
+
+When an instance of the `LookupDiscovery` class is constructed, the entity that creates the instance must be granted appropriate discovery permission. For example, if the instance of `LookupDiscovery` is currently configured to discover a non-empty, non-`null` set of groups, then the entity that created the instance must have permission to attempt discovery of each of the groups in that set. If the set of groups to discover is `null` (`ALL_GROUPS`), then the entity must have permission to attempt discovery of all possible groups. If appropriate permissions are not granted, the constructor of `LookupDiscovery`, as well as the methods `addGroups` and `setGroups`, will throw a `java.lang.SecurityException`.
+
+Discovery permissions are controlled in security policy files using the permission class `DiscoveryPermission`. The public methods provided by the `DiscoveryPermission` class are as follows:
+
+    package net.jini.discovery;
+    
+    public final class DiscoveryPermission extends Permission
+                                           implements Serializable
+    {
+        public DiscoveryPermission(String group) {...}
+        public DiscoveryPermission(String group, 
+                                   String actions) {...}
+    }
+
+The `DiscoveryPermission` class is a subclass of `Permission`, adding no additional items of abstract state.
+
+#####The Semantics<br>
+
+The `equals` method for this class returns `true` if and only if two instances of this class have the same group name.
+
+The constructor for this class has two forms: one form expecting one input parameter, the other form expecting two input parameters. Each form of the constructor takes, as its first input parameter, a `String` representing one or more group names for which to allow discovery.
+
+The second parameter of the second form of the constructor is a `String` value that is currently ignored because there are no actions associated with a discovery permission.
+
+######`DiscoveryPermission` Examples<br>
+
+A number of examples that illustrate the use of this permission are presented. Note that each example represents a line in a policy file.
+
+    `permission net.jini.discovery.DiscoveryPermission "*";`<br>
+Grant the entity permission to attempt discovery of all possible groups
+
+    `permission net.jini.discovery.DiscoveryPermission "";`<br>
+Grant the entity permission to attempt discovery of only the "public" group
+
+    `permission net.jini.discovery.DiscoveryPermission "foo";`<br>
+Grant the entity permission to attempt discovery of the group named "foo"
+
+    `permission net.jini.discovery.DiscoveryPermission "*.sun.com";`<br>
+Grant the entity permission to attempt discovery of all groups whose names end with the substring ".sun.com"
+
+Each of the above declarations grants permission to attempt discovery of one name. A name does not necessarily correspond to a single group. That is, the following should be noted:
+
+  - The name `"*"` grants permission to attempt discovery of _all_ possible groups.
+  - A name beginning with `"*."` grants permission to attempt discovery of all groups that match the _remainder_ of that name; for example, the name `"*.example.org"` would match a group named `"foonly.example.org"` and also a group named `"sf.ca.example.org"`.
+  - The empty name `""` denotes the _public_ group.
+  - All other names are treated as individual groups and must match exactly.
+
+Finally, it is important to note that a restriction of the Java2 platform security model requires that appropriate `DiscoveryPermission` be granted to the Jini technology infrastructure software codebase itself, in addition to any codebases that may use Jini technology infrastructure software classes.
+
+###DU.3.6	 Serialized Forms
+|Class|`serialVersionUID`|Serialized Fields|
+|`DiscoveryPermission`|-3036978025008149170L|_none_|
+
+##DU.4	 The `LookupLocatorDiscovery` Utility
+
+###DU.4.1	 Overview
+
+The _Jini Discovery and Join Specification_, states that the "unicast discovery protocol is a simple request-response protocol." In a Jini application environment, the entities that participate in this protocol are a discovering entity (Jini client or service) and a Jini lookup service that acts as the entity to be discovered. The discovering entity sends unicast discovery requests to the lookup service, and the lookup service reacts to those requests by sending unicast discovery responses to the interested discovering entity.
+
+The `LookupLocatorDiscovery` helper utility (belonging to the package `net.jini.discovery`) encapsulates the functionality required of an entity that wishes to employ the unicast discovery protocol to discover a lookup service. This utility provides an implementation that makes the process of finding specific instances of a lookup service much simpler for both services and clients.
+

[... 1869 lines stripped ...]