Provides implementations of {@link net.jini.core.lookup.ServiceRegistrar}. Two implementations are available for use with the {@link org.apache.river.start} package:

- `org.apache.river.reggie.PersistentRegistrarImpl` - a persistent implementation which can be run either as activatable or non-activatable, suitable for use with {@link org.apache.river.start.SharedActivatableServiceDescriptor} or {@link org.apache.river.start.NonActivatableServiceDescriptor}
- `org.apache.river.reggie.TransientRegistrarImpl` - a non-activatable transient implementation, suitable for use with {@link org.apache.river.start.NonActivatableServiceDescriptor}

The name "Reggie" loosely refers to either implementation. The JAR file `reggie.jar`, included in the `lib` subdirectory of the Apache River release installation, contains the classes for both Reggie service implementations. The `reggie-dl.jar` and `jsk-dl.jar` files in the `lib-dl` subdirectory contain the classes needed in the codebase for its downloaded proxies. None of the JAR files include classes from `jsk-platform.jar`, which are included by the service starter's `start.jar` JAR file, and need to be included in the codebase of clients.

The main proxy of an instance of either of the implementations above implements the `ServiceRegistrar`, {@link net.jini.admin.Administrable} and {@link net.jini.id.ReferentUuid} interfaces. The admin proxy, obtainable by calling the {@link net.jini.admin.Administrable#getAdmin getAdmin} method of the main proxy, implements the {@link net.jini.lookup.DiscoveryAdmin}, {@link net.jini.admin.JoinAdmin}, {@link org.apache.river.admin.DestroyAdmin} and `ReferentUuid` interfaces.

This document provides the following information about Reggie:

- Configuring Reggie
- Access Control Permission Targets
- Loggers and Logging Levels
- System Properties
- Examples for Running Reggie

## Configuring Reggie

Both `TransientRegistrarImpl` and `PersistentRegistrarImpl` service implementations obtain their configurations by calling {@link net.jini.config.ConfigurationProvider#getInstance(String[],ClassLoader) ConfigurationProvider.getInstance} with the specified configOptions and the class loader for the implementation class.

The configuration entries supported by the two implementations are listed below. `PersistentRegistrarImpl` supports all of the listed entries. `TransientRegistrarImpl` supports all listed entries except for the following persistence/activation-specific entries:

- `activationIdPreparer`
- `activationSystemPreparer`
- `persistenceDirectory`
- `persistenceSnapshotThreshold`
- `persistenceSnapshotWeight`
- `recoveredListenerPreparer`
- `recoveredLocatorPreparer`

All configuration entries listed below have `org.apache.river.reggie` as their component.

• | `activationIdPreparer`
--- | ---
| Type: | {@link net.jini.security.ProxyPreparer}
| Default: | `new {@link net.jini.security.BasicProxyPreparer}()`
| Description: | Specifies the proxy preparer to use for the {@link java.rmi.activation.ActivationID} for this service, if this service is run as activatable. This service does not invoke any methods on the prepared `ActivationID` directly; however, it passes it to clients which may call its {@link java.rmi.activation.ActivationID#activate activate} method if they need to reactivate this service. This entry is obtained at service start and restart if the service is running as activatable, and is only supported by `PersistentRegistrarImpl`.

• | `activationSystemPreparer`
--- | ---
| Type: | {@link net.jini.security.ProxyPreparer}
| Default: | `new {@link net.jini.security.BasicProxyPreparer}()`
| Description: | Specifies the proxy preparer to use for the {@link java.rmi.activation.ActivationSystem} proxy. During shutdown, this service calls the {@link java.rmi.activation.ActivationSystem#unregisterObject unregisterObject} method on the `ActivationSystem` instance returned from this preparer. This entry is obtained at service start and restart if the service is running as activatable, and is only supported by `PersistentRegistrarImpl`.

• | `discoveryConstraints`
--- | ---
| Type: | {@link net.jini.core.constraint.MethodConstraints}
| Default: | `null`
| Description: | Specifies constraints to apply to the multicast request, multicast announcement and unicast discovery protocols. Multicast request constraints are derived by calling {@link net.jini.core.constraint.MethodConstraints#getConstraints getConstraints} on the obtained `MethodConstraints` instance with a `Method` object for the {@link org.apache.river.discovery.DiscoveryConstraints#multicastRequest} method; multicast announcement and unicast discovery constraints are similarly obtained by passing `Method` objects for the {@link org.apache.river.discovery.DiscoveryConstraints#multicastAnnouncement} and {@link org.apache.river.discovery.DiscoveryConstraints#unicastDiscovery} methods, respectively. A `null` value is interpreted as mapping all methods to empty constraints. Reggie supports use of the following constraint types to control discovery behavior: {@link org.apache.river.discovery.DiscoveryProtocolVersion}: this constraint can be used to control which version(s) of the multicast request, multicast announcement, and unicast discovery protocols are used. Reggie defaults to using version one of the discovery protocols if this constraint is not specified and no other constraints, besides the ones listed here, are specified. {@link org.apache.river.discovery.MulticastMaxPacketSize}: this constraint can be used to control the maximum size of multicast announcement packets to send; it can also be used to specify the size of the buffer used to receive incoming multicast request packets. Reggie defaults to `512` bytes as the maximum size for announcements sent if this constraint is not specified for the {@link org.apache.river.discovery.DiscoveryConstraints#multicastAnnouncement} method. Reggie defaults to `512` bytes as the size of the buffer used to receive incoming multicast request packets if this constraint is not specified for the {@link org.apache.river.discovery.DiscoveryConstraints#multicastRequest} method. {@link org.apache.river.discovery.MulticastTimeToLive}: this constraint can be used to control the time to live (TTL) value set on outgoing multicast request packets. Reggie defaults to sending multicast announcements with a TTL of `15` if this constraint is not specified for the {@link org.apache.river.discovery.DiscoveryConstraints#multicastAnnouncement} method. {@link org.apache.river.discovery.UnicastSocketTimeout}: this constraint can be used to control the read timeout set on sockets over which unicast discovery is performed. In other words, it controls the amount of time Reggie waits to read data from a connected client attempting to discover Reggie. Reggie defaults to one minute as the read timeout on sockets over which unicast discovery is performed if this constraint is not specified for the {@link org.apache.river.discovery.DiscoveryConstraints#unicastDiscovery} method. {@link net.jini.core.constraint.ConnectionRelativeTime}: this constraint can be used to control the connection timeout set on sockets over which unicast discovery is performed. In other words, it controls the amount of time Reggie waits to connect to a client attempting to discover Reggie. If this constraint is not specified for the {@link org.apache.river.discovery.DiscoveryConstraints#unicastDiscovery} method, the connection attempt will block until the connection is established or an error occurs. {@link net.jini.core.constraint.ConnectionAbsoluteTime}: This constraint can be used to set a time after which reggie will cease to respond to discovery requests. By default, Reggie has no limitation on how long to continue responding to discovery requests. Constraints other than those listed above are passed on to the underlying implementations of versions 1 and 2 of the discovery protocols. This entry is obtained at service start and restart.

• | `discoveryManager`
--- | ---
| Type: | {@link net.jini.discovery.DiscoveryManagement}
| Default: |
    new {@link net.jini.discovery.LookupDiscoveryManager}(
        {@link net.jini.discovery.DiscoveryGroupManagement#NO_GROUPS},
        null, // locators
        null, // listener
        this) // config
| Description: | Specifies `DiscoveryManagement` instance to use to discover other lookup services with which this service should register. The object returned must also implement {@link net.jini.discovery.DiscoveryGroupManagement} and {@link net.jini.discovery.DiscoveryLocatorManagement}, and should be configured initially to discover no groups or specific lookup services. This entry is obtained at service start and restart.

• | `initialLookupAttributes`
--- | ---
| Type: | `{@link net.jini.core.entry.Entry}[]`
| Default: | `new Entry[0]`
| Description: | Specifies initial attributes to use when registering with lookup services (including self). The `null` value is equivalent to an empty `Entry` array. This service implementation provides two additional hardcoded attributes--a {@link net.jini.lookup.entry.ServiceInfo} instance with `name` field set to the string `"Lookup"`, and a {@link org.apache.river.lookup.entry.BasicServiceType} instance with `type` field also set to `"Lookup"`--which are combined with the entry-specified attributes to obtain the total set of initial attributes with which to register. This entry is obtained once at service start; the current set of attributes (modifiable via the {@link net.jini.admin.JoinAdmin} methods of Reggie's admin object) is persisted across restarts.

• | `initialLookupGroups`
--- | ---
| Type: | `String[]`
| Default: | {@link net.jini.discovery.DiscoveryGroupManagement#NO_GROUPS}
| Description: | Specifies initial groups for determining the set of lookup services with which to register. This entry is obtained once at service start; the current set of lookup groups (modifiable via the {@link net.jini.admin.JoinAdmin} methods of Reggie's admin object) is persisted across restarts.

• | `initialLookupLocators`
--- | ---
| Type: | `{@link net.jini.core.discovery.LookupLocator}[]`
| Default: | `new LookupLocator[0]`
| Description: | Specifies initial list of locators indicating other lookup services with which to register. This entry is obtained once at service start; the current set of lookup locators (modifiable via the {@link net.jini.admin.JoinAdmin} methods of Reggie's admin object) is persisted across restarts.

• | `initialMemberGroups`
--- | ---
| Type: | `String[]`
| Default: | `new String[]{ "" }`
| Description: | Specifies initial groups for this lookup service to be a member of. The value should not be `null` (which is equal to {@link net.jini.discovery.DiscoveryGroupManagement#ALL_GROUPS}). This entry is obtained once at service start; the current set of member groups (modifiable via the {@link net.jini.lookup.DiscoveryAdmin} methods of Reggie's admin object) is persisted across restarts.

• | `initialUnicastDiscoveryPort`
--- | ---
| Type: | `int`
| Default: | `0`
| Description: | Specifies the initial number of the port on which to listen for unicast discovery queries. If the port number is `0`, then an arbitrary port is selected (with preference given to {@link net.jini.discovery.Constants#discoveryPort}, if available). This entry is obtained once at service start; the current value (modifiable via the {@link net.jini.lookup.DiscoveryAdmin} methods of Reggie's admin object) is persisted across restarts.

• | `listenerPreparer`
--- | ---
| Type: | {@link net.jini.security.ProxyPreparer}
| Default: | `new {@link net.jini.security.BasicProxyPreparer}()`
| Description: | Specifies the proxy preparer to use for {@link net.jini.core.event.RemoteEventListener}s registered with this service in calls to {@link net.jini.core.lookup.ServiceRegistrar#notify}. During event notification, this service calls the {@link net.jini.core.event.RemoteEventListener#notify notify} method on `RemoteEventListener` instances returned from this preparer. This entry is obtained at service start and restart.

• | `locatorPreparer`
--- | ---
| Type: | {@link net.jini.security.ProxyPreparer}
| Default: | `new {@link net.jini.security.BasicProxyPreparer}()`
| Description: | Specifies the proxy preparer to use for {@link net.jini.core.discovery.LookupLocator}s passed to this service in calls to the {@link net.jini.admin.JoinAdmin#addLookupLocators addLookupLocators}, {@link net.jini.admin.JoinAdmin#setLookupLocators setLookupLocators} and {@link net.jini.admin.JoinAdmin#removeLookupLocators removeLookupLocators} methods of its admin object. When registering with other lookup services, this service may call or use the constraints assigned to the `getRegistrar` methods of `LookupLocator` instances returned from this preparer. This entry is obtained at service start and restart.

• | `loginContext`
--- | ---
| Type: | {@link javax.security.auth.login.LoginContext}
| Default: | Do not perform JAAS login
| Description: | Specifies the JAAS login context to use for performing a JAAS login and supplying the {@link javax.security.auth.Subject} to use when running the service. If this entry is not specified or if it is specified with a value of `null`, no JAAS login is performed. This entry is obtained at service start and restart.

• | `minMaxEventLease`
--- | ---
| Type: | `long`
| Default: | `1000 * 60 * 30L`
| Description: | Specifies the lower bound for the maximum value allowed for event leases, in milliseconds. The maximum event lease granted is never less than the specified value, but may be greater than it if the expected average time between lease renewals (based on the current number of service and event registrations) would be less than the value of the `minRenewalInterval` configuration entry. This entry replaces in function the `setMinMaxEventLease` method of the `RegistrarAdmin` interface supported by previous implementations of Reggie, and is obtained at service start and restart.

• | `minMaxServiceLease`
--- | ---
| Type: | `long`
| Default: | `1000 * 60 * 5L`
| Description: | Specifies the lower bound for the maximum value allowed for service leases, in milliseconds. The maximum service lease granted is never less than the specified value, but may be greater than it if the expected average time between lease renewals (based on the current number of service and event registrations) would be less than the value of the `minRenewalInterval` configuration entry. This entry replaces in function the `setMinMaxServiceLease` method of the `RegistrarAdmin` interface supported by previous implementations of Reggie, and is obtained at service start and restart.

• | `minRenewalInterval`
--- | ---
| Type: | `long`
| Default: | `100L`
| Description: | Specifies the minimum average time to maintain between lease renewals, in milliseconds. This entry replaces in function the `setMinRenewalInterval` method of the `RegistrarAdmin` interface supported by previous implementations of Reggie, and is obtained at service start and restart.

• | `multicastAnnouncementInterval`
--- | ---
| Type: | `long`
| Default: | `1000 * 60 * 2L`
| Description: | Specifies the number of milliseconds to wait in between sending multicast announcement packets. This entry is consulted instead of the `net.jini.discovery.announce` system property used by previous implementations of Reggie. This entry is obtained at service start and restart.

• | `multicastInterfaceRetryInterval`
--- | ---
| Type: | `int`
| Default: | `1000 * 60 * 5`
| Description: | Specifies the number of milliseconds to wait in between retrying multicast interfaces for which initial attempts at enablement failed. Failed interfaces are retried at the given interval until they are successfully enabled; the overall set of multicast interfaces to use is configurable via the `multicastInterfaces` configuration entry. This entry is obtained at service start and restart.

• | `multicastInterfaces`
--- | ---
| Type: | `{@link java.net.NetworkInterface}[]`
| Default: | Use all network interfaces
| Description: | Specifies the network interfaces to use to send and receive multicast request and announcement packets as part of multicast discovery. If no value is specified for this entry, then all network interfaces of the host are used. If the entry value is `null`, then the interface to which the operating system defaults is used. If the entry value is a zero-length array, then multicast discovery is disabled. This entry is consulted instead of the `net.jini.discovery.interface` system property used by previous implementations of Reggie, and is obtained at service start and restart.

• | `multicastRequestSubjectChecker`
--- | ---
| Type: | {@link org.apache.river.discovery.ClientSubjectChecker}
| Default: | Do not check {@link javax.security.auth.Subject}s of multicast requests
| Description: | Specifies the object to use for screening multicast requests based on their authenticated `Subject`s. This entry is obtained at service start and restart.

• | `persistenceDirectory`
--- | ---
| Type: | `String`
| Default: | Required: no default
| Description: | Specifies the directory where the service's persistent state is recorded. This entry is obtained at service start and restart, and is only supported by `PersistentRegistrarImpl`, which requires it to be set.

• | `persistenceSnapshotThreshold`
--- | ---
| Type: | `int`
| Default: | `200`
| Description: | Specifies the minimum number of log updates before a new snapshot can be taken. This entry replaces the `setLogToSnapshotThreshold` method of the `RegistrarAdmin` interface supported by previous implementations of Reggie. It is obtained at service start and restart, and is only supported by `PersistentRegistrarImpl`.

• | `persistenceSnapshotWeight`
--- | ---
| Type: | `float`
| Default: | `10.0F`
| Description: | Specifies the weight factor by which the snapshot size is multiplied in order to determine when to take the next snapshot--when the number of log records exceeds the product of `persistenceSnapshotWeight` and the snapshot size and is larger than the `persistenceSnapshotThreshold` value, then a snapshot is taken. This entry replaces the `setSnapshotWeight` method of the `RegistrarAdmin` interface supported by previous implementations of Reggie. It is obtained at service start and restart, and is only supported by `PersistentRegistrarImpl`.

• | `recoveredListenerPreparer`
--- | ---
| Type: | {@link net.jini.security.ProxyPreparer}
| Default: | `new {@link net.jini.security.BasicProxyPreparer}()`
| Description: | Specifies the proxy preparer to use for {@link net.jini.core.event.RemoteEventListener}s recovered from the service's persistent state log. During event notification, this service calls the {@link net.jini.core.event.RemoteEventListener#notify notify} method on `RemoteEventListener` instances returned from this preparer. This entry is obtained at service start and restart, and is only supported by `PersistentRegistrarImpl`.

• | `recoveredLocatorPreparer`
--- | ---
| Type: | {@link net.jini.security.ProxyPreparer}
| Default: | `new {@link net.jini.security.BasicProxyPreparer}()`
| Description: | Specifies the proxy preparer to use for {@link net.jini.core.discovery.LookupLocator}s recovered from the service's persistent state log. When registering with other lookup services, this service may call or use the constraints assigned to the `getRegistrar` methods of `LookupLocator` instances returned from this preparer. This entry is obtained at service start and restart, and is only supported by `PersistentRegistrarImpl`.

• | `resourceIdGenerator`
--- | ---
| Type: | {@link org.apache.river.reggie.UuidGenerator}
| Default: | `new UuidGenerator()`
| Description: | Specifies the generator for producing {@link net.jini.id.Uuid}s assigned to resources dispensed by the service, such as leases and service registrations. This entry is obtained at service start and restart.

• | `serverExporter`
--- | ---
| Type: | {@link net.jini.export.Exporter}
| Default: |
    // if non-activatable
    new {@link net.jini.jeri.BasicJeriExporter}(
        {@link net.jini.jeri.tcp.TcpServerEndpoint}.getInstance(0),
        new {@link net.jini.jeri.BasicILFactory}())

    // if activatable
    new {@link net.jini.activation.ActivationExporter}(
        activationID,
        new BasicJeriExporter(
            TcpServerEndpoint.getInstance(0),
            new BasicILFactory()))
| Description: | Specifies the exporter to use to export this service. Note that this entry, while supported by both `TransientRegistrarImpl` and `PersistentRegistrarImpl`, has a different default value for `PersistentRegistrarImpl` in the activatable case. For the activatable case, the `activationID` value is passed in as the `data` argument in the call to {@link net.jini.config.Configuration#getEntry(String,String,Class,Object,Object)}. This entry is obtained at service start and restart.

• | `serviceIdGenerator`
--- | ---
| Type: | {@link org.apache.river.reggie.UuidGenerator}
| Default: | `new UuidGenerator()`
| Description: | Specifies the generator for producing service IDs assigned to services registering with this lookup service that do not already have service IDs. This generator is also used to produce the service ID for this lookup service. The {@link net.jini.id.Uuid}s returned by the generator are converted into {@link net.jini.core.lookup.ServiceID} instances by extracting their 128-bit values and using them to construct corresponding `ServiceID`s. This entry is obtained at service start and restart.

• | `eventNotifierExecutor`
--- | ---
| Type: | {@link java.util.concurrent/ScheduledExecutorService ScheduledExecutorService}
| Default: | `new ScheduledThreadPoolExecutor( poolSizeLimit, /* = (numberOfCPUCores / 0.3) */ new NamedThreadFactory("Reggie_Event_Notifier", false))`
| Description: | Specifies the object that pools and manages the threads used by this service to send event notifications. The {@link java.util.concurrent/ExecutorService#shutdown shutdown} method of this object will be called when the service is destroyed. This entry is obtained at service start and restart.

• | `discoveryResponseExecutor`
--- | ---
| Type: | {@link java.util.concurrent/ExecutorService ExecutorService}
| Default: | `new ThreadPoolExecutor( poolSizeLimit, /* = (numberOfCPUCores / 0.3) */ poolSizeLimit, /* Ignored */ 15L, TimeUnit.MINUTES, new LinkedBlockingQueue(), /* Unbounded Queue */ new NamedThreadFactory("Reggie_Discovery_Response", false) )`
| Description: | Specifies the object that pools and manages the threads used by this service to respond to discovery requests. The {@link java.util.concurrent/ExecutorService#shutdownNow shutdownNow} method of this object will be called when the service is destroyed. Sockets for remaining tasks will be closed after this method returns. This entry is obtained at service start and restart.

• | `unexportTimeout`
--- | ---
| Type: | `long`
| Default: | `1000 * 60 *2L`
| Description: | Specifies the maximum time in milliseconds to wait for in-progress calls to finish before forcibly unexporting Reggie during shutdown.

• | `unexportWait`
--- | ---
| Type: | `long`
| Default: | `1000L`
| Description: | Specifies the maximum time in milliseconds to wait between unexport attempts during shutdown while `unexportTimeout` has not expired.

• | `unicastDiscoveryHost`
--- | ---
| Type: | `String`
| Default: | `{@link java.net.InetAddress}.getLocalHost().getHostName()`
| Description: | Specifies the host name for unicast discovery, which is advertised in multicast announcements and (protocol 2) unicast discovery responses. This entry is obtained at service start and restart.

• | `unicastDiscoverySubjectChecker`
--- | ---
| Type: | {@link org.apache.river.discovery.ClientSubjectChecker}
| Default: | Do not check client {@link javax.security.auth.Subject} during unicast discovery
| Description: | Specifies the object to use for screening unicast discovery attempts based on their authenticated client `Subject`s. This entry is obtained at service start and restart.

### Other Configuration Entries

Reggie passes its configuration when creating instances of the following configurable classes, which may support additional configuration entries:

- {@link net.jini.discovery.LookupDiscoveryManager}, used to discover lookup services, as specified by the `discoveryManager` configuration entry
- {@link net.jini.lookup.JoinManager}, used to manage lookup service registrations

## Access Control Permission Targets

The following table lists the remote methods on Reggie's proxy objects and the associated target names for enforcing access control using {@link org.apache.river.reggie.RegistrarPermission}:

Proxy Method | Target Name
--- | ---
{@link net.jini.core.lookup.ServiceRegistrar#getEntryClasses ServiceRegistrar.getEntryClasses} | `getEntryClasses`
{@link net.jini.core.lookup.ServiceRegistrar#getFieldValues ServiceRegistrar.getFieldValues} | `getFieldValues`
{@link net.jini.core.lookup.ServiceRegistrar#getGroups ServiceRegistrar.getGroups} | `getMemberGroups`
{@link net.jini.core.lookup.ServiceRegistrar#getLocator ServiceRegistrar.getLocator} | `getLocator`
{@link net.jini.core.lookup.ServiceRegistrar#getServiceTypes ServiceRegistrar.getServiceTypes} | `getServiceTypes`
{@link net.jini.core.lookup.ServiceRegistrar#lookup( net.jini.core.lookup.ServiceTemplate) ServiceRegistrar.lookup(ServiceTemplate)} | `lookup`
{@link net.jini.core.lookup.ServiceRegistrar#lookup( net.jini.core.lookup.ServiceTemplate, int) ServiceRegistrar.lookup(ServiceTemplate, int)} | `lookup`
{@link net.jini.core.lookup.ServiceRegistrar#notify ServiceRegistrar.notify} | `notify`
{@link net.jini.core.lookup.ServiceRegistrar#register ServiceRegistrar.register} | `register`
{@link net.jini.admin.Administrable#getAdmin Administrable.getAdmin} | `getAdmin`
{@link org.apache.river.start.ServiceProxyAccessor#getServiceProxy ServiceProxyAccessor.getServiceProxy} | `getServiceProxy`
{@link net.jini.core.lookup.ServiceRegistration#addAttributes ServiceRegistration.addAttributes} | `addAttributes`
{@link net.jini.core.lookup.ServiceRegistration#modifyAttributes ServiceRegistration.modifyAttributes} | `modifyAttributes`
{@link net.jini.core.lookup.ServiceRegistration#setAttributes ServiceRegistration.setAttributes} | `setAttributes`
{@link net.jini.core.lease.Lease#cancel Lease.cancel} (for event leases) | `cancelEventLease`
{@link net.jini.core.lease.Lease#renew Lease.renew} (for event leases) | `renewEventLease`
{@link net.jini.core.lease.Lease#cancel Lease.cancel} (for service leases) | `cancelServiceLease`
{@link net.jini.core.lease.Lease#renew Lease.renew} (for service leases) | `renewServiceLease`
{@link net.jini.core.lease.LeaseMap#cancelAll LeaseMap.cancelAll} | `cancelLeases`
{@link net.jini.core.lease.LeaseMap#renewAll LeaseMap.renewAll} | `renewLeases`
{@link net.jini.lookup.DiscoveryAdmin#addMemberGroups DiscoveryAdmin.addMemberGroups} | `addMemberGroups`
{@link net.jini.lookup.DiscoveryAdmin#getMemberGroups DiscoveryAdmin.getMemberGroups} | `getMemberGroups`
{@link net.jini.lookup.DiscoveryAdmin#getUnicastPort DiscoveryAdmin.getUnicastPort} | `getUnicastPort`
{@link net.jini.lookup.DiscoveryAdmin#removeMemberGroups DiscoveryAdmin.removeMemberGroups} | `removeMemberGroups`
{@link net.jini.lookup.DiscoveryAdmin#setMemberGroups DiscoveryAdmin.setMemberGroups} | `setMemberGroups`
{@link net.jini.lookup.DiscoveryAdmin#setUnicastPort DiscoveryAdmin.setUnicastPort} | `setUnicastPort`
{@link net.jini.admin.JoinAdmin#addLookupAttributes JoinAdmin.addLookupAttributes} | `addLookupAttributes`
{@link net.jini.admin.JoinAdmin#addLookupGroups JoinAdmin.addLookupGroups} | `addLookupGroups`
{@link net.jini.admin.JoinAdmin#addLookupLocators JoinAdmin.addLookupLocators} | `addLookupLocators`
{@link net.jini.admin.JoinAdmin#getLookupAttributes JoinAdmin.getLookupAttributes} | `getLookupAttributes`
{@link net.jini.admin.JoinAdmin#getLookupGroups JoinAdmin.getLookupGroups} | `getLookupGroups`
{@link net.jini.admin.JoinAdmin#getLookupLocators JoinAdmin.getLookupLocators} | `getLookupLocators`
{@link net.jini.admin.JoinAdmin#modifyLookupAttributes JoinAdmin.modifyLookupAttributes} | `modifyLookupAttributes`
{@link net.jini.admin.JoinAdmin#removeLookupGroups JoinAdmin.removeLookupGroups} | `removeLookupGroups`
{@link net.jini.admin.JoinAdmin#removeLookupLocators JoinAdmin.removeLookupLocators} | `removeLookupLocators`
{@link net.jini.admin.JoinAdmin#setLookupGroups JoinAdmin.setLookupGroups} | `setLookupGroups`
{@link net.jini.admin.JoinAdmin#setLookupLocators JoinAdmin.setLookupLocators} | `setLookupLocators`
{@link org.apache.river.admin.DestroyAdmin#destroy DestroyAdmin.destroy} | `destroy`
{@link net.jini.security.proxytrust.ProxyTrust#getProxyVerifier ProxyTrust.getProxyVerifier} | `getProxyVerifier`

## Loggers and Logging Levels

Both `PersistentRegistrarImpl` and `TransientRegistrarImpl` log diagnostic information to the {@link java.util.logging.Logger} named `org.apache.river.reggie`. The server-side components of each implementation log information at the following logging levels:

`org.apache.river.reggie` (server-side)
Level | Description
--- | ---
{@link java.util.logging.Level#SEVERE SEVERE} | Exceptions that prevent service startup
{@link java.util.logging.Level#WARNING WARNING} | Exceptions that, while non-fatal, indicate compromised service functionality, such as failures to persist or recover state, or to send multicast announcements on an explicitly configured interface
{@link java.util.logging.Level#INFO INFO} | Service start, restart, or destruction events, as well as exceptions of moderate severity, such as failures to send event notifications or multicast announcements, or to establish a unicast discovery connection
{@link java.util.logging.Level#CONFIG CONFIG} | Changes made to the service through administrative interfaces, as well as high-level service configuration information, such as the persistence directory (if any) and multicast interfaces (if any) used
{@link org.apache.river.logging.Levels#HANDLED HANDLED} | Minor exceptions involving activation, discovery, event handling, and shutdown that are handled internally by the service, and not reflected to callers
{@link java.util.logging.Level#FINE FINE} | Changes in service state, such as the establishment, expiration, and cancellation of service and event listener registrations, as well as invalid service ID values
{@link java.util.logging.Level#FINER FINER} | Persistent state log operations

The service proxies for `PersistentRegistrarImpl` and `TransientRegistrarImpl` log information at the following logging levels:

`org.apache.river.reggie` (service proxy)
Level | Description
--- | ---
{@link java.util.logging.Level#WARNING WARNING} | Invalid service IDs used for registration
{@link java.util.logging.Level#INFO INFO} | Service item unmarshalling exceptions

## System Properties

Both `TransientRegistrarImpl` and `PersistentRegistrarImpl` service implementations support the following system property:

• | `org.apache.river.reggie.enableImplToStubReplacement`
--- | ---
| Description: | This system property is interpreted as a `boolean` value (see {@link java.lang.Boolean#getBoolean Boolean.getBoolean}). If `true`, then JRMP impl-to-stub replacement will be attempted on the service proxy objects contained in {@link net.jini.core.lookup.ServiceItem}s passed to the {@link net.jini.core.lookup.ServiceRegistrar#register register} method of Reggie's proxy. By default, this behavior is not enabled--it is provided as a transitional measure for services that depend on JRMP impl-to-stub replacement when registering with Reggie.

## Examples for Running Reggie

This section provides examples of running Reggie in various configurations.

- Assumptions for running the examples
- Setting Discovery Constraints
- JRMP configurations
  - Transient
  - Persistent
  - Activatable
- Jini extensible remote invocation (Jini ERI) configurations
  - Transient
  - Persistent
  - Activatable
- Stopping activatable configurations

### Assumptions for Running the Examples

The examples below make the following assumptions:

- The Java(TM) 2 Platform, Standard Edition, (J2SE(TM)) has been installed, and its commands are available in the current path
- The Apache River release has been installed in the install_dir directory
- The example configuration and policy files described below are available in the config_dir directory
- The local host name is your_host
- The instance of Reggie to run will advertise itself as a member of the group named your.group
- The HTTP server for download JAR files is running on your_host and is available on port http_port. This HTTP server is serving files located in the install_dir/lib-dl directory. You can use the {@link org.apache.river.tool.ClassServer} class for this purpose.
- The examples are being run on UNIX platforms
- The examples are being run on a secure network where access control and authentication are not needed. See the hello example for some same client and service configurations that enforce security.
- For activatable services, an activation system is running on your_host. You can use the {@link org.apache.river.phoenix} implementation for this purpose.

Throughout the example, items in bold need to be customized for your local environment.

### Setting Discovery Constraints

Discovery constraints for Reggie can be set by specifying a `discoveryConstraints` entry under the `org.apache.river.reggie` component. For example, to specify that Reggie must wait at most five seconds to connect to a client attempting discovery and at most three minutes to read data from a connected client attempting discovery, the following entry must be added to Reggie's configuration source file under the `org.apache.river.reggie` component:

>     discoveryConstraints = new BasicMethodConstraints(
>         new MethodDesc[] {
>             new MethodDesc("unicastDiscovery",
>                 new InvocationConstraints(
>                     new InvocationConstraint[] {
>                         new ConnectionRelativeTime(5000),
>                         new UnicastSocketTimeout(180000) // 3*60*1000
>                     },
>                     null
>                 )
>             )
>         }
>     );

As another example, to specify that Reggie must use version two of of the multicast request, multicast announcement, and unicast discovery protocols, the following entry must be added to Reggie's configuration source file under the `org.apache.river.reggie` component.

>     discoveryConstraints = new BasicMethodConstraints(
>         new InvocationConstraints(DiscoveryProtocolVersion.TWO, null)
>     );

### Starting Transient Reggie using JRMP

To run a transient Reggie, which does not store any information persistently or use the activation system to restart itself, using JRMP for remote communication, run the following command.

>     java -Djava.security.policy=config_dir/jsk-all.policy \
>          -jar install_dir/lib/start.jar \
>          config_dir/start-transient-jrmp-reggie.config

This configuration uses the following files.

#### File config_dir/jsk-all.policy

Use this security policy file for starting and running all Reggie configurations. This file grants all permissions to local code included in the `lib` subdirectory of the Apache River release installation.

>     grant codebase "file:install_dir/lib/*" {
>         permission java.security.AllPermission;
>     };

#### File config_dir/start-transient-jrmp-reggie.config

Use this configuration source file to start transient Reggie using JRMP.

>     import org.apache.river.start.NonActivatableServiceDescriptor;
>     import org.apache.river.start.ServiceDescriptor;

>     org.apache.river.start {
>         private static codebase = "http://your_host:http_port/reggie-dl.jar"
>             + " http://your_host:http_port/jsk-dl.jar";
>         private static policy = "config_dir/jsk-all.policy";
>         private static classpath = "install_dir/lib/reggie.jar";
>         private static config = "config_dir/transient-jrmp-reggie.config";

>         static serviceDescriptors = new ServiceDescriptor[] {
>     	new NonActivatableServiceDescriptor(
>     	    codebase, policy, classpath,
>     	    "org.apache.river.reggie.TransientRegistrarImpl",
>     	    new String[] { config })
>         };
>     }

#### File config_dir/transient-jrmp-reggie.config

Use this configuration source file to run transient Reggie using JRMP.

>     import net.jini.jrmp.JrmpExporter;

>     org.apache.river.reggie {
>         initialMemberGroups = new String[] { "your.group" };
>         serverExporter = new JrmpExporter();
>     }

### Starting Persistent Reggie using JRMP

To run a persistent Reggie, which stores information persistently but does not use the activation system to restart itself, using JRMP for remote communication, run the following command.

>     java -Djava.security.policy=config_dir/jsk-all.policy \
>          -jar install_dir/lib/start.jar \
>          config_dir/start-persistent-jrmp-reggie.config

Note: Because JRMP does not provide a convenient way to specify the same object ID each time a given object is exported, this configuration is only useful for debugging -- an existing service proxy cannot be used after the service is restarted.

This configuration uses the following additional files.

#### File config_dir/start-persistent-jrmp-reggie.config

Use this configuration source file to start persistent Reggie using JRMP.

>     import org.apache.river.start.NonActivatableServiceDescriptor;
>     import org.apache.river.start.ServiceDescriptor;

>     org.apache.river.start {
>         private static codebase = "http://your_host:http_port/reggie-dl.jar"
>             + " http://your_host:http_port/jsk-dl.jar";
>         private static policy = "config_dir/jsk-all.policy";
>         private static classpath = "install_dir/lib/reggie.jar";
>         private static config = "config_dir/persistent-jrmp-reggie.config";

>         static serviceDescriptors = new ServiceDescriptor[] {
>     	new NonActivatableServiceDescriptor(
>     	    codebase, policy, classpath,
>     	    "org.apache.river.reggie.PersistentRegistrarImpl",
>     	    new String[] { config })
>         };
>     }

#### File config_dir/persistent-jrmp-reggie.config

Use this configuration source file to run persistent Reggie using JRMP.

>     import net.jini.jrmp.JrmpExporter;

>     org.apache.river.reggie {
>         initialMemberGroups = new String[] { "your.group" };
>         persistenceDirectory = "config_dir/reggie.log";
>         serverExporter = new JrmpExporter();
>     }

### Starting Activatable Reggie using JRMP

To run an activatable Reggie, which stores information persistently and uses the activation system to restart itself, using JRMP for remote communication, run the following command.

>     java -Djava.security.policy=config_dir/jsk-all.policy \
>          -jar install_dir/lib/start.jar \
>          config_dir/start-activatable-jrmp-reggie.config

You should remove the config_dir/group.log directory before running this command. Note that the activation system will restart the activatable Reggie service as needed until Reggie is shutdown.

Remember to remove the config_dir/reggie.log directory before running this command if you want Reggie to forget registrations and settings made in previous invocations.

This configuration uses the following additional files.

#### File config_dir/start-activatable-jrmp-reggie.config

Use this configuration source file to start activatable Reggie using JRMP.

>     import org.apache.river.start.ServiceDescriptor;
>     import org.apache.river.start.SharedActivatableServiceDescriptor;
>     import org.apache.river.start.SharedActivationGroupDescriptor;

>     org.apache.river.start {
>         private static reggieCodebase = "http://your_host:http_port/reggie-dl.jar"
>             + " http://your_host:http_port/jsk-dl.jar";
>         private static reggiePolicy = "config_dir/jsk-all.policy";
>         private static reggieClasspath = "install_dir/lib/reggie.jar";
>         private static reggieConfig = "config_dir/activatable-jrmp-reggie.config";

>         private static groupCodebase = "http://your_host:http_port/group-dl.jar";
>         private static groupPolicy = "config_dir/jsk-all.policy";
>         private static groupClasspath = "install_dir/lib/sharedvm.jar";
>         private static groupPersistenceDirectory = "config_dir/group.log";

>         static serviceDescriptors = new ServiceDescriptor[] {
>     	new SharedActivationGroupDescriptor(
>     	    groupPolicy, groupClasspath, groupPersistenceDirectory,
>     	    null /* serverCommand */,
>     	    null /* serverOptions */,
>     	    null /* serverProperties */),
>     	new SharedActivatableServiceDescriptor(
>     	    reggieCodebase, reggiePolicy, reggieClasspath,
>     	    "org.apache.river.reggie.PersistentRegistrarImpl",
>     	    groupPersistenceDirectory,
>     	    new String[] { reggieConfig },
>     	    true /* restart */)
>         };
>     }

#### File config_dir/activatable-jrmp-reggie.config

Use this configuration source file to run activatable Reggie using JRMP.

>     import java.rmi.activation.ActivationID;
>     import net.jini.jrmp.JrmpExporter;

>     org.apache.river.reggie {
>         initialMemberGroups = new String[] { "your.group" };
>         persistenceDirectory = "config_dir/reggie.log";
>         serverExporter = new JrmpExporter((ActivationID) $data, 0);
>     }

### Stopping Activatable Reggie

To destroy the activation group running an activatable Reggie, run using either JRMP or Jini ERI, run the following command.

>     java -Djava.security.policy=config_dir/jsk-all.policy \
>          -jar install_dir/lib/destroy.jar \
>          config_dir/stop-activatable-reggie.config

Running this command will remove the config_dir/group.log directory.

Note that this command does not actually destroy the service itself, but just destroys the activation group the service is running in. You may want to first destroy the service using Reggie's administrable interface, or to remove the config_dir/reggie.log directory after destroying the activation group.

This command uses the following additional file.

#### File config_dir/stop-activatable-reggie.config

Use this configuration source file to destroy the activation group for an activatable Reggie.

>     import org.apache.river.start.ServiceDescriptor;
>     import org.apache.river.start.SharedActivatableServiceDescriptor;

>     org.apache.river.start {
>         private static codebase = "http://your_host:http_port/group-dl.jar";
>         private static policy = "config_dir/jsk-all.policy";
>         private static classpath = "install_dir/lib/group.jar";
>         private static persistenceDirectory = "config_dir/group.log";

>         static serviceDestructors = new ServiceDescriptor[] {
>     	new SharedActivatableServiceDescriptor(
>     	    codebase, policy, classpath,
>     	    "org.apache.river.start.SharedGroupImpl",
>     	    persistenceDirectory,
>     	    null /* config */,
>     	    false /* restart */)
>         };
>     }

### Starting Transient Reggie using Jini ERI

To run a transient Reggie, which does not store any information persistently or use the activation system to restart itself, using Jini ERI for remote communication, run the following command.

>     java -Djava.security.policy=config_dir/jsk-all.policy \
>          -jar install_dir/lib/start.jar \
>          config_dir/start-transient-reggie.config

This configuration uses the following additional files.

#### File config_dir/start-transient-reggie.config

Use this configuration source file to start transient Reggie using Jini ERI.

>     import org.apache.river.start.NonActivatableServiceDescriptor;
>     import org.apache.river.start.ServiceDescriptor;

>     org.apache.river.start {
>         private static codebase = "http://your_host:http_port/reggie-dl.jar"
>             + " http://your_host:http_port/jsk-dl.jar";
>         private static policy = "config_dir/jsk-all.policy";
>         private static classpath = "install_dir/lib/reggie.jar";
>         private static config = "config_dir/transient-reggie.config";

>         static serviceDescriptors = new ServiceDescriptor[] {
>     	new NonActivatableServiceDescriptor(
>     	    codebase, policy, classpath,
>     	    "org.apache.river.reggie.TransientRegistrarImpl",
>     	    new String[] { config })
>         };
>     }

#### File config_dir/transient-reggie.config

Use this configuration source file to run transient Reggie using Jini ERI.

>     org.apache.river.reggie {
>         initialMemberGroups = new String[] { "your.group" };
>     }

### Starting Persistent Reggie using Jini ERI

To run a persistent Reggie, which stores information persistently but does not use the activation system to restart itself, using Jini ERI for remote communication, run the following command.

>     java -Djava.security.policy=config_dir/jsk-all.policy \
>          -jar install_dir/lib/start.jar \
>          config_dir/start-persistent-reggie.config

This configuration uses the following additional files.

#### File config_dir/start-persistent-reggie.config

Use this configuration source file to start persistent Reggie using Jini ERI.

>     import org.apache.river.start.NonActivatableServiceDescriptor;
>     import org.apache.river.start.ServiceDescriptor;

>     org.apache.river.start {
>         private static codebase = "http://your_host:http_port/reggie-dl.jar"
>             + " http://your_host:http_port/jsk-dl.jar";
>         private static policy = "config_dir/jsk-all.policy";
>         private static classpath = "install_dir/lib/reggie.jar";
>         private static config = "config_dir/persistent-reggie.config";

>         static serviceDescriptors = new ServiceDescriptor[] {
>     	new NonActivatableServiceDescriptor(
>     	    codebase, policy, classpath,
>     	    "org.apache.river.reggie.PersistentRegistrarImpl",
>     	    new String[] { config })
>         };
>     }

#### File config_dir/persistent-reggie.config

Use this configuration source file to run persistent Reggie using Jini ERI.

>     import net.jini.id.UuidFactory;
>     import net.jini.jeri.BasicILFactory;
>     import net.jini.jeri.BasicJeriExporter;
>     import net.jini.jeri.tcp.TcpServerEndpoint;

>     org.apache.river.reggie {
>         initialMemberGroups = new String[] { "your.group" };
>         persistenceDirectory = "config_dir/reggie.log";
>         serverExporter = new BasicJeriExporter(
>     	TcpServerEndpoint.getInstance(obj_port),
>     	new BasicILFactory(),
>     	false,
>     	true,
>     	UuidFactory.create("obj_UUID_string"));
>     }

The obj_port is the fixed TCP port to use for listening for requests for this object. The obj_UUID_string is the {@linkplain net.jini.id.Uuid universally unique ID} for the exported object. These IDs have the form `"01234567-89ab-cdef-0123-456789abcdef"`.

Remember to remove the config_dir/reggie.log directory before restarting persistent Reggie if you want it to forget registrations and settings made in previous invocations.

### Starting Activatable Reggie using Jini ERI

To run an activatable Reggie, which stores information persistently and uses the activation system to restart itself, using Jini ERI for remote communication, run the following command.

>     java -Djava.security.policy=config_dir/jsk-all.policy \
>          -jar install_dir/lib/start.jar \
>          config_dir/start-activatable-reggie.config

You should remove the config_dir/group.log directory before running this command. Note that the activation system will restart the activatable Reggie service as needed until Reggie is shutdown.

Remember to remove the config_dir/reggie.log directory before running this command if you want Reggie to forget registrations and settings made in previous invocations.

This configuration uses the following additional files.

#### File config_dir/start-activatable-reggie.config

Use this configuration source file to start activatable Reggie using Jini ERI.

>     import org.apache.river.start.ServiceDescriptor;
>     import org.apache.river.start.SharedActivatableServiceDescriptor;
>     import org.apache.river.start.SharedActivationGroupDescriptor;

>     org.apache.river.start {
>         private static reggieCodebase = "http://your_host:http_port/reggie-dl.jar"
>             + " http://your_host:http_port/jsk-dl.jar";
>         private static reggiePolicy = "config_dir/jsk-all.policy";
>         private static reggieClasspath = "install_dir/lib/reggie.jar";
>         private static reggieConfig = "config_dir/activatable-reggie.config";

>         private static groupCodebase = "http://your_host:http_port/group-dl.jar";
>         private static groupPolicy = "config_dir/jsk-all.policy";
>         private static groupClasspath = "install_dir/lib/sharedvm.jar";
>         private static groupPersistenceDirectory = "config_dir/group.log";

>         static serviceDescriptors = new ServiceDescriptor[] {
>     	new SharedActivationGroupDescriptor(
>     	    groupPolicy, groupClasspath, groupPersistenceDirectory,
>     	    null /* serverCommand */,
>     	    null /* serverOptions */,
>     	    null /* serverProperties */),
>     	new SharedActivatableServiceDescriptor(
>     	    reggieCodebase, reggiePolicy, reggieClasspath,
>     	    "org.apache.river.reggie.PersistentRegistrarImpl",
>     	    groupPersistenceDirectory,
>     	    new String[] { reggieConfig },
>     	    true /* restart */)
>         };
>     }

#### File config_dir/activatable-reggie.config

Use this configuration source file to run activatable Reggie using Jini ERI.

>     org.apache.river.reggie {
>         initialMemberGroups = new String[] { "your.group" };
>         persistenceDirectory = "config_dir/reggie.log";
>     }

@see net.jini.core.lookup @see net.jini.core.lookup.ServiceRegistrar