The Artima Developer Community
Sponsored Link

The Journal of Spontaneous Networking
Using Objects to Configure Jini Network Services
by John McClain
June 29, 2004

<<  Page 3 of 4  >>


Object-Oriented Service Configuration

While we could use Configuration to retrieve only simple primitive values, the config models power is more evident when we retrieve complete objects from a Configuration.

For instance, MyServiceImpl will need to find lookup services to register with. The service could obtain an array of group names and lookup locators from the configuration and use those to create a LookupDiscoveryManager. Alternatively, or we could specify an entire DiscoveryManagement object:

           DiscoveryManagement discoveryManager;
           try {
               discoveryManager = (DiscoveryManagement)config.getEntry(
                   "org.jini.user.jmcclain.myservice", // component
                   "discoveryManager",                 // name
                   DiscoveryManagement.class)          // type

               if (null == discoveryManager) {
                  throw new ConfigurationException("entry for component  " +
                      "org.jini.user.jmcclain.myservice, name " +
                      "discoveryManager must be non-null");
           } catch (NoSuchEntryException e) {
               // default value
               discoveryManager = new LookupDiscoveryManager(
                   new String[] {""}, null, null, config);

A ConfigurationFile source file that provided a value for discoveryManager might look something like this:

    import net.jini.core.discovery.LookupLocator;
    import net.jini.discovery.LookupDiscoveryManager;

    org.jini.user.jmcclain.myservice {
       discoveryManager = new LookupDiscoveryManager(
           new String{"", ""},
           new LookupLocator("", 4160),
           this); // the current config

Using the above configuration source file, discoveryManager would end up with a LookupDiscoveryManager that would discover lookups in the and groups plus any lookups on host using port 4160.

A few things to note about this example:

By retrieving a complete DiscoveryManagement object from the configuration, MyService gives the deployer a lot of control over what lookups the service will register with. The deployer can provide:

Configuration Strategies

As these two examples show, a configuration may contain errors: it may be missing entries that don't have defaults, or it could have values for all the entries, but one or more of them could be malformed. For that reason it is generally best for a module to retrieve all of its configuration entries early, usually in the constructor, so errors can be signaled early. That makes it easier for the deployer to debug her configuration.

That strategy should be followed even if the values of these entries are not going to be used immediately, or may not be used at all. If you know that a given entry is never going to be used (e.g. a persistence directory for a transient service) then skipping it is probably the right thing to do. Deferring the fetching of an entry may also be the right approach if the entry in question is expensive to create.

Once the service got hold of a DiscoveryManagement object, it can create its JoinManager. Ideally, instead of obtaining a DiscoveryManagement object from the configuration, the service would have retrieved JoinManager. However, JoinManager is not a good candidate for a Configuration entry. Unlike the DiscoveryManagement object, where the deployer is expected to have all the information to construct an instance, constructing a JoinManager requires both information the deployer will have (e.g. DiscoveryManagement object, LeaseRenewalManager, some of the attributes), as well as objects only the service knows about (e.g. the proxy, other attributes, ServiceID/ServiceID listener). As a result, the MyService implementation uses the following code:

            joinManager = new JoinManager(proxy, getAttributes(),
                serviceID, discoveryManager, null, config);

That above code passes the Configuration into JoinManager's constructor. What JoinManager does with that Configuration is application-specific. The JoinManager in the Sun-contributed JSK uses that object to obtain proxy preparers, a thread pool, a LeaseRenewalManager (since null was passed in for the leaseMgr parameter), a wakeup manager, and the number of retries to perform on various tasks. Had null been passed in for the discoveryMgr parameter, JoinManager would also obtain a DiscoveryManagement object from the Configuration.

<<  Page 3 of 4  >>

Sponsored Links

Copyright © 1996-2018 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use