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 com.sun.jini.fiddler.FiddlerImpl}. Those proxy classes are:

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 com.sun.jini.fiddler.Fiddler} interface, is implemented in {@link com.sun.jini.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:

This document provides the following information about 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 com.sun.jini.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 com.sun.jini.fiddler.FiddlerAdmin} interface. During startup, and upon any change through com.sun.jini.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 com.sun.jini.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 com.sun.jini.fiddler.FiddlerAdmin} interface. During startup, and upon any change through com.sun.jini.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 com.sun.jini.fiddler.FiddlerAdmin} interface. During startup, and upon any change through com.sun.jini.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 com.sun.jini.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.
taskManager
  Type: {@link com.sun.jini.thread.TaskManager}
  Default: new {@link com.sun.jini.thread.TaskManager#TaskManager() TaskManager}(10, (15*1000), 1.0f)
  Description: The object that pools and manages the various threads executed by this implementation of the service. The default manager creates a maximum of 10 threads, waits 15 seconds before removing idle threads, and uses a load factor of 1.0 when determining whether to create a new thread.

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.

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 com.sun.jini.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 com.sun.jini.fiddler.FiddlerAdmin#setLeaseBound FiddlerAdmin.setLeaseBound} setLeaseBound
{@link com.sun.jini.fiddler.FiddlerAdmin#getLeaseBound FiddlerAdmin.getLeaseBound} getLeaseBound
{@link com.sun.jini.fiddler.FiddlerAdmin#setPersistenceSnapshotWeight FiddlerAdmin.setPersistenceSnapshotWeight} setPersistenceSnapshotWeight
{@link com.sun.jini.fiddler.FiddlerAdmin#getPersistenceSnapshotWeight FiddlerAdmin.getPersistenceSnapshotWeight} getPersistenceSnapshotWeight
{@link com.sun.jini.fiddler.FiddlerAdmin#setPersistenceSnapshotThreshold FiddlerAdmin.setPersistenceSnapshotThreshold} setPersistenceSnapshotThreshold
{@link com.sun.jini.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 com.sun.jini.admin.DestroyAdmin#destroy DestroyAdmin.destroy} destroy
{@link net.jini.security.proxytrust.ProxyTrust#getProxyVerifier ProxyTrust.getProxyVerifier} getProxyVerifier
{@link com.sun.jini.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, com.sun.jini.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.

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:

com.sun.jini.fiddler.discard
Level Description
{@link java.util.logging.Level#FINE FINE} trace information related to lookup services that are discarded by this service

com.sun.jini.fiddler.events
Level Description
{@link java.util.logging.Level#FINE FINE} trace information related to events sent or received by this service

com.sun.jini.fiddler.groups
Level Description
{@link java.util.logging.Level#FINER FINER} trace information related to the groups this service is attempting to discover

com.sun.jini.fiddler.lease
Level Description
{@link java.util.logging.Level#FINER FINER} trace information related to the leases granted or received by this service

com.sun.jini.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

com.sun.jini.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

com.sun.jini.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 com.sun.jini.logging.Levels#FAILED FAILED} exceptions that occur while retrieving the locator of a discovered lookup service
{@link com.sun.jini.logging.Levels#HANDLED HANDLED} problems that occur while attempting to prepare locators or log information about events the service sends

com.sun.jini.fiddler.registration
Level Description
{@link java.util.logging.Level#FINER FINER} trace information related to the registrations granted by or to this service

com.sun.jini.fiddler.startup
Level Description
{@link java.util.logging.Level#INFO INFO} one time trace information, such as startup/deactivation/shutdown notices

com.sun.jini.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 com.sun.jini.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:

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.

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 com.sun.jini.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:

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:

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:

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 com.sun.jini.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 com.sun.jini.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 com.sun.jini.start.NonActivatableServiceDescriptor;
import com.sun.jini.start.ServiceDescriptor;

com.sun.jini.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("com.sun.jini.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 com.sun.jini.start

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

import net.jini.jrmp.JrmpExporter;

com.sun.jini.fiddler {

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

}//end com.sun.jini.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 com.sun.jini.start.NonActivatableServiceDescriptor;
import com.sun.jini.start.ServiceDescriptor;

com.sun.jini.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("com.sun.jini.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 com.sun.jini.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;

com.sun.jini.fiddler {

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

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

}//end com.sun.jini.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:

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 com.sun.jini.start.NonActivatableServiceDescriptor;
import com.sun.jini.start.ServiceDescriptor;

com.sun.jini.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("com.sun.jini.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 com.sun.jini.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;

com.sun.jini.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 com.sun.jini.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 com.sun.jini.phoenix.ActivatorSunJrmpExporter;
import com.sun.jini.phoenix.MonitorAccessExporter;
import com.sun.jini.phoenix.RegistrySunExporter;
import com.sun.jini.phoenix.SystemAccessExporter;

com.sun.jini.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 com.sun.jini.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 com.sun.jini.phoenix.InstantiatorAccessExporter;

com.sun.jini.phoenix {

    instantiatorExporter = new InstantiatorAccessExporter();

}//end com.sun.jini.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 com.sun.jini.phoenix.SystemPermission "registerGroup";
    permission com.sun.jini.phoenix.SystemPermission "registerObject";
    permission com.sun.jini.phoenix.SystemPermission "unregisterGroup";
    permission com.sun.jini.phoenix.SystemPermission "unregisterObject";
    permission com.sun.jini.phoenix.MonitorPermission "*";

    /* System Properties to allow to be set on all VMs */
    permission com.sun.jini.phoenix.ExecOptionPermission "-classpath";
    permission com.sun.jini.phoenix.ExecOptionPermission "-cp";

    permission com.sun.jini.phoenix.ExecOptionPermission "-Djava.security.manager=";
    permission com.sun.jini.phoenix.ExecOptionPermission "-Djava.security.debug=all";
    permission com.sun.jini.phoenix.ExecOptionPermission "-Djava.security.debug=access,failure";
    permission com.sun.jini.phoenix.ExecOptionPermission "-Djava.security.debug=policy,access,failure";

    permission com.sun.jini.phoenix.ExecOptionPermission "jini_install_dir${/}lib${/}sharedvm.jar";

    permission com.sun.jini.phoenix.ExecOptionPermission "-Djava.security.policy=example_install_dir${/}policy${/}policy.all";
    permission com.sun.jini.phoenix.ExecOptionPermission "-Djava.security.policy=example_install_dir${/}policy${/}jrmp-sharedvm.policy";

    /* System Properties for Fiddler Activatable Object */
    permission com.sun.jini.phoenix.ExecOptionPermission "jini_install_dir${/}lib${/}fiddler.jar";
    permission com.sun.jini.phoenix.ExecOptionPermission "-Djava.security.policy=example_install_dir${/}policy${/}jrmp-activatable-fiddler.policy";
    permission com.sun.jini.phoenix.ExecOptionPermission "-Djava.rmi.server.codebase=http://myHost:8080/fiddler-dl.jar http://myHost:8080/jsk-dl.jar";
    permission com.sun.jini.phoenix.ExecOptionPermission "-DserviceConfig=example_install_dir${/}config${/}jrmp-activatable-fiddler.config";
    permission com.sun.jini.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 com.sun.jini.start.ServiceDescriptor;
import com.sun.jini.start.SharedActivatableServiceDescriptor;
import com.sun.jini.start.SharedActivationGroupDescriptor;
import net.jini.security.BasicProxyPreparer;

com.sun.jini.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("com.sun.jini.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("com.sun.jini.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 com.sun.jini.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;

com.sun.jini.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 com.sun.jini.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;

com.sun.jini.start {

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

}//end com.sun.jini.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 com.sun.jini.phoenix.AccessILFactory;
import com.sun.jini.phoenix.PhoenixConstants;
import com.sun.jini.phoenix.RegistrySunExporter;
import com.sun.jini.phoenix.SystemAccessILFactory;

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

com.sun.jini.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 com.sun.jini.phoenix

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

import com.sun.jini.phoenix.AccessILFactory;
import net.jini.jeri.BasicJeriExporter;
import net.jini.jeri.tcp.TcpServerEndpoint;

com.sun.jini.phoenix {

    private invocationLayerFactory = new AccessILFactory();
    instantiatorExporter = new BasicJeriExporter
                                            (TcpServerEndpoint.getInstance(0),
                                             invocationLayerFactory,
                                             false,
                                             true);
}//end com.sun.jini.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 com.sun.jini.phoenix.SystemPermission "registerGroup";
    permission com.sun.jini.phoenix.SystemPermission "registerObject";
    permission com.sun.jini.phoenix.SystemPermission "unregisterGroup";
    permission com.sun.jini.phoenix.SystemPermission "unregisterObject";
    permission com.sun.jini.phoenix.MonitorPermission "*";

    /* System Properties to allow to be set on all VMs */
    permission com.sun.jini.phoenix.ExecOptionPermission "-classpath";
    permission com.sun.jini.phoenix.ExecOptionPermission "-cp";

    permission com.sun.jini.phoenix.ExecOptionPermission "-Djava.security.manager=";
    permission com.sun.jini.phoenix.ExecOptionPermission "-Djava.security.debug=all";
    permission com.sun.jini.phoenix.ExecOptionPermission "-Djava.security.debug=access,failure";
    permission com.sun.jini.phoenix.ExecOptionPermission "-Djava.security.debug=policy,access,failure";

    permission com.sun.jini.phoenix.ExecOptionPermission "jini_install_dir${/}lib${/}sharedvm.jar";

    permission com.sun.jini.phoenix.ExecOptionPermission "-Djava.security.policy=example_install_dir${/}policy${/}policy.all";
    permission com.sun.jini.phoenix.ExecOptionPermission "-Djava.security.policy=example_install_dir${/}policy${/}jeri-sharedvm.policy";

    /* System Properties for Fiddler Activatable Object */
    permission com.sun.jini.phoenix.ExecOptionPermission "jini_install_dir${/}lib${/}fiddler.jar";
    permission com.sun.jini.phoenix.ExecOptionPermission "-Djava.security.policy=example_install_dir${/}policy${/}jeri-activatable-fiddler.policy";
    permission com.sun.jini.phoenix.ExecOptionPermission "-Djava.rmi.server.codebase=http://myHost:8080/fiddler-dl.jar http://myHost:8080/jsk-dl.jar";
    permission com.sun.jini.phoenix.ExecOptionPermission "-DserviceConfig=example_install_dir${/}config${/}jeri-activatable-fiddler.config";
    permission com.sun.jini.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 com.sun.jini.start.ServiceDescriptor;
import com.sun.jini.start.SharedActivatableServiceDescriptor;
import com.sun.jini.start.SharedActivationGroupDescriptor;
import net.jini.security.BasicProxyPreparer;

com.sun.jini.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("com.sun.jini.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("com.sun.jini.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 com.sun.jini.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;

com.sun.jini.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 com.sun.jini.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;

com.sun.jini.start {

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

    activationSystemPreparer = new BasicProxyPreparer();

}//end com.sun.jini.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