Provides the server side of an implementation of the lookup discovery service (see `{@link net.jini.discovery.LookupDiscoveryService}`). Multiple client-side proxy classes are used to interact and communicate with the backend server defined in the class `{@link org.apache.river.fiddler.FiddlerImpl}`. Those proxy classes are:

- `{@link org.apache.river.fiddler.FiddlerProxy}` - the proxy for the `{@link net.jini.discovery.LookupDiscoveryService}` interface, which defines how clients register with the lookup discovery service
- `{@link org.apache.river.fiddler.FiddlerAdminProxy}` - the proxy for the `{@link org.apache.river.fiddler.FiddlerAdmin}` interface, which specifies the methods through which clients can perform administrative duties such as joining, changing the policy for persisting the service's state, and gracefully shutting down the service
- `{@link org.apache.river.fiddler.FiddlerRegistration}` - the proxy for the `{@link net.jini.discovery.LookupDiscoveryRegistration}` interface, which specifies the methods through which clients can perform duties such as group and locator management, state retrieval, and discarding discovered but unavailable lookup services so they will be eligible for re-discovery

Clients interact with the Fiddler implementation of the lookup discovery service by communicating with the backend server through the above proxies. When a client makes a remote method invocation on one of the proxies, the proxy makes a call on the corresponding method which is specified in the `{@link org.apache.river.fiddler.Fiddler}` interface, is implemented in `{@link org.apache.river.fiddler.FiddlerImpl}`, and ultimately executes on the backend server.

The Fiddler implementation of the lookup discovery service can be run in one of the following modes:

- transient - when run in this mode, Fiddler will not persist its state, and it is not activatable; that is, it will not be restarted by the activation system upon a system crash or failure. To run Fiddler in this mode, specify the wrapper class `org.apache.river.fiddler.TransientFiddlerImpl`, to the {@link org.apache.river.start.NonActivatableServiceDescriptor}, as required by the {@link org.apache.river.start Service Starter} framework.
- nonactivatable - when run in this mode, Fiddler does persist its state, but is not activatable. To run Fiddler in this mode, specify the wrapper class `org.apache.river.fiddler.NonActivatableFiddlerImpl`, to the {@link org.apache.river.start.NonActivatableServiceDescriptor}, as required by the {@link org.apache.river.start Service Starter} framework.
- activatable - when run in this mode, Fiddler both persists its state, and is activatable. To run Fiddler in this mode, specify the wrapper class `org.apache.river.fiddler.ActivatableFiddlerImpl`, to the {@link org.apache.river.start.SharedActivatableServiceDescriptor}, as required by the {@link org.apache.river.start Service Starter} framework.

This document provides the following information about Fiddler:

- Configuring Fiddler
- Access Control Permission Targets
- Logging
- Examples for Running Fiddler

## Configuring Fiddler

The Fiddler implementation of the lookup discovery service supports the configuration entries described below; where each configuration entry name is associated with the component name `org.apache.river.fiddler`. Note that the configuration entries specified here are specific to the Fiddler implementation of the service. Also note that each entry whose name is prefixed with the string "initial" is retrieved only when the service is started for the first time. All other entries, unless otherwise stated, are retrieved from the configuration when the service is started or restarted.

• | `activationIdPreparer`
--- | ---
| Type: | {@link net.jini.security.ProxyPreparer}
| Default: | `new {@link net.jini.security.BasicProxyPreparer}()`
| Description: | Preparer for the proxy to the activation ID that is generated by the activation system and associated with the instance of the lookup discovery service that the activation system constructs. The value of this entry should not be `null`, and is only used when the service is run in activatable mode. This service does not invoke any methods on the prepared `ActivationID` directly; however, the service passes the prepared `ActivationID` to clients which may call its {@link java.rmi.activation.ActivationID#activate activate} method if they need to reactivate this service.

• | `activationSystemPreparer`
--- | ---
| Type: | {@link net.jini.security.ProxyPreparer}
| Default: | `new {@link net.jini.security.BasicProxyPreparer}()`
| Description: | Preparer for the proxy to the activation system. The value of this entry should not be `null`, and is only used when the service is run in activatable mode. The following methods of the proxy returned by this preparer are invoked by this service: {@link java.rmi.activation.ActivationSystem#unregisterObject unregisterObject}

• | `discoveryManager`
--- | ---
| Type: | {@link net.jini.discovery.DiscoveryManagement}
| Default: | `new {@link net.jini.discovery.LookupDiscoveryManager#LookupDiscoveryManager( java.lang.String[], net.jini.core.discovery.LookupLocator[], net.jini.discovery.DiscoveryListener, net.jini.config.Configuration) LookupDiscoveryManager}( {@link net.jini.discovery.DiscoveryGroupManagement#NO_GROUPS DiscoveryGroupManagement.NO_GROUPS}, new {@link net.jini.core.discovery.LookupLocator}[0], null, config)`
| Description: | The discovery manager that is passed to the join manager that is employed by this service to advertise itself to clients through lookup services. This discovery manager must satisfy the following requirements: it must not be `null`, it must be an instance of both the interface {@link net.jini.discovery.DiscoveryGroupManagement} and the interface {@link net.jini.discovery.DiscoveryLocatorManagement}, and it must be initially configured to discover `DiscoveryGroupManagement.NO_GROUPS` and no locators (`new` {@link net.jini.core.discovery.LookupLocator LookupLocator}[0]).

• | `initialLeaseBound`
--- | ---
| Type: | `long`
| Default: | `1000*60*30`
| Description: | The initial value of the least upper bound applied to the duration of each lease granted by this service. Once the service has completed startup processing, the value of this item can be modified through the `{@link org.apache.river.fiddler.FiddlerAdmin}` interface. During startup, and upon any change through `org.apache.river.fiddler.FiddlerAdmin`, the persistent version of the service stores the value of this item. After any crash-and-restart of the service, that stored value - rather than this configuration item - is always consulted during recovery.

• | `initialLookupAttributes`
--- | ---
| Type: | {@link net.jini.core.entry.Entry Entry[]}
| Default: | `null`
| Description: | Additional set of attributes the service will associate itself with when initially joining each targeted lookup service at startup. To determine the full set of attributes to use when initially joining lookup services, this set is combined with the set of attributes the service itself supplies internally (`{@link net.jini.lookup.entry.ServiceInfo}` and `{@link org.apache.river.lookup.entry.BasicServiceType}` for this implementation of the service). A `null` value is equivalent to an empty `{@link net.jini.core.entry.Entry}` array. This item is consulted only when the service starts up for the first time. During initial startup, the service joins all discovered lookup services, registering itself with the combined set of attributes described above. Once the initial join process is complete, the set of attributes with which the service is currently registered (and with which it is to perform all future joins) can be modified through the `{@link net.jini.admin.JoinAdmin}` interface. During startup, and upon any change through {@link net.jini.admin.JoinAdmin}, the service persists the set of attributes with which it is to join the lookup services of interest. After any crash-and-restart of the service, those persisted attributes - rather than this configuration item - are always consulted during recovery.

• | `initialLookupGroups`
--- | ---
| Type: | {@link java.lang.String}[]
| Default: | `new {@link java.lang.String}[] { "" } /* the public group */`
| Description: | Initial groups this service should discover and join. During initial startup, the service will retrieve the value contained in this item and directly configure itself to discover and join lookup services belonging to the given groups. Once the service has completed startup processing, the set of groups to join can be modified through the {@link net.jini.admin.JoinAdmin} interface. During startup, and upon any change through {@link net.jini.admin.JoinAdmin}, the service persists the set of groups to join. After any crash-and-restart of the service, those persisted group names - rather than this configuration item - are always consulted during recovery.

• | `initialLookupLocators`
--- | ---
| Type: | {@link net.jini.core.discovery.LookupLocator}[]
| Default: | `new {@link net.jini.core.discovery.LookupLocator}[0]`
| Description: | Initial locators of lookup services this service should discover and join. During initial startup, the service will retrieve the value contained in this item and directly configure itself to discover and join the lookup services corresponding to the given locators. Once the service has completed startup processing, the set of locators to join can be modified through the {@link net.jini.admin.JoinAdmin} interface. During startup, and upon any change through {@link net.jini.admin.JoinAdmin}, the service persists the set of locators to join. After any crash-and-restart of the service, those persisted locators - rather than this configuration item - are always consulted during recovery.

• | `initialPersistenceSnapshotThreshold`
--- | ---
| Type: | `int`
| Default: | `200`
| Description: | The initial value for the threshold used by the persistent versions of the service when deciding whether or not to take a snapshot of the service's state. This value represents the number of log records that must have been written since the last snapshot and before a new snapshot is taken. Once the service has completed startup processing, the value of this item can be modified through the `{@link org.apache.river.fiddler.FiddlerAdmin}` interface. During startup, and upon any change through `org.apache.river.fiddler.FiddlerAdmin`, the persistent version of the service stores the value of this item. After any crash-and-restart of the service, that stored value - rather than this configuration item - is always consulted during recovery.

• | `initialPersistenceSnapshotWeight`
--- | ---
| Type: | `float`
| Default: | `10`
| Description: | The initial value for the weight factor the persistent versions of the service each applies when deciding when to take a snapshot of the service's state. This value represents the ratio of the size of the snapshot record to the size of the log update record. Once the service has completed startup processing, the value of this item can be modified through the `{@link org.apache.river.fiddler.FiddlerAdmin}` interface. During startup, and upon any change through `org.apache.river.fiddler.FiddlerAdmin`, the persistent version of the service stores the value of this item. After any crash-and-restart of the service, that stored value - rather than this configuration item - is always consulted during recovery.

• | `leaseMax`
--- | ---
| Type: | `long`
| Default: | `1000L*60*60*24*365*1000`
| Description: | When re-setting the bound on lease durations, that bound cannot be set to a value larger than this value.

• | `listenerPreparer`
--- | ---
| Type: | {@link net.jini.security.ProxyPreparer}
| Default: | `new {@link net.jini.security.BasicProxyPreparer}()`
| Description: | Preparer for the proxies to the remote event listeners that are registered with this service. This preparer is used to prepare those listeners only when they are initially registered with this service. The value of this entry should not be `null`, and the preparer must return a listener that is equal to the original listener as determined by `Object.equals`. This preparer should perform all operations required to use a newly received listener, typically including verifying trust in the listener proxy, granting permissions, and setting constraints. The prepared listener will be retained by the service in its persistent store. The following methods of the proxy returned by this preparer are invoked by this service: {@link net.jini.core.event.RemoteEventListener#notify notify}

• | `locatorToDiscoverPreparer`
--- | ---
| Type: | {@link net.jini.security.ProxyPreparer}
| Default: | `new {@link net.jini.security.BasicProxyPreparer}()`
| Description: | Preparer for the lookup locators of the lookup services this service is to discover on behalf of the clients that register with it. This preparer is used to prepare those locators only when they are initially input to this service; either when a client first registers with this service, or later, when the registration's locators-of-interest are changed through the `LookupDiscoveryRegistration`. The value of this entry should not be `null`. This preparer should perform all operations required to use a newly received lookup locator, typically including verifying trust in the listener proxy, granting permissions, and setting constraints. The prepared lookup locator will be retained by the service in its persistent store. Currently, none of the methods on the lookup locator returned by this preparer are invoked by this implementation of the service.

• | `locatorToJoinPreparer`
--- | ---
| Type: | {@link net.jini.security.ProxyPreparer}
| Default: | `new {@link net.jini.security.BasicProxyPreparer}()`
| Description: | Preparer for the lookup locators of the lookup services the service itself is to discover and join. This preparer is used to prepare those locators only when they are initially associated with this service; either when this service is first started, or later, when the locators are changed through the {@link net.jini.admin.JoinAdmin} interface. The value of this entry should not be `null`. This preparer should perform all operations required to use a newly received lookup locator, typically including verifying trust in the listener proxy, granting permissions, and setting constraints. The prepared lookup locator will be retained by the service in its persistent store. The `LookupLocator` instances obtained from the `initialLookupLocators` configuration entry will not be prepared by this preparer. When joining any lookup service, this service may invoke (or use the constraints assigned to) the following methods of the `LookupLocator` instances returned by this preparer: {@link net.jini.core.discovery.LookupLocator#getRegistrar getRegistrar}

• | `loginContext`
--- | ---
| Type: | {@link javax.security.auth.login.LoginContext}
| Default: | no login context
| Description: | The JAAS login context to use for performing a JAAS login. This context also provides the `Subject` the service will run as after the service has successfully logged in. If the value of this entry is `null`, no JAAS login is performed.

• | `persistenceDirectory`
--- | ---
| Type: | {@link java.lang.String}
| Default: | Required for persistent implementations: no default
| Description: | The path of the directory in which this service will store its persistent state. This entry is required only for persistent (activatable and nonactivatable) implementations of this service; otherwise it is not used. The value of this entry should not be `null`, and the associated directory should not already exist. That directory will be deleted if the service is destroyed through the `{@link org.apache.river.admin.DestroyAdmin}` interface.

• | `recoveredListenerPreparer`
--- | ---
| Type: | {@link net.jini.security.ProxyPreparer}
| Default: | `new {@link net.jini.security.BasicProxyPreparer}()`
| Description: | Preparer for the proxies to the remote event listeners that are registered with this service. This preparer is used to prepare those listeners only after they have been previously prepared; for example, upon recovery of the service's persisted state. The value of this entry should not be `null`, and is only used by the persistent versions of this service (activatable and nonactivatable modes). This preparer needs to perform only those operations whose results are not retained in the listener proxy itself, but which need need to be performed in the environment in which the proxy is unmarshalled; typically the granting of permissions. The following methods of the proxy returned by this preparer are invoked by this service: {@link net.jini.core.event.RemoteEventListener#notify notify}

• | `recoveredLocatorToDiscoverPreparer`
--- | ---
| Type: | {@link net.jini.security.ProxyPreparer}
| Default: | `new {@link net.jini.security.BasicProxyPreparer}()`
| Description: | Preparer for the lookup locators of the lookup services this service is to discover on behalf of the clients that register with it. This preparer is used to prepare those locators only after they have been previously prepared; for example, upon recovery of the service's persisted state. The value of this entry should not be `null`, and is only used by the persistent versions of this service (activatable and nonactivatable modes). This preparer should perform only those operations whose results are not retained in the lookup locator itself, but which need to be performed in the environment in which the proxy is unmarshalled; typically the granting of permissions.

• | `recoveredLocatorToJoinPreparer`
--- | ---
| Type: | {@link net.jini.security.ProxyPreparer}
| Default: | `new {@link net.jini.security.BasicProxyPreparer}()`
| Description: | Preparer for the lookup locators of the lookup services the service itself is to discover and join. This preparer is used to prepare those locators only after they have been previously prepared; for example, upon recovery of the service's persisted state. The value of this entry should not be `null`, and is only used by the persistent versions of this service (activatable and nonactivatable modes). This preparer should perform only those operations whose results are not retained in the lookup locator itself, but which need to be performed in the environment in which the proxy is unmarshalled; typically the granting of permissions. The `LookupLocator` instances obtained from the `initialLookupLocators` are prepared by this preparer only during recovery.

• | `serverExporter`
--- | ---
| Type: | {@link net.jini.export.Exporter}
| Default: | Activatable case - `new {@link net.jini.activation.ActivationExporter#ActivationExporter( java.rmi.activation.ActivationID, net.jini.export.Exporter) ActivationExporter}( activationID, new {@link net.jini.jeri.BasicJeriExporter#BasicJeriExporter( net.jini.jeri.ServerEndpoint, net.jini.jeri.InvocationLayerFactory, boolean, boolean) BasicJeriExporter}( {@link net.jini.jeri.tcp.TcpServerEndpoint#getInstance TcpServerEndpoint.getInstance}(0), new {@link net.jini.jeri.BasicILFactory}(), false, true) )` Nonactivatable case - `new {@link net.jini.jeri.BasicJeriExporter#BasicJeriExporter( net.jini.jeri.ServerEndpoint, net.jini.jeri.InvocationLayerFactory, boolean, boolean) BasicJeriExporter}( {@link net.jini.jeri.tcp.TcpServerEndpoint#getInstance TcpServerEndpoint.getInstance}(0), new {@link net.jini.jeri.BasicILFactory}(), false, true)`
| Description: | The object to use for exporting this service. The value of this entry should not be `null`. When this service is run in the activatable mode, the call to `getEntry` will supply the activation ID in the `data` argument.

• | `executorService`
--- | ---
| Type: | {@link java.util.concurrent/ExecutorService ExecutorService}
| Default: | `new {@link java.util.concurrent/ThreadPoolExecutor ThreadPoolExecutor}( 10, 10, 15, TimeUnit.SECONDS, new LinkedBlockingQueue(), new NamedThreadFactory("Fiddler Executor", false) )`
| Description: | The object that pools and manages the various threads executed by this implementation of the service.

The configuration passed to Fiddler will be passed to one or more of the configurable classes listed below. Thus, the same configuration used to configure Fiddler is also used to configure instances of the classes used by Fiddler to perform that service's lookup discovery and join management duties. For information on the configuration entries supported by those classes, refer to the documentation associated with each class.

- `LookupDiscovery`, employed by the service to use the multicast discovery protocol to discover the group(s) of lookup services the service should join, as specified through the `discoveryManager` configuration entry
- `LookupLocatorDiscovery`, employed by the service to use the unicast discovery protocol to discover the specific lookup service(s) the service should join, as specified through the `discoveryManager` configuration entry
- `JoinManager`, employed by the service to manage the service's join state related to the lookup service(s) discovered through multicast and/or unicast discovery

## Access Control Permission Targets

The following table lists the names of the remote methods provided by the proxy objects to the Fiddler backend server, and each method's corresponding target name, which can be used to enforce access control using {@link org.apache.river.fiddler.FiddlerPermission}:

Proxy Method | Target Name
--- | ---
{@link net.jini.discovery.LookupDiscoveryService#register LookupDiscoveryService.register} | register
{@link net.jini.discovery.LookupDiscoveryRegistration#getRegistrars LookupDiscoveryRegistration.getRegistrars} | getRegistrars
{@link net.jini.discovery.LookupDiscoveryRegistration#getGroups LookupDiscoveryRegistration.getGroups} | getGroups
{@link net.jini.discovery.LookupDiscoveryRegistration#getLocators LookupDiscoveryRegistration.getLocators} | getLocators
{@link net.jini.discovery.LookupDiscoveryRegistration#addGroups LookupDiscoveryRegistration.addGroups} | addGroups
{@link net.jini.discovery.LookupDiscoveryRegistration#setGroups LookupDiscoveryRegistration.setGroups} | setGroups
{@link net.jini.discovery.LookupDiscoveryRegistration#removeGroups LookupDiscoveryRegistration.removeGroups} | removeGroups
{@link net.jini.discovery.LookupDiscoveryRegistration#addLocators LookupDiscoveryRegistration.addLocators} | addLocators
{@link net.jini.discovery.LookupDiscoveryRegistration#setLocators LookupDiscoveryRegistration.setLocators} | setLocators
{@link net.jini.discovery.LookupDiscoveryRegistration#removeLocators LookupDiscoveryRegistration.removeLocators} | removeLocators
{@link net.jini.discovery.LookupDiscoveryRegistration#discard LookupDiscoveryRegistration.discard} | discard
{@link net.jini.core.lease.Lease#renew Lease.renew} | renewLease
{@link net.jini.core.lease.Lease#cancel Lease.cancel} | cancelLease
{@link net.jini.core.lease.LeaseMap#renewAll LeaseMap.renewAll} | renewLeases
{@link net.jini.core.lease.LeaseMap#cancelAll LeaseMap.cancelAll} | cancelLeases
{@link net.jini.admin.Administrable#getAdmin Administrable.getAdmin} | getAdmin
{@link org.apache.river.fiddler.FiddlerAdmin#setLeaseBound FiddlerAdmin.setLeaseBound} | setLeaseBound
{@link org.apache.river.fiddler.FiddlerAdmin#getLeaseBound FiddlerAdmin.getLeaseBound} | getLeaseBound
{@link org.apache.river.fiddler.FiddlerAdmin#setPersistenceSnapshotWeight FiddlerAdmin.setPersistenceSnapshotWeight} | setPersistenceSnapshotWeight
{@link org.apache.river.fiddler.FiddlerAdmin#getPersistenceSnapshotWeight FiddlerAdmin.getPersistenceSnapshotWeight} | getPersistenceSnapshotWeight
{@link org.apache.river.fiddler.FiddlerAdmin#setPersistenceSnapshotThreshold FiddlerAdmin.setPersistenceSnapshotThreshold} | setPersistenceSnapshotThreshold
{@link org.apache.river.fiddler.FiddlerAdmin#getPersistenceSnapshotThreshold FiddlerAdmin.getPersistenceSnapshotThreshold} | getPersistenceSnapshotThreshold
{@link net.jini.admin.JoinAdmin#getLookupAttributes JoinAdmin.getLookupAttributes} | getLookupAttributes
{@link net.jini.admin.JoinAdmin#addLookupAttributes JoinAdmin.addLookupAttributes} | addLookupAttributes
{@link net.jini.admin.JoinAdmin#modifyLookupAttributes JoinAdmin.modifyLookupAttributes} | modifyLookupAttributes
{@link net.jini.admin.JoinAdmin#getLookupGroups JoinAdmin.getLookupGroups} | getLookupGroups
{@link net.jini.admin.JoinAdmin#addLookupGroups JoinAdmin.addLookupGroups} | addLookupGroups
{@link net.jini.admin.JoinAdmin#removeLookupGroups JoinAdmin.removeLookupGroups} | removeLookupGroups
{@link net.jini.admin.JoinAdmin#setLookupGroups JoinAdmin.setLookupGroups} | setLookupGroups
{@link net.jini.admin.JoinAdmin#getLookupLocators JoinAdmin.getLookupLocators} | getLookupLocators
{@link net.jini.admin.JoinAdmin#addLookupLocators JoinAdmin.addLookupLocators} | addLookupLocators
{@link net.jini.admin.JoinAdmin#removeLookupLocators JoinAdmin.removeLookupLocators} | removeLookupLocators
{@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
{@link org.apache.river.start.ServiceProxyAccessor#getServiceProxy ServiceProxyAccessor.getServiceProxy} | getServiceProxy

## Loggers Employed By Fiddler

This implementation of the lookup discovery service (Fiddler) uses a separate `{@link java.util.logging.Logger}` for each type of information it logs. The name of each `Logger` is a dot-separated concatenation of the implementation package name, `org.apache.river.fiddler`, with a descriptive string. The list below identifies the descriptive part of each `Logger` name, along with a brief description of the information that will be sent to the associated Logger.

- `discard` - trace information related to lookup services that are discarded by this service
- `events` - trace information related to events sent or received by this service
- `groupsLogger` - trace information related to the groups this service is attempting to discover on behalf of its clients
- `lease` - trace information related to the leases granted or received by this service
- `locators` - trace information related to the locators this service is attempting to discover on behalf of its clients
- `persist` - trace information related to the state persistence mechanism employed by the implementation of this service
- `problem` - serious, unexpected problems that the user/deployer/administrator needs to know about
- `registration` - trace information related to the registrations granted by or to this service
- `startup` - one time trace information such as startup/deactivation/shutdown notices
- `discard` - trace information related to the tasks executed by this implementation of the service

For each `Logger` named above, the following tables describe the information that will be logged, and the levels at which that information will be logged:

`org.apache.river.fiddler.discard`
Level | Description
--- | ---
{@link java.util.logging.Level#FINE FINE} | trace information related to lookup services that are discarded by this service

`org.apache.river.fiddler.events`
Level | Description
--- | ---
{@link java.util.logging.Level#FINE FINE} | trace information related to events sent or received by this service

`org.apache.river.fiddler.groups`
Level | Description
--- | ---
{@link java.util.logging.Level#FINER FINER} | trace information related to the groups this service is attempting to discover

`org.apache.river.fiddler.lease`
Level | Description
--- | ---
{@link java.util.logging.Level#FINER FINER} | trace information related to the leases granted or received by this service

`org.apache.river.fiddler.locator`
Level | Description
--- | ---
{@link java.util.logging.Level#FINER FINER} | trace information related to the locators this service is attempting to discover on behalf of its clients

`org.apache.river.fiddler.persist`
Level | Description
--- | ---
{@link java.util.logging.Level#FINEST FINEST} | trace information related to the state persistence mechanism employed by the implementation of this service

`org.apache.river.fiddler.problem`
Level | Description
--- | ---
{@link java.util.logging.Level#SEVERE SEVERE} | problems which prevent startup or cause shutdown of the service, or which generally prevent the service from continuing with its processing
{@link java.util.logging.Level#WARNING WARNING} | problems that allow the service to continue with its processing, but in a "crippled" state that might be serious enough to affect other operations in the system
{@link java.util.logging.Level#INFO INFO} | serious, unexpected "problems" that occur during processing that the user/deployer/administrator needs to know about, but which doesn't necessarily indicate problems with other operations in the system
{@link org.apache.river.logging.Levels#FAILED FAILED} | exceptions that occur while retrieving the locator of a discovered lookup service
{@link org.apache.river.logging.Levels#HANDLED HANDLED} | problems that occur while attempting to prepare locators or log information about events the service sends

`org.apache.river.fiddler.registration`
Level | Description
--- | ---
{@link java.util.logging.Level#FINER FINER} | trace information related to the registrations granted by or to this service

`org.apache.river.fiddler.startup`
Level | Description
--- | ---
{@link java.util.logging.Level#INFO INFO} | one time trace information, such as startup/deactivation/shutdown notices

`org.apache.river.fiddler.tasks`
Level | Description
--- | ---
{@link java.util.logging.Level#FINEST FINEST} | trace information related to the tasks executed by this implementation of the service

See the {@link org.apache.river.logging.LogManager} class for one way to use the logging levels `HANDLED` and `FAILED` in standard logging configuration files.

## Examples for Running Fiddler

This section provides example command lines, configuration files, and security policy files for running Fiddler in several configurations. These examples make the following assumptions:

- The examples are being run on UNIX platforms.
- The Java(TM) 2 Platform, Standard Edition, has been installed in the directory java_install_dir
- The Apache River release has been installed in the directory jini_install_dir
- The example configuration and policy files described below are available in the directories example_install_dir/config and example_install_dir/policy respectively
- The name of the host on which the service will run is myHost
- The name of the lookup group the service will discover and join is myGroup.myCompany.com
- The HTTP server for download JAR files will listen for requests on port 8080

To use these examples to start Fiddler on your system, you will need to make one or more modifications that are specific to your system. The list below describes the sort of modifications you may need to make in order for the examples to run on your system.

- Change all occurrences of myHost to the actual name of the host on which the service is to run.
- Replace all occurrences of java_install_dir with the path to the 1.4 version (or above) of the Java 2 Platform installed on your system.
- Replace all occurrences of jini_install_dir with the path to the desired version of the Apache River release.
- Replace all occurrences of example_install_dir/config and example_install_dir/policy with the appropriate path to the example configuration and policy files.
- With respect to the command lines provided below, if running on Windows, replace the UNIX file system separator '/' with the Windows separator ('\'), prepend the appropriate drive-letter-with-colon on all directory path file specifications, and replace the various install directories if appropriate.
- With respect to the configuration and policy files, if running on Windows, prepend the appropriate drive-letter-with-colon on all directory path file specifications, and replace install directories where appropriate.

Note that when running on Windows, unlike the command lines, it is not necessary to replace the UNIX file system separator with the Windows separator in the example configuration and policy files provided here. This is because those files specify directory paths using the special token for the `file.separator` system property ('${/}'); which provides for the automatic substitution of the appropriate separator, depending on the OS.

### HTTP Server

For each of the possible modes in which Fiddler executes, an HTTP server must be running that makes available the necessary download JAR files from the jini_install_dir/lib-dl directory. Note that the same HTTP server can be used for all of the examples described below. That is, once started, the HTTP server does not need to be stopped and restarted for each mode in which the service runs.

If you choose to use the HTTP server supplied with the Apache River release, then the following command will start that daemon in verbose mode, listening for requests on port `8080`, and serving files from the root directory, jini_install_dir/lib-dl:

>     java_install_dir/bin/java -jar jini_install_dir/lib/classserver.jar \
>                                    -dir jini_install_dir/lib-dl \
>                                    -port 8080 \
>                                    -verbose

Note that rather than executing the HTTP server directly as shown above, it can also be run as a transient service using the {@link org.apache.river.start Service Starter} framework. For details on how to do this, refer to the `ClassServer` documentation.

### The Execution Modes of the Service

As stated above, Fiddler can be run in one of the following three modes:

- transient (not persistent and not activatable)
- nonactivatable (persistent but not activatable)
- activatable (persistent and activatable)

One of the significant features of Jini Network Technology is that it is designed to allow for configuration and pluggability of the remote communication framework itself, as well as the transport employed by that framework. Because of this, the list of framework/transport combinations that Fiddler can be configured to use for its remote communication, in conjunction with the mode in which Fiddler is configured to run, is essentially boundless. The flexibility inherent in the configuration mechanism allows Fiddler not only to be configured to employ any existing remote communication framework and transport, but also any future framework or transport that may be defined. The current release of Apache River provides implementations for the following remote communication frameworks and transports:

- JRMP over TCP/IP
- Jini Extensible Remote Invocation (Jini ERI) over TCP/IP (the default for all modes)
- Jini ERI over HTTP
- Jini ERI over HTTPS
- Jini ERI over SSL/TLS (JSSE)
- Jini ERI over Kerberos/GSS-API (JGSS)

So as not to exceed the scope of this document, the examples below are limited to the following combinations of mode and remote communication mechanism:

- `transient mode using JRMP over TCP/IP`
- `transient mode using Jini ERI over TCP/IP`
- `nonactivatable mode using Jini ERI over TCP/IP`
- `activatable mode using JRMP over TCP/IP`
- `activatable mode using Jini ERI over TCP/IP`

For detailed examples of the other combinations, see the hello example supplied with the Apache River release.

### Activation

In order to run the activatable mode of this service, an activation system must be running on the same host as the service. For previous releases, RMID was used for this purpose. Although RMID may still be used under certain circumstances, it is recommended that the `org.apache.river.phoenix` implementation supplied with the Apache River release now be used for all activatable configurations of the service.

For the two activatable examples below, command lines for starting and stopping Phoenix, along with an associated set of example configuration and policy files are presented. Note that, as with the HTTP server, Phoenix may also be started using the {@link org.apache.river.start Service Starter} framework (as described `here`).

### Configuration and Security Policy Files

In each of the examples below, the service requires a configuration file and a security policy file. Additionally, because the Service Starter framework is used to start the service, a separate configuration and policy file - different than that provided for the service - are provided for that framework. Finally, for the activatable mode of the service, not only are configuration files and a security policy file required to run Phoenix, but because the Service Starter framework executes the service in an `{@link java.rmi.activation.ActivationGroup ActivationGroup}` (referred to as a shared VM) that may be shared with other services, a configuration and policy file are both required to be defined for the shared VM as well.

The table below shows what is required for each example configuration of Fiddler presented here:

`Example Configuration Matrix`
Mode RMI | Daemons | Configuration | Security Policy
--- | --- | --- | ---
`Transient JRMP` | `HTTPD` | `jrmp-start-transient.config` `jrmp-transient-fiddler.config` | `jrmp-start-transient.policy` `jrmp-transient-fiddler.policy`
`Transient Jini ERI` | `HTTPD` | `jeri-start-transient.config` `jeri-transient-fiddler.config` | `jeri-start-transient.policy` `jeri-transient-fiddler.policy`
`Non- activatable Jini ERI` | `HTTPD` | `jeri-start-nonactivatable.config` `jeri-nonactivatable-fiddler.config` | `jeri-start-nonactivatable.policy` `jeri-nonactivatable-fiddler.policy`
`Activatable JRMP` | `HTTPD` `Phoenix` | `jrmp-start-activatable.config` `jrmp-activatable-fiddler.config` `jrmp-phoenix.config` `jrmp-phoenix-group.config` `jrmp-destroyGroup.config` | `jrmp-start-activatable.policy` `jrmp-activatable-fiddler.policy` `jrmp-phoenix.policy` `jrmp-sharedvm.policy`
`Activatable Jini ERI` | `HTTPD` `Phoenix` | `jeri-start-activatable.config` `jeri-activatable-fiddler.config` `jeri-phoenix.config` `jeri-phoenix-group.config` `jeri-destroyGroup.config` | `jeri-start-activatable.policy` `jeri-activatable-fiddler.policy` `jeri-phoenix.policy` `jeri-sharedvm.policy`

What follows are the command lines used to start Fiddler in the configurations summarized in the table above, as well as example content for the various configuration and policy files required by each of those example configurations.

### Transient Mode using JRMP

The following command will start Fiddler in transient mode using JRMP for remote communication. This configuration of Fiddler will not persist any state information, and it will not be restarted by the activation system upon a system crash or failure.

#### Command Line

>     java_install_dir/bin/java \
>       -Djava.security.manager= \
>       -Djava.security.policy=example_install_dir/policy/jrmp-start-transient.policy \
>         -jar jini_install_dir/lib/start.jar \
>                example_install_dir/config/jrmp-start-transient.config

#### Starter Configuration: example_install_dir/config/jrmp-start-transient.config

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

>     org.apache.river.start {

>         private static serviceCodebase   = new String("http://myHost:8080/fiddler-dl.jar http://myHost:8080/jsk-dl.jar");
>         private static servicePolicyFile = new String("example_install_dir${/}policy${/}jrmp-transient-fiddler.policy");
>         private static serviceClasspath  = new String("jini_install_dir${/}lib${/}fiddler.jar");
>         private static serviceImplName   = new String("org.apache.river.fiddler.TransientFiddlerImpl");
>         private static serviceConfig     = new String("example_install_dir${/}config${/}jrmp-transient-fiddler.config");
>         private static serviceArgsArray  = new String[] { serviceConfig };

>         private static nonActivatableServiceDescriptor =
>                        new NonActivatableServiceDescriptor(serviceCodebase,
>                                                            servicePolicyFile,
>                                                            serviceClasspath,
>                                                            serviceImplName,
>                                                            serviceArgsArray);
>         static serviceDescriptors =
>                      new ServiceDescriptor[] { nonActivatableServiceDescriptor };

>     }//end org.apache.river.start

#### Service Configuration: example_install_dir/config/jrmp-transient-fiddler.config

>     import net.jini.jrmp.JrmpExporter;

>     org.apache.river.fiddler {

>         serverExporter = new JrmpExporter();
>         initialLookupGroups = new String[] {"myGroup.myCompany.com"};

>     }//end org.apache.river.fiddler

#### Starter Security Policy: example_install_dir/policy/jrmp-start-transient.policy

>     grant codebase "file:jini_install_dir/lib/jsk-platform.jar" {
>         permission java.security.AllPermission;
>     };

>     grant codebase "file:${java.class.path}" {
>         permission java.security.AllPermission;
>     };

#### Service Security: example_install_dir/policy/jrmp-transient-fiddler.policy

>     grant codebase "file:jini_install_dir/lib/jsk-lib.jar" {
>         permission java.security.AllPermission;
>     };

>     grant codeBase "file:jini_install_dir/lib/fiddler.jar" {
>         permission java.security.AllPermission;
>     };

### Transient Mode using Jini ERI

The following command will start Fiddler in transient mode using Jini ERI for remote communication. As with the transient-JRMP configuration, this configuration of Fiddler will not persist any state information, and it will not be restarted by the activation system upon a system crash or failure.

#### Command Line

>     java_install_dir/bin/java \
>       -Djava.security.manager= \
>       -Djava.security.policy=example_install_dir/policy/jeri-start-transient.policy \
>         -jar jini_install_dir/lib/start.jar \
>                example_install_dir/config/jeri-start-transient.config

#### Starter Configuration: example_install_dir/config/jeri-start-transient.config

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

>     org.apache.river.start {

>         private static serviceCodebase   = new String("http://myHost:8080/fiddler-dl.jar http://myHost:8080/jsk-dl.jar");
>         private static servicePolicyFile = new String("example_install_dir${/}policy${/}jeri-transient-fiddler.policy");
>         private static serviceClasspath  = new String("jini_install_dir${/}lib${/}fiddler.jar");
>         private static serviceImplName   = new String("org.apache.river.fiddler.TransientFiddlerImpl");
>         private static serviceConfig     = new String("example_install_dir${/}config${/}jeri-transient-fiddler.config");
>         private static serviceArgsArray  = new String[] { serviceConfig };

>         private static nonActivatableServiceDescriptor =
>                        new NonActivatableServiceDescriptor(serviceCodebase,
>                                                            servicePolicyFile,
>                                                            serviceClasspath,
>                                                            serviceImplName,
>                                                            serviceArgsArray);
>         static serviceDescriptors =
>                      new ServiceDescriptor[] { nonActivatableServiceDescriptor };

>     }//end org.apache.river.start

#### Service Configuration: example_install_dir/config/jeri-transient-fiddler.config

Note that the value of the `serverExporter` configuration entry specified in this example configuration file is actually the default value that would be used by the service if no value were supplied for that entry. Although it is not necessary to specify a value for that entry, it is included in this example for reference purposes. Note also that when the value of the `port` argument in the call to `TcpServerEndpoint.getInstance` is 0 (as it is in this example), the actual port used to export the service will be randomly chosen by the Jini ERI framework.

It may be worth comparing the exporter specified in this example to the exporter specified in the `JERI/Nonactivatable` example presented later. This example allows the Jini ERI framework - not the deployer - to choose the port and object ID with which to export the service, whereas the `JERI/Nonactivatable` example specifies a specific port and object ID to use. This can be seen by observing that this example inputs 0 for the port and uses only the 4-argument version of the `{@link net.jini.jeri.BasicJeriExporter BasicJeriExporter}` constructor (leaving the object ID unspecified), whereas the other example configures the exporter using the 5-argument version of the constructor, supplying a non-zero value for the port and a specific value for the object ID in the last argument.

To understand why the transient and nonactivatable modes of the service are exported differently, consider the following. The nonactivatable mode of the service persists its state because it wishes to be able to recover and pick up where it left off when it is restarted after a crash or system failure. As will be explained in a little more detail `below`, in order to do this, the service must always be exported and re-exported using the same port and object ID. Thus, for the nonactivatable mode of the service under Jini ERI, the exporter used is configured with a fixed port and object ID. On the other hand, there is no such requirement for the transient modes of the service (under either JRMP or Jini ERI). This is because by its nature, each time a transient service is started, it is as if it is started for the very first time; there is no state to recover, no "place" to pick up where a previous run left off.

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

>     org.apache.river.fiddler {

>         private invocationLayerFactory = new BasicILFactory();
>         serverExporter = new BasicJeriExporter(TcpServerEndpoint.getInstance(0),
>                                                invocationLayerFactory,
>                                                false,
>                                                true);

>         initialLookupGroups = new String[] {"myGroup.myCompany.com"};

>     }//end org.apache.river.fiddler

#### Starter Security Policy: example_install_dir/policy/jeri-start-transient.policy

>     grant codebase "file:jini_install_dir/lib/jsk-platform.jar" {
>         permission java.security.AllPermission;
>     };

>     grant codebase "file:${java.class.path}" {
>         permission java.security.AllPermission;
>     };

#### Service Security: example_install_dir/policy/jeri-transient-fiddler.policy

>     grant codebase "file:jini_install_dir/lib/jsk-lib.jar" {
>         permission java.security.AllPermission;
>     };

>     grant codeBase "file:jini_install_dir/lib/fiddler.jar" {
>         permission java.security.AllPermission;
>     };

### Nonactivatable Mode using JRMP

Although it is possible to run Fiddler in nonactivatable mode using JRMP, it is not recommended. This is because when Fiddler has been configured in this way and is restarted, clients of the service that hold old proxies to the service that were created on a previous run will not be able to interact with the service through those old proxies; effectively making the restarted service useless to those clients. A proxy that was created on a previous run cannot be used to communicate with the restarted service because such a proxy is associated with an old object ID, produced when the service was previously exported; whereas the restarted service will be associated with a new, different object ID, produced when the service is re-exported during the restart. Note that this will be true even if the service is re-exported on the same port.

The reason the restarted service cannot be re-exported with the object ID from its previous run is that when a service is configured to use JRMP, the service is exported using a {@link net.jini.jrmp.JrmpExporter}, and such an exporter cannot be created with a pre-specified object ID. Thus, although the old object ID could be recovered from persisted state when the service is restarted, there is no way to re-export the service (under JRMP) with that old object ID. And so a new object ID is assigned to the service's inner proxy every time the service is restarted. To address this, one might argue that clients could always obtain a new service proxy (containing the new inner proxy with the new object ID) simply by re-querying the lookup service. But this only addresses primary proxies to the service; it doesn't address secondary proxies such as leases the service had issued to its clients on previous runs. Any such leases would no longer be valid, and so each client would need to re-register with the restarted service through the new primary proxy to obtain new leases. From the point of view of the client then, it would be as if the service was started anew.

Note that for nonactivatable, persistent services that are exported using Jini ERI, the above situation can be avoided. Jini ERI allows the service to be configured to always be exported on the same port, with the same object ID (see the `JERI/Nonactivatable` example configuration below). Thus, any primary or secondary proxies a client holds that are from a prior run of the service, can still be used to communicate with the service when the service is restarted.

Also note that the situation described above for nonactivatable, persistent services exported under JRMP does not affect services that are registered with an activation system (that is, services that are activatable); and this holds for services exported under either JRMP or Jini ERI. This is because the activation mechanism provided in Java Remote Method Invocation (Java RMI) provides for persistent references; that is, remote references that remain valid after the service has crashed and been restarted. For more details, see the `"Note on RMI Activation"`.

Finally, recall that a primary purpose for persisting state is so that the service can recover that state and pick up where it left off when restarted. For the reasons described above, when a service is configured to be persistent but nonactivatable, and is also configured to be exported using JRMP, that purpose cannot be achieved. Therefore, the use of such a configuration is strongly discouraged. With this in mind, the following guidelines should be considered when deciding how to configure a service with respect to mode, communication framework, and transport:

- If state recovery is not important, then the service should be configured for the transient mode using the communication framework and transport of choice.
- If state recovery is important, but JRMP is not necessary, then the service should be configured for the mode of choice, but the communication framework should be Jini ERI with the transport of choice.
- If both state recovery and JRMP are necessary, then the service should be configured to be activatable. That is, the only way to get persistent, valid JRMP references is when the service is activatable.

### Nonactivatable Mode using Jini ERI

The following command will start Fiddler in nonactivatable mode using Jini ERI for remote communication. This configuration of Fiddler will persist its state information, but it will not be restarted by the activation system upon a system crash or failure. In order to recover its state and "pick up where it left off", the service must be restarted either manually, or by some means other than Java RMI activation (for example, some sort of script that auto-starts the service on system recovery).

#### Command Line

>     java_install_dir/bin/java \
>       -Djava.security.manager= \
>       -Djava.security.policy=example_install_dir/policy/jeri-start-nonactivatable.policy \
>         -jar jini_install_dir/lib/start.jar \
>                example_install_dir/config/jeri-start-nonactivatable.config

#### Starter Configuration: example_install_dir/config/jeri-start-nonactivatable.config

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

>     org.apache.river.start {

>         private static serviceCodebase   = new String("http://myHost:8080/fiddler-dl.jar http://myHost:8080/jsk-dl.jar");
>         private static servicePolicyFile = new String("example_install_dir${/}policy${/}jeri-nonactivatable-fiddler.policy");
>         private static serviceClasspath  = new String("jini_install_dir${/}lib${/}fiddler.jar");
>         private static serviceImplName   = new String("org.apache.river.fiddler.NonActivatableFiddlerImpl");
>         private static serviceConfig     = new String("example_install_dir${/}config${/}jeri-nonactivatable-fiddler.config");
>         private static serviceArgsArray  = new String[] { serviceConfig };

>         private static nonActivatableServiceDescriptor =
>                        new NonActivatableServiceDescriptor(serviceCodebase,
>                                                            servicePolicyFile,
>                                                            serviceClasspath,
>                                                            serviceImplName,
>                                                            serviceArgsArray);
>         static serviceDescriptors =
>                      new ServiceDescriptor[] { nonActivatableServiceDescriptor };

>     }//end org.apache.river.start

#### Service Configuration: example_install_dir/config/jeri-nonactivatable-fiddler.config

Note that there is nothing special about the values specified for the `objPort` and `objId` configuration entries in the example configuration file shown below. For both entries, fixed arbitrarily chosen values are specified. What's important is that neither the port nor the object ID is changed if the service is restarted. For a more detailed explanation of why this is important, see the respective notes accompanying the `JERI/Transient` example and the `JRMP/Nonactivatable` explanation.

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

>     org.apache.river.fiddler {

>         private invocationLayerFactory = new BasicILFactory();

>         private objPort = 19999;
>         private objId = UuidFactory.create("17ac4cdc-375a-9acc-1026-da040656ffbb");

>         serverExporter = new BasicJeriExporter
>                                          (TcpServerEndpoint.getInstance(objPort),
>                                           invocationLayerFactory,
>                                           false,
>                                           true,
>                                           objId);

>         initialLookupGroups = new String[] {"myGroup.myCompany.com"};
>         persistenceDirectory = new String("${java.io.tmpdir}jeri-fiddler-log");

>     }//end org.apache.river.fiddler

#### Starter Security Policy: example_install_dir/policy/jeri-start-nonactivatable.policy

>     grant codebase "file:jini_install_dir/lib/jsk-platform.jar" {
>         permission java.security.AllPermission;
>     };

>     grant codebase "file:${java.class.path}" {
>         permission java.security.AllPermission;
>     };

#### Service Security: example_install_dir/policy/jeri-nonactivatable-fiddler.policy

>     grant codebase "file:jini_install_dir/lib/jsk-lib.jar" {
>         permission java.security.AllPermission;
>     };

>     grant codeBase "file:jini_install_dir/lib/fiddler.jar" {
>         permission java.security.AllPermission;
>     };

### Phoenix using JRMP

In order to run Fiddler in any of the activatable configurations, an activation system must be running on the same host as Fiddler. Phoenix is the name of the implementation of the activation system provided with the Apache River release. Because Phoenix is configurable and supports the desired communication mechanisms, that implementation is presented with the activatable configurations of Fiddler that follow. (For more information and examples on Phoenix, refer to the Phoenix documentation `here`.)

The following commands will, respectively, start and stop Phoenix when using JRMP for remote communication.

#### Command Line

>     java_install_dir/bin/java \
>       -Djava.security.manager= \
>       -Djava.security.policy=example_install_dir/policy/jrmp-phoenix.policy \
>       -Djava.rmi.server.codebase="http://myHost:8080/phoenix-dl.jar http://myHost:8080/jsk-dl.jar" \
>         -jar jini_install_dir/lib/phoenix.jar \
>                example_install_dir/config/jrmp-phoenix.config

>     java_install_dir/bin/java \
>       -Djava.security.manager= \
>       -Djava.security.policy=example_install_dir/policy/jrmp-phoenix.policy \
>       -Djava.rmi.server.codebase="http://myHost:8080/phoenix-dl.jar http://myHost:8080/jsk-dl.jar" \
>         -jar jini_install_dir/lib/phoenix.jar \
>                -stop \
>                example_install_dir/config/jrmp-phoenix.config

#### Phoenix Configuration: example_install_dir/config/jrmp-phoenix.config

>     import org.apache.river.phoenix.ActivatorSunJrmpExporter;
>     import org.apache.river.phoenix.MonitorAccessExporter;
>     import org.apache.river.phoenix.RegistrySunExporter;
>     import org.apache.river.phoenix.SystemAccessExporter;

>     org.apache.river.phoenix {

>         registryExporter = new RegistrySunExporter();
>         systemExporter = new SystemAccessExporter();
>         activatorExporter = new ActivatorSunJrmpExporter();
>         monitorExporter = new MonitorAccessExporter();
>         groupConfig = new String[] { "example_install_dir${/}config${/}jrmp-phoenix-group.config" };
>         groupTimeout = 1800000;
>         persistenceDirectory = new String("${java.io.tmpdir}jrmp-phoenix-log");

>     }//end org.apache.river.phoenix

#### Phoenix Activation Group Configuration: example_install_dir/config/jrmp-phoenix-group.config

This configuration file specifies the entries used to configure the activation group VM that is spawned by Phoenix. The Phoenix activation group exports one remote object: the activation instantiator.

>     import org.apache.river.phoenix.InstantiatorAccessExporter;

>     org.apache.river.phoenix {

>         instantiatorExporter = new InstantiatorAccessExporter();

>     }//end org.apache.river.phoenix

#### Phoenix Security Policy: example_install_dir/policy/jrmp-phoenix.policy

>     grant codebase "file:jini_install_dir/lib/jsk-platform.jar" {
>         permission java.security.AllPermission;
>     };

>     grant codebase "file:jini_install_dir/lib/jsk-lib.jar" {
>         permission java.security.AllPermission;
>     };

>     grant codeBase "file:${java.class.path}" {
>         permission java.security.AllPermission;
>     };

>     grant codebase "file:jini_install_dir/lib/phoenix-group.jar" {
>         permission java.security.AllPermission;
>     };

>     grant {
>         /* Remote methods to allow to be invoked */
>         permission org.apache.river.phoenix.SystemPermission "registerGroup";
>         permission org.apache.river.phoenix.SystemPermission "registerObject";
>         permission org.apache.river.phoenix.SystemPermission "unregisterGroup";
>         permission org.apache.river.phoenix.SystemPermission "unregisterObject";
>         permission org.apache.river.phoenix.MonitorPermission "*";

>         /* System Properties to allow to be set on all VMs */
>         permission org.apache.river.phoenix.ExecOptionPermission "-classpath";
>         permission org.apache.river.phoenix.ExecOptionPermission "-cp";

>         permission org.apache.river.phoenix.ExecOptionPermission "-Djava.security.manager=";
>         permission org.apache.river.phoenix.ExecOptionPermission "-Djava.security.debug=all";
>         permission org.apache.river.phoenix.ExecOptionPermission "-Djava.security.debug=access,failure";
>         permission org.apache.river.phoenix.ExecOptionPermission "-Djava.security.debug=policy,access,failure";

>         permission org.apache.river.phoenix.ExecOptionPermission "jini_install_dir${/}lib${/}sharedvm.jar";

>         permission org.apache.river.phoenix.ExecOptionPermission "-Djava.security.policy=example_install_dir${/}policy${/}policy.all";
>         permission org.apache.river.phoenix.ExecOptionPermission "-Djava.security.policy=example_install_dir${/}policy${/}jrmp-sharedvm.policy";

>         /* System Properties for Fiddler Activatable Object */
>         permission org.apache.river.phoenix.ExecOptionPermission "jini_install_dir${/}lib${/}fiddler.jar";
>         permission org.apache.river.phoenix.ExecOptionPermission "-Djava.security.policy=example_install_dir${/}policy${/}jrmp-activatable-fiddler.policy";
>         permission org.apache.river.phoenix.ExecOptionPermission "-Djava.rmi.server.codebase=http://myHost:8080/fiddler-dl.jar http://myHost:8080/jsk-dl.jar";
>         permission org.apache.river.phoenix.ExecOptionPermission "-DserviceConfig=example_install_dir${/}config${/}jrmp-activatable-fiddler.config";
>         permission org.apache.river.phoenix.ExecOptionPermission "-DserviceClasspath=jini_install_dir${/}lib${/}fiddler.jar";
>     };

### Activatable Mode using JRMP

The first command shown below will start Fiddler in activatable mode using JRMP for remote communication. This configuration of Fiddler will persist its state information, and it will be restarted by the activation system upon a system crash or failure.

The second command will destroy the shared VM in which Fiddler (and possibly other services) are running. That command will remove the shared VM log directories, but will not remove any service-specific persistence directories. Typically, this command is executed only after all services executing in the shared VM have been gracefully (administratively) shutdown.

#### Command Line

>     java_install_dir/bin/java \
>       -Djava.security.manager= \
>       -Djava.security.policy=example_install_dir/policy/jrmp-start-activatable.policy \
>         -jar jini_install_dir/lib/start.jar \
>                example_install_dir/config/jrmp-start-activatable.config

>     java_install_dir/bin/java \
>       -Djava.security.manager= \
>       -Djava.security.policy=example_install_dir/policy/jrmp-start-activatable.policy \
>         -jar jini_install_dir/lib/destroy.jar \
>                example_install_dir/config/jrmp-start-activatable.config

#### Starter Configuration: example_install_dir/config/jrmp-start-activatable.config

>     import org.apache.river.start.ServiceDescriptor;
>     import org.apache.river.start.SharedActivatableServiceDescriptor;
>     import org.apache.river.start.SharedActivationGroupDescriptor;
>     import net.jini.security.BasicProxyPreparer;

>     org.apache.river.start {

>         activationSystemPreparer = new BasicProxyPreparer();

>         private static sharedVMPolicyFile = new String("example_install_dir${/}policy${/}jrmp-sharedvm.policy");
>         private static sharedVMClasspath  = new String("jini_install_dir${/}lib${/}sharedvm.jar");

>         private static groupCodebase   = new String("http://myHost:8080/group-dl.jar");
>         private static groupPolicyFile = new String("example_install_dir${/}policy${/}jrmp-sharedvm.policy");
>         private static groupClasspath  = new String("jini_install_dir${/}lib${/}group.jar");
>         private static groupImplName   = new String("org.apache.river.start.SharedGroupImpl");
>         private static groupArgsArray  = new String[] { "example_install_dir${/}config${/}jrmp-destroyGroup.config" };

>         private static serviceCodebase   = new String("http://myHost:8080/fiddler-dl.jar http://myHost:8080/jsk-dl.jar");
>         private static servicePolicyFile = new String("example_install_dir${/}policy${/}jrmp-activatable-fiddler.policy");
>         private static serviceClasspath  = new String("jini_install_dir${/}lib${/}fiddler.jar");
>         private static serviceImplName   = new String("org.apache.river.fiddler.ActivatableFiddlerImpl");
>         private static serviceConfig     = new String("example_install_dir${/}config${/}jrmp-activatable-fiddler.config");
>         private static serviceArgsArray  = new String[] { serviceConfig };

>         private static sharedVMDir = "${java.io.tmpdir}jrmp-sharedvm-log";

>         private static serverCommand    = null;
>         private static serverOptions    = null;
>         private static serverProperties =
>                          new String[] { "serviceClasspath", serviceClasspath,
>                                         "serviceConfig",    serviceConfig };
>         private registryHost = "myHost";
>         private registryPort = 1098;

>         private static sharedActivationGroupDescriptor =
>                        new SharedActivationGroupDescriptor(sharedVMPolicyFile,
>                                                            sharedVMClasspath,
>                                                            sharedVMDir,
>                                                            serverCommand,
>                                                            serverOptions,
>                                                            serverProperties,
>                                                            registryHost,
>                                                            registryPort );
>         private static destroySharedGroupDescriptor =
>                        new SharedActivatableServiceDescriptor(groupCodebase,
>                                                               groupPolicyFile,
>                                                               groupClasspath,
>                                                               groupImplName,
>                                                               sharedVMDir,
>                                                               groupArgsArray,
>                                                               false,
>                                                               registryHost,
>                                                               registryPort );
>         private static activatableServiceDescriptor =
>                        new SharedActivatableServiceDescriptor(serviceCodebase,
>                                                               servicePolicyFile,
>                                                               serviceClasspath,
>                                                               serviceImplName,
>                                                               sharedVMDir,
>                                                               serviceArgsArray,
>                                                               true,
>                                                               registryHost,
>                                                               registryPort );
>         static serviceDescriptors =
>                new ServiceDescriptor[] { sharedActivationGroupDescriptor,
>                                          activatableServiceDescriptor };
>         static serviceDestructors =
>                new ServiceDescriptor[] { destroySharedGroupDescriptor };

>     }//end org.apache.river.start

#### Service Configuration: example_install_dir/config/jrmp-activatable-fiddler.config

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

>     org.apache.river.fiddler {

>         serverExporter = new JrmpExporter( (ActivationID)$data, 0 );

>         activationSystemPreparer = new BasicProxyPreparer();
>         activationIdPreparer = new BasicProxyPreparer();

>         initialLookupGroups = new String[] {"myGroup.myCompany.com"};
>         persistenceDirectory = new String("${java.io.tmpdir}jrmp-fiddler-log");

>     }//end org.apache.river.fiddler

#### Service Configuration: example_install_dir/config/jrmp-destroyGroup.config

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

>     org.apache.river.start {

>         exporter = new JrmpExporter( (ActivationID)$data,0 );
>         activationSystemPreparer = new BasicProxyPreparer();

>     }//end org.apache.river.start

#### Starter Security Policy: example_install_dir/policy/jrmp-start-activatable.policy

>     grant codebase "file:jini_install_dir/lib/jsk-platform.jar" {
>         permission java.security.AllPermission;
>     };

>     grant codebase "file:${java.class.path}" {
>         permission java.security.AllPermission;
>     };

#### Service Security: example_install_dir/policy/jrmp-activatable-fiddler.policy

>     grant codebase "file:jini_install_dir/lib/jsk-lib.jar" {
>         permission java.security.AllPermission;
>     };

>     grant codeBase "file:jini_install_dir/lib/fiddler.jar" {
>         permission java.security.AllPermission;
>     };

#### Service Security: example_install_dir/policy/jrmp-sharedvm.policy

>     grant codebase "file:jini_install_dir/lib/jsk-platform.jar" {
>         permission java.security.AllPermission;
>     };

>     grant codebase "file:jini_install_dir/lib/jsk-lib.jar" {
>         permission java.security.AllPermission;
>     };

>     grant codebase "file:jini_install_dir/lib/phoenix-init.jar" {
>         permission java.security.AllPermission;
>     };

>     grant codebase "file:jini_install_dir/lib/phoenix-group.jar" {
>         permission java.security.AllPermission;
>     };

>     grant codebase "file:${java.class.path}" {
>         permission java.security.AllPermission;
>     };

>     grant codebase "file:jini_install_dir/lib/group.jar" {
>         permission java.security.AllPermission;
>     };

>     grant codebase "file:jini_install_dir/lib/fiddler.jar" {
>         permission java.security.AllPermission;
>     };

### Phoenix using Jini ERI

The following commands will, respectively, start and stop Phoenix when using Jini ERI for remote communication.

#### Command Line

>     java_install_dir/bin/java \
>       -Djava.security.manager= \
>       -Djava.security.policy=example_install_dir/policy/jeri-phoenix.policy \
>       -Djava.rmi.server.codebase="http://myHost:8080/phoenix-dl.jar http://myHost:8080/jsk-dl.jar" \
>         -jar jini_install_dir/lib/phoenix.jar \
>                example_install_dir/config/jeri-phoenix.config

>     java_install_dir/bin/java \
>       -Djava.security.manager= \
>       -Djava.security.policy=example_install_dir/policy/jeri-phoenix.policy \
>       -Djava.rmi.server.codebase="http://myHost:8080/phoenix-dl.jar http://myHost:8080/jsk-dl.jar" \
>         -jar jini_install_dir/lib/phoenix.jar \
>                -stop \
>                example_install_dir/config/jeri-phoenix.config

#### Phoenix Configuration: example_install_dir/config/jeri-phoenix.config

>     import org.apache.river.phoenix.AccessILFactory;
>     import org.apache.river.phoenix.PhoenixConstants;
>     import org.apache.river.phoenix.RegistrySunExporter;
>     import org.apache.river.phoenix.SystemAccessILFactory;

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

>     org.apache.river.phoenix {

>         registryExporter = new RegistrySunExporter();

>         private jeriPort = 2000; //cannot be 1098
>         private serverEndpoint = TcpServerEndpoint.getInstance(jeriPort);

>         systemExporter = new BasicJeriExporter
>                                        (serverEndpoint,
>                                         new SystemAccessILFactory(),
>                                         false,
>                                         true,
>                                         PhoenixConstants.ACTIVATION_SYSTEM_UUID);

>         activatorExporter = new BasicJeriExporter(serverEndpoint,
>                                                   new BasicILFactory(),
>                                                   false,
>                                                   true,
>                                                   PhoenixConstants.ACTIVATOR_UUID);

>         private invocationLayerFactory = new AccessILFactory();
>         monitorExporter = new BasicJeriExporter(serverEndpoint,
>                                                 invocationLayerFactory,
>                                                 false,
>                                                 true);

>         groupConfig = new String[] { "example_install_dir${/}config${/}jeri-phoenix-group.config" };
>         groupTimeout = 1800000;
>         persistenceDirectory = new String("${java.io.tmpdir}jeri-phoenix-log");

>     }//end org.apache.river.phoenix

#### Phoenix Activation Group Configuration: example_install_dir/config/jeri-phoenix-group.config

>     import org.apache.river.phoenix.AccessILFactory;
>     import net.jini.jeri.BasicJeriExporter;
>     import net.jini.jeri.tcp.TcpServerEndpoint;

>     org.apache.river.phoenix {

>         private invocationLayerFactory = new AccessILFactory();
>         instantiatorExporter = new BasicJeriExporter
>                                                 (TcpServerEndpoint.getInstance(0),
>                                                  invocationLayerFactory,
>                                                  false,
>                                                  true);
>     }//end org.apache.river.phoenix

#### Phoenix Security Policy: example_install_dir/policy/jeri-phoenix.policy

>     grant codebase "file:jini_install_dir/lib/jsk-platform.jar" {
>         permission java.security.AllPermission;
>     };

>     grant codebase "file:jini_install_dir/lib/jsk-lib.jar" {
>         permission java.security.AllPermission;
>     };

>     grant codeBase "file:${java.class.path}" {
>         permission java.security.AllPermission;
>     };

>     grant codebase "file:jini_install_dir/lib/phoenix-group.jar" {
>         permission java.security.AllPermission;
>     };

>     grant {
>         /* Remote methods to allow to be invoked */
>         permission org.apache.river.phoenix.SystemPermission "registerGroup";
>         permission org.apache.river.phoenix.SystemPermission "registerObject";
>         permission org.apache.river.phoenix.SystemPermission "unregisterGroup";
>         permission org.apache.river.phoenix.SystemPermission "unregisterObject";
>         permission org.apache.river.phoenix.MonitorPermission "*";

>         /* System Properties to allow to be set on all VMs */
>         permission org.apache.river.phoenix.ExecOptionPermission "-classpath";
>         permission org.apache.river.phoenix.ExecOptionPermission "-cp";

>         permission org.apache.river.phoenix.ExecOptionPermission "-Djava.security.manager=";
>         permission org.apache.river.phoenix.ExecOptionPermission "-Djava.security.debug=all";
>         permission org.apache.river.phoenix.ExecOptionPermission "-Djava.security.debug=access,failure";
>         permission org.apache.river.phoenix.ExecOptionPermission "-Djava.security.debug=policy,access,failure";

>         permission org.apache.river.phoenix.ExecOptionPermission "jini_install_dir${/}lib${/}sharedvm.jar";

>         permission org.apache.river.phoenix.ExecOptionPermission "-Djava.security.policy=example_install_dir${/}policy${/}policy.all";
>         permission org.apache.river.phoenix.ExecOptionPermission "-Djava.security.policy=example_install_dir${/}policy${/}jeri-sharedvm.policy";

>         /* System Properties for Fiddler Activatable Object */
>         permission org.apache.river.phoenix.ExecOptionPermission "jini_install_dir${/}lib${/}fiddler.jar";
>         permission org.apache.river.phoenix.ExecOptionPermission "-Djava.security.policy=example_install_dir${/}policy${/}jeri-activatable-fiddler.policy";
>         permission org.apache.river.phoenix.ExecOptionPermission "-Djava.rmi.server.codebase=http://myHost:8080/fiddler-dl.jar http://myHost:8080/jsk-dl.jar";
>         permission org.apache.river.phoenix.ExecOptionPermission "-DserviceConfig=example_install_dir${/}config${/}jeri-activatable-fiddler.config";
>         permission org.apache.river.phoenix.ExecOptionPermission "-DserviceClasspath=jini_install_dir${/}lib${/}fiddler.jar";
>     };

### Activatable Mode using Jini ERI

The first command shown below will start Fiddler in activatable mode using Jini ERI for remote communication. This configuration of Fiddler will persist its state information, and it will be restarted by the activation system upon a system crash or failure.

The second command will destroy the shared VM in which Fiddler (and possibly other services) are running. That command will remove the shared VM log directories, but will not remove any service-specific persistence directories. Typically, this command is executed only after all services executing in the shared VM have been gracefully (administratively) shutdown.

#### Command Line

>     java_install_dir/bin/java \
>       -Djava.security.manager= \
>       -Djava.security.policy=example_install_dir/policy/jeri-start-activatable.policy \
>         -jar jini_install_dir/lib/start.jar \
>                example_install_dir/config/jeri-start-activatable.config

>     java_install_dir/bin/java \
>       -Djava.security.manager= \
>       -Djava.security.policy=example_install_dir/policy/jeri-start-activatable.policy \
>         -jar jini_install_dir/lib/destroy.jar \
>                example_install_dir/config/jeri-start-activatable.config

#### Starter Configuration: example_install_dir/config/jeri-start-activatable.config

>     import org.apache.river.start.ServiceDescriptor;
>     import org.apache.river.start.SharedActivatableServiceDescriptor;
>     import org.apache.river.start.SharedActivationGroupDescriptor;
>     import net.jini.security.BasicProxyPreparer;

>     org.apache.river.start {

>         activationSystemPreparer = new BasicProxyPreparer();

>         private static sharedVMPolicyFile = new String("example_install_dir${/}policy${/}jeri-sharedvm.policy");
>         private static sharedVMClasspath  = new String("jini_install_dir${/}lib${/}sharedvm.jar");

>         private static groupCodebase   = new String("http://myHost:8080/group-dl.jar");
>         private static groupPolicyFile = new String("example_install_dir${/}policy${/}jeri-sharedvm.policy");
>         private static groupClasspath  = new String("jini_install_dir${/}lib${/}group.jar");
>         private static groupImplName   = new String("org.apache.river.start.SharedGroupImpl");
>         private static groupArgsArray  = new String[] { "example_install_dir${/}config${/}jeri-destroyGroup.config" };

>         private static serviceCodebase   = new String("http://myHost:8080/fiddler-dl.jar http://myHost:8080/jsk-dl.jar");
>         private static servicePolicyFile = new String("example_install_dir${/}policy${/}jeri-activatable-fiddler.policy");
>         private static serviceClasspath  = new String("jini_install_dir${/}lib${/}fiddler.jar");
>         private static serviceImplName   = new String("org.apache.river.fiddler.ActivatableFiddlerImpl");
>         private static serviceConfig     = new String("example_install_dir${/}config${/}jeri-activatable-fiddler.config");
>         private static serviceArgsArray  = new String[] { serviceConfig };

>         private static sharedVMDir = "${java.io.tmpdir}jeri-sharedvm-log";

>         private static serverCommand    = null;
>         private static serverOptions    = null;
>         private static serverProperties =
>                          new String[] { "serviceClasspath", serviceClasspath,
>                                         "serviceConfig",    serviceConfig };
>         private registryHost = "myHost";
>         private registryPort = 1098;

>         private static sharedActivationGroupDescriptor =
>                        new SharedActivationGroupDescriptor(sharedVMPolicyFile,
>                                                            sharedVMClasspath,
>                                                            sharedVMDir,
>                                                            serverCommand,
>                                                            serverOptions,
>                                                            serverProperties,
>                                                            registryHost,
>                                                            registryPort );
>         private static destroySharedGroupDescriptor =
>                        new SharedActivatableServiceDescriptor(groupCodebase,
>                                                               groupPolicyFile,
>                                                               groupClasspath,
>                                                               groupImplName,
>                                                               sharedVMDir,
>                                                               groupArgsArray,
>                                                               false,
>                                                               registryHost,
>                                                               registryPort );
>         private static activatableServiceDescriptor =
>                        new SharedActivatableServiceDescriptor(serviceCodebase,
>                                                               servicePolicyFile,
>                                                               serviceClasspath,
>                                                               serviceImplName,
>                                                               sharedVMDir,
>                                                               serviceArgsArray,
>                                                               true,
>                                                               registryHost,
>                                                               registryPort );
>         static serviceDescriptors =
>                new ServiceDescriptor[] { sharedActivationGroupDescriptor,
>                                          activatableServiceDescriptor };
>         static serviceDestructors =
>                new ServiceDescriptor[] { destroySharedGroupDescriptor };

>     }//end org.apache.river.start

#### Service Configuration: example_install_dir/config/jeri-activatable-fiddler.config

>     import net.jini.activation.ActivationExporter;
>     import net.jini.jeri.BasicILFactory;
>     import net.jini.jeri.BasicJeriExporter;
>     import net.jini.jeri.tcp.TcpServerEndpoint;
>     import net.jini.security.BasicProxyPreparer;
>     import java.rmi.activation.ActivationID;

>     org.apache.river.fiddler {

>         private invocationLayerFactory = new BasicILFactory();
>         private underlyingExporter =
>                     new BasicJeriExporter(TcpServerEndpoint.getInstance(0),
>                                           invocationLayerFactory,
>                                           false,
>                                           true);
>         serverExporter = new ActivationExporter((ActivationID)$data,
>                                                 underlyingExporter);

>         activationSystemPreparer = new BasicProxyPreparer();
>         activationIdPreparer = new BasicProxyPreparer();

>         initialLookupGroups = new String[] {"myGroup.myCompany.com"};
>         persistenceDirectory = new String("${java.io.tmpdir}jeri-fiddler-log");

>     }//end org.apache.river.fiddler

#### Service Configuration: example_install_dir/config/jeri-destroyGroup.config

>     import net.jini.jeri.BasicILFactory;
>     import net.jini.jeri.BasicJeriExporter;
>     import net.jini.jeri.tcp.TcpServerEndpoint;
>     import net.jini.security.BasicProxyPreparer;

>     org.apache.river.start {

>         exporter = new BasicJeriExporter(TcpServerEndpoint.getInstance(0),
>                                          new BasicILFactory(),
>                                          false,
>                                          true);

>         activationSystemPreparer = new BasicProxyPreparer();

>     }//end org.apache.river.start

#### Starter Security Policy: example_install_dir/policy/jeri-start-activatable.policy

>     grant codebase "file:jini_install_dir/lib/jsk-platform.jar" {
>         permission java.security.AllPermission;
>     };

>     grant codebase "file:${java.class.path}" {
>         permission java.security.AllPermission;
>     };

#### Service Security: example_install_dir/policy/jeri-activatable-fiddler.policy

>     grant codebase "file:jini_install_dir/lib/jsk-lib.jar" {
>         permission java.security.AllPermission;
>     };

>     grant codeBase "file:jini_install_dir/lib/fiddler.jar" {
>         permission java.security.AllPermission;
>     };

#### Service Security: example_install_dir/policy/jeri-sharedvm.policy

>     grant codebase "file:jini_install_dir/lib/jsk-platform.jar" {
>         permission java.security.AllPermission;
>     };

>     grant codebase "file:jini_install_dir/lib/jsk-lib.jar" {
>         permission java.security.AllPermission;
>     };

>     grant codebase "file:jini_install_dir/lib/phoenix-init.jar" {
>         permission java.security.AllPermission;
>     };

>     grant codebase "file:jini_install_dir/lib/phoenix-group.jar" {
>         permission java.security.AllPermission;
>     };

>     grant codebase "file:${java.class.path}" {
>         permission java.security.AllPermission;
>     };

>     grant codebase "file:jini_install_dir/lib/group.jar" {
>         permission java.security.AllPermission;
>     };

>     grant codebase "file:jini_install_dir/lib/fiddler.jar" {
>         permission java.security.AllPermission;
>     };

@see net.jini.discovery.LookupDiscoveryService