Chapter 7: Leasing
Contents
Leasing is the mechanism used between applications to give access to resources over a period of time in an agreed manner.
Jan: As in other chapters, the preceding introduction should be expanded a bit, perhaps by moving a bit of the following introductory info into the introduction. If it isn’t too basic for the audience, an example of what might lease what from what might be useful. Andy
Requesting and Receiving Leases
Jan: I’ve revised this heading to contrast with the following level-one heading. Feel free to revise, but I think it is useful to have the heading indicate clearly what is being said about leases here. Andy
Leases are requested for a period of time. In distributed applications, there may be partial failures of the network or of components on this network. Leasing is a way for components to register that they are alive, but to ensure that they are “timed out” if they fail, are unreachable, etc. In Jini, one use of leasing is for a service to request that a copy be kept on a lookup service for a certain length of time for delivery to clients on request. The service requests a time in the ServiceRegistrar’s register()method. Two special values of the time are
*	Lease.ANY—the service lets the lookup service decide on the time
*	Lease.FOREVER—the request is for a lease that never expires
The lookup service acts as the granter of the lease and decides how long it will actually create the lease for. (The lookup service from Sun typically sets the lease time as only five minutes.) Once it has done that, it will attempt to ensure that the request is honored for that period of time. The lease is returned to the service and is accessible through the method getLease() of the ServiceRegistration object. These objects are shown in Figure 7.1.

Figure 7.1: Objects in a leased system
Jan: In other chapters you labeled the figures as “Service Locator” and “Service” or “Service Provider”. These should be kept consistent, so let me know if the preceding ones should be changed to match or not. Andy
Jan: What is the following code? There should be an introductory sentence that clearly explains what it is, and at present the only sentence that might serve that purpose is up above the figure, which makes the connection difficult to follow. Andy
ServiceRegistration reg = registrar.register();
Lease lease = reg.getLease();
The principal methods of the Lease object are these:
package net.jini.core;

public interface Lease {
    void cancel() throws
                  UnknownLeaseException,
                  java.rmi.RemoteException;
    long getExpiration();
    void renew(long duration) throws
                  LeaseDeniedException,
                  UnknownLeaseException,
                  java.rmi.RemoteException;
}
Jan: Following addition okay? I presume you are referring to a return value since there don’t seem to be any parameters for the method. Andy
The expiration value returned from getExpiration() is the time in milliseconds since the beginning of the epoch (the same as in System.currentTimeMillis()). To find the amount of time still remaining from the present, the current time can be subtracted from this, as follows:
long duration = lease.getExpiration() - System.currentTimeMillis();
Cancellation
A service can cancel its lease by using cancel(). The lease communicates back to the lease management system on the lookup service, which cancels storage of the service.
Expiration
Jan: In the third sentence below, you say “this would probably be impractical”. Why would it be impractical? Saying that it is “probably” impractical suggests that you aren’t entirely sure why, so the whole thing comes across as a rather half-hearted explanation. If you don’t know why the system was designed this way, it would be better just to say that that’s the way it is. Or if it would create a lot of unnecessary network traffic, or something like that, it would be clearer to say that. “Impractical” is rather vague. Andy
When a lease expires, it does so silently. That is, the lease granter (the lookup service) will not inform the lease holder (the service) that it has expired. While it might seem nice to get warning of a lease expiring so that it can be renewed, this would have to be done in advance of the expiration (“I’m just about to expire; please renew me quickly!”) and this would probably be impractical. 
Jan: And, in the second sentence below you refer to the “servis”. What is that? Should it be “service” or something else? I can’t find any reference to such a word elsewhere in the chapter. Andy
Jan: And what are the expiration time and the duration time? The duration time I presume is the parameter for the renew() method, shown earlier. I don’t see any expiration parameter anywhere. Is it the value returned by the getExpiration() method? In any case, it should be explained a little more. Andy
Jan: And, in the fourth and following sentences, you start referring to the renewal manager. What is this? It hasn’t been explained anywhere. And similarly, the listener hasn’t been mentioned yet in this chapter. And what does it mean if the listener is null? Andy
Instead, it is up to the service to call renew() before the lease expires if it wishes the lease to continue. The servis in milliseconds. The expiration time is since the epoch, whereas the duration time is measured from now. Generally leases will be renewed and the manager will function quietly. However, the lookup service may decide not to renew a lease and will cause an exception to be thrown. This will be caught by the renewal manager and will cause the listener’s notify() method to be called with a LeaseRenewalEvent as parameter, which will allow the application to take corrective action if its lease is denied. The listener may be null.
Jan: The renewFor method isn’t listed above. When you say “in Jini v1.0”, do you mean that it only existed in that version, or does it still exist now but you don’t need to be careful now? That should be made clearer. Andy
You have to be careful about setting the duration in renewFor() (in Jini v1.0). If you want the service to be registered forever, it is tempting to use Lease.FOREVER. However, the Jini 1.0 implementation just adds this to System.currentTimeMillis(), which overflows to a negative value that is not checked. As a result, it never does any renewals. You need to check that
duration + System.currentTimeMillis() > 0
before calling renewFor(). This is fixed in Jini 1.1. The renewUntil()method can use Lease.FOREVER with no problems.
Jan: The renewUntil() method isn’t listed above either. Is that an oversight? Andy
Granting and Handling Leases
The preceding discussion looked at leases from the side of the client that receives a lease and has to manage it. The converse of this is the agent that grants leases and has to manage things from its side. This is more advanced material that you can skip for now—it is not really needed until Chapter 14, “Remote Events.” An example of use is given in Chapter 13, “More Complex Examples.”
Jan: In the preceding sentence, an example of the use of what is given in Chapter 13? Andy
Jan: Following changes okay? Andy
Jan: And below you say “An object will want the remote service to keep “pinging” it periodically”. What object are you referring to? Since we are discussing lease-granting here, I’m guessing that you are referring to the objects that grant the leases, but that should be made a little clearer. Andy
A lease can be granted for almost any remote service—any one where one object wants to maintain information about another one that is not within the same virtual machine. As with other remote services, there are the added partial failure modes, such as network crash, remote service crash, timeouts, and so on. An object will want the remote service to keep “pinging” it periodically to say that it is still alive and that it wants the information kept. Without this periodic assurance, the object might conclude that the remote service has vanished or is somehow unreachable, and that it should discard the information about it.
Leases are a very general mechanism for allowing one service to have confidence in the existence of the other for a limited period. Because they are general, they allow for a great deal of flexibility in use. Because of the potential variety of services, some parts of the Jini lease mechanism cannot be specifically defined and must be left as interfaces for applications to fill in. This generality means that all of the details are not filled in for you, as your own requirements cannot be completely predicted in advance.
A lease is given as an interface, and any agent that wishes to grant leases must implement this interface. Jini provides two implementations, an AbstractLease and a subclass of this, a LandlordLease.
A main issue in implementing a particular lease class lies in setting a policy for handling the initial request for a lease period and in deciding what to do when a renewal request comes in. A couple of simple possibilities are these:
*	Always grant the requested time
*	Ignore the requested time and always grant a fixed time
Of course, there are many more possibilities based on the lessor’s expected time to live, system load, etc. There are other issues, though. Any particular lease will need a time-out mechanism. Also, a group of leases can be managed together, and this can reduce the amount of overhead involved in managing individual leases.
Abstract Lease
An abstract lease gives a basic implementation of a lease that can almost be used for simple leases. 
Warning: This class, and those that depend on it, are still not fully specified and may change in future versions of Jini.
package com.sun.jini.lease;

public abstract class AbstractLease implements Lease, java.io.Serializable {
    protected AbstractLease(long expiration);
    public long getExpiration();
    public int getSerialFormat();
    public void setSerialFormat(int format);
    public void renew(long duration);
    protected abstract long doRenew(long duration);
}
This class supplies straightforward implementations of much of the Lease interface, with three provisos: 
*	The constructor is protected, so that constructing a lease with a specified duration is devolved to a subclass. This means that lease duration policy must be set by this subclass. 
*	The renew() method calls into the abstract doRenew() method, again to force a subclass to implement a renewal policy. 
*	The Lease interface does not implement the cancel() method, so this must also be left to a subclass. 
So this class implements the easy things, and leaves all matters of policy to concrete subclasses.
Landlord Lease Package
Jan: I’ve revised some of the headings here and below, and I’ve changed some heading levels. Basically I’ve  clarified the headings by indicating whether the words are the names of classes, interfaces, etc. I’ve based this on the surrounding text, so please revise if I got anything wrong. Also, I’ve bumped all the following headings down one level so that all the discussion of the elements of the landlord package are three-heads under this two-head. This more clearly differentiates the abstract lease discussion above and the various elements of the landlord lease discussion here and below. Andy
The “landlord” is a package that allows more complex leasing systems to be built. It is not part of the Jini specification, but is supplied as a set of classes and interfaces. The set is not complete in itself—some parts are left as interfaces and need to have class implementations. These will be supplied by a particular application.
Warning: This landlord package is part of the com.sun.jini package, which may change for Jini 1.1.
A landlord looks after a set of leases. Leases are identified to the landlord by a cookie, which is just some object that uniquely labels each lease to its landlord. It could be an Integer, for example, with a new value for each lease. A landlord does not need to create leases itself, as it can use a landlord lease factory to do this. (But, of course, it can create them, depending on how an implementation is done.) When a lease wishes to cancel or renew itself, it asks its landlord to do it. A client is unlikely to ask the landlord directly, as it will only have been given a lease, not a landlord.
Jan: Do you mean in the preceding sentence that the client asks the lease to renew itself, and the lease asks the landlord? Andy
The principal classes and interfaces in the landlord package are shown in Figure 7.2, where the interfaces are shown in italicized font and the classes in normal font.

Figure 7.2: Class diagram of the landlord package
This fairly complex set of classes and interfaces is driven by a number of factors:
Jan: I’m not sure why choosing a particular implementation means that you need a factory. Could this be explained a little more? Andy
*	A simple lease implementation was needed for a variety of situations. If a particular implementation is chosen, then a factory is needed for this, and a corresponding factory interface to generate other particular implementations. A lease (on the client) also requires the existence of some handler for its methods on the lease-granting side, which is the landlord.
Jan: In the following point, I’m not sure what you mean by the second sentence. What needs something to work on, and what do you mean by “work on”? Do you mean that needs some physical place to be instantiated, or that it needs something that it will affect, or something else? Also, I’m not sure what you mean by “this needs to be done on the leasing side”. Which side is the leasing side (that could mean either the granting or requesting side), and what needs to be done? Andy
*	To handle all policy issues, such as initial granting of lease times, and requests for lease renewal, a policy object is used. This needs something to work on and to store results. The lease is on the client side, and this needs to be done on the leasing side. The required information for this policy management is wrapped up in a leased resource.
*	For each lease on the client side, there will be a leased resource on the lessor side. These must be stored and managed somehow. There may be only a few leases, but there could be many thousands. There could be relationships between them (such as linear order), or none at all. So, to avoid decisions about storage structures which would be wrong half of the time, lease management is just left as an interface.
Jan: Following deletion okay? If not, please clarify what you meant. “Implemented in certain ways” is really vague. Andy
The interfaces assume that each implementation class will contain a reference to certain other interfaces, and this doesn’t show in the interface specifications! If we have a landlord for a Foo resource, then we could end up with the class structure shown in Figure 7.3.

Figure 7.3: Class diagram of a landlord implementation
Jan: Will readers know what the 1s and *s are in the figure? If not, they should be explained. I’m not sure what they are, myself. It would also help to give a brief explanation of what is shown in the figure. Not just saying that it is a landlord implementation, but explaining how the various pieces relate to each other. Andy
Jan: IN the following sentence, what directions and multiplicities are you referring to? Andy
Some comments are appropriate about the directions and multiplicities:
*	A landlord can be managing many leases, but it doesn’t know what the leases are—the leases know their landlord, and they call its methods using the lease cookie. So many LandlordLease objects contain a reference to a FooLandlord.
*	Certain requests need to be forwarded through the system. For example, a renew() request from a lease will get passed to a landlord. The landlord cannot handle it directly, since the renewal is a matter requiring policy decisions. It must be passed to a lease policy object. One way of doing this (as shown in Figure 7.3) is for the landlord to have a reference to a lease manager, which has a reference to a lease policy. Similarly, a newLease() request from the landlord will need to invoke a newLease() method on the factory, and this can be done by ensuring that the lease policy also has a reference to the factory.
*	A factory may be used by many lease policies; a policy may be used by many lease managers; and a lease manager may be used by many landlords.
LandlordLease Class
The LandlordLease class extends AbstractLease. This class has the private fields cookie and landlord, as shown in Figure 7.4.

Figure 7.4: The class diagram for LandlordLease
Jan: In the following sentence, what is the “it” in “its”? And what is shown in the following code? It would help if the sentence explained the code a little more clearly. Andy
Implementation of the methods cancel()and doRenew() is deferred to its landlord.
public void cancel() {
        landlord.cancel(cookie);
    }

    protected long doRenew(long renewDuration) {
        return landlord.renew(cookie, renewDuration);
    }
Jan: Which class are you referring to in the following sentence? Andy
The class can be used as is, with no subclassing needed. Note that the landlord system produces these leases but does not actually keep them anywhere—they are passed on to clients, which then use the lease to call the landlord and hence interact with the landlord lease system. Within this system, the cookie is used as an identifier for the lease.
LeasedResource Interface
A LeasedResource is a convenience wrapper around a resource that includes extra information and methods for use by landlords. It defines an interface as follows:
public interface LeasedResource {
    public void setExpiration(long newExpiration);
    public long getExpiration();
    public Object getCookie();
}
This interface includes the cookie, a unique identifier for a lease within a landlord system, as well as expiration information for the lease. This is all the information maintained about the lease that has been given out to a client.
An implementation of LeasedResource will typically include the resource that is leased, plus a method of setting the cookie. The following code shows an example:
/**
 * FooLeasedResource.java
 */
package foolandlord;

import com.sun.jini.lease.landlord.LeasedResource;

public class FooLeasedResource implements LeasedResource  {
   
    static protected int cookie = 0;
    protected int thisCookie;
    protected Foo foo;
    protected long expiration = 0;

    public FooLeasedResource(Foo foo) {
        this.foo = foo;
        thisCookie = cookie++;
    }

    public void setExpiration(long newExpiration) {
        this.expiration = newExpiration;
    }

    public long getExpiration() {
        return expiration;
    }
    public Object getCookie() {
        return new Integer(thisCookie);
    }

    public Foo getFoo() {
        return foo;
    }
} // FooLeasedResource
LeasePolicy Interface
A lease policy is used when a lease is first granted and when it tries to renew itself. The time requested may be granted, modified, or denied. A lease policy is specified by the LeasePolicy interface.
package com.sun.jini.lease.landlord;

public interface LeasePolicy {

    public Lease leaseFor(LeasedResource resource, long requestedDuration)
        throws LeaseDeniedException;

    public long renew(LeasedResource resource, long requestedDuration)
        throws LeaseDeniedException, UnknownLeaseException;

    public boolean ensureCurrent(LeasedResource resource);
}
This interface includes a “factory” method leaseFor() that returns a lease based on the policy and request.
Jan: Following addition okay? Is LeaseDurationPolicy a class, or should it be described as something else? Andy
An implementation of this policy is given by the LeaseDurationPolicy class. This class grants and renews leases based on constant values for maximum and default lease durations, as shown here:
package com.sun.jini.lease.landlord;

public class LeaseDurationPolicy implements LeasePolicy {

    public LeaseDurationPolicy(long maximum, long defaultLength,
        Landlord landlord, LeaseManager mgr, LandlordLeaseFactory factory);

    public Lease leaseFor(LeasedResource resource, long requestedDuration)
        throws LeaseDeniedException;
    public long renew(LeasedResource resource, long requestedDuration);
    public boolean ensureCurrent(LeasedResource resource);
}
In addition to implementing the interface methods, the constructor also passes in the factory to be used (which will probably be a LandlordLease.Factory) and maximum and default lengths for leases. The maximum duration is to set a hard upper limit (which could be, say, Lease.FOREVER), while the default is what is granted if the client asks for a duration of Lease.ANY.
LeaseManager Interface
Jan: Below you refer to the renewed() method of the policy, but it looks to me that renewed() is a method of the LeaseManager, and the comparable method in the policy is renew(). Please check this and revise as necessary. Andy
The operations that can be carried out on a lease are creation, renewal, and cancellation. The first two are subject to the lease policy and must be handled by the leaseFor() and renewed() methods of the policy. These set or alter the properties of a single lease. There may be many leases for a resource, or even many resources with one or more leases. Some level of management for a group of leases may be needed, and this is done by a LeaseManager. 
The LeaseManager interface is defined as follows:
package com.sun.jini.lease.landlord;

public interface LeaseManager {
    public void register(LeasedResource resource, long duration);
    public void renewed(LeasedResource resource, long duration,
                        long oldExpiration);
}
Jan: Addition below okay? Andy
This LeaseManager doesn’t actually manage the leases, since they have been given to the client. Rather, it handles the lease resource, which has the cookie identifier and the expiration time for the lease.
Jan: What is “this” in the following sentence? Andy
An implementation of LeaseManager will look after a set of leases (really, their resources) by adding a new lease resource to its set for each lease, and by updating information about renewals. The interface does not include a method for informing the manager of cancelled leases, though—that is done to the Landlord instead, by the lease when its cancel() method is called.
This split responsibility between LeaseManager and Landlord is a little awkward and can possibly lead to memory leaks, with the manager holding a reference to a lease (resource) that the landlord has cancelled. Either the list of lease resources must be shared between the two, or the landlord must ensure that it passes on cancellations to the manager.
There is also the question of how the lease manager is informed of changes to individual leases by the lease policy. The LeaseDurationPolicy will pass on this information in its leaseFor() and renew() methods, but other implementations of LeasePolicy need not. As we only use the LeasePolicy implementation, we are okay here.
A third question is who looks after leases expiring, and how this can be done. No part of the landlord specifications talk about this or give a suitable method. This suggests that it, too, is subject to some sort of policy, but it is not one with landlord support. It is left to implementations of one of the landlord interfaces, or to a subclass. A convenient place to locate this checking is in the lease manager, because it has knowledge of all the leases and their duration. Possible ways of doing this include the following:
*	A thread per lease, which will sleep and time out when the lease should expire. This will need to sleep again if the lease has been renewed in the meantime.
*	A single sleeper thread sleeping for the minimum period of all leases. This may need to be interrupted if a new lease is created with a shorter expiration period.
*	A polling mechanism in which a thread sleeps for a fixed time and then cleans up all leases that have expired in the meantime.
*	A lazy method, in which no active thread looks for lease expiries but just cleans them up if it comes across expired leases while doing something else (which is done by Outrigger with Entries).
Jan: What are you referring to in the preceding parenthetical comment? Will readers know what Outrigger and Entries are? Andy
The FooLeaseManager implements this third method polling mechanism:
/**
 * FooLeaseManager.java
 */
package foolandlord;

import java.util.*;
import net.jini.core.lease.Lease;
import com.sun.jini.lease.landlord.LeaseManager;
import com.sun.jini.lease.landlord.LeasedResource;
import com.sun.jini.lease.landlord.LeaseDurationPolicy;
import com.sun.jini.lease.landlord.Landlord;
import com.sun.jini.lease.landlord.LandlordLease;
import com.sun.jini.lease.landlord.LeasePolicy;

public class FooLeaseManager implements LeaseManager {

    protected static long DEFAULT_TIME = 30*1000L;

    protected Vector fooResources = new Vector();
    protected LeaseDurationPolicy policy;

    public FooLeaseManager(Landlord landlord) {
        policy = new LeaseDurationPolicy(Lease.FOREVER,
                                         DEFAULT_TIME,
                                         landlord,
                                         this,
                                         new LandlordLease.Factory());
        new LeaseReaper().run();
    }
   
    public void register(LeasedResource r,long duration) {
        fooResources.add(r);
    }

    public void renewed(LeasedResource r, long duration, long olddur) {
        // no smarts in the scheduling, so do nothing
    }

    public void cancelAll(Object[] cookies) {
        for (int n = cookies.length; --n >= 0; ) {
            cancel(cookies[n]);
        }
    }

    public void cancel(Object cookie) {
        for (int n = fooResources.size(); --n >= 0; ) {
            FooLeasedResource r = (FooLeasedResource) fooResources.elementAt(n);
            if (r.getCookie().equals(cookie)) {
                fooResources.removeElementAt(n);
            }
        }
    }

    public LeasePolicy getPolicy() {
        return policy;
    }

    public LeasedResource getResource(Object cookie) {
        for (int n = fooResources.size(); --n >= 0; ) {
            FooLeasedResource r = (FooLeasedResource) fooResources.elementAt(n);
            if (r.getCookie().equals(cookie)) {
                return r;
            }
        }
        return null;
    }

    class LeaseReaper extends Thread {
        public void run() {
            while (true) {
                try {
                    Thread.sleep(DEFAULT_TIME) ;
                }
                catch (InterruptedException e) {
                }
                for (int n = fooResources.size()-1; n >= 0; n--) {
                    FooLeasedResource r = (FooLeasedResource)
                                           fooResources.elementAt(n)
 ;
                    if (!policy.ensureCurrent(r)) {
                        System.out.println("Lease expired for cookie = " +
                                           r.getCookie()) ;
                        fooResources.removeElementAt(n);
                        // replace this landlord.cancel(r.getCookie()) ;
                        
                    }
                }
            }
        }
    }

} // FooLeaseManager
Landlord Interface
The Landlord is the final interface in the package that we need for a basic landlord system. Other classes and interfaces, such as LeaseMap are for handling leases in batches, and will not be dealt with here. The Landlord interface is as follows:
package com.sun.jini.lease.landlord;

public interface Landlord extends Remote {

    public long renew(Object cookie, long extension)
        throws LeaseDeniedException, UnknownLeaseException, RemoteException;

    public void cancel(Object cookie)
        throws UnknownLeaseException, RemoteException;

    public RenewResults renewAll(Object[] cookie, long[] extension)
        throws RemoteException;
      
    public void cancelAll(Object[] cookie)
        throws LeaseMapException, RemoteException;
}
Jan: You refer to the FooManager implementation in the following paragraph, but there doesn’t seem to be any such implementation in this chapter. If you are referring to something in one of the figures, the figure number should be referred to. Andy
The renew() and cancel() methods are usually called from the renew() and cancel() methods of a particular lease. The renew() method needs to use a policy object to ask for renewal, and in the FooManager implementation, it gets this policy from the FooLeaseManager. The cancel() method needs to modify the list of leases, and in the FooManager implementation, it passes this on to the FooLeaseManager, since that is the only object that maintains a list of resources.
There must be a method to ask for a new lease for a resource, and this is not specified by the landlord package. This request will probably be made on the lease-granting side, and this should have access to the landlord object, which forms a central point for lease management. So, an implementation of this interface will quite likely have a method such as
public Lease newFooLease(Foo foo, long duration);
which will give a lease for a resource.
The lease used in the landlord package is a LandlordLease. This contains a private field, which is a reference to the landlord itself. The lease is given to a client as a result of newFooLease(), and this client will usually be a remote object. This will involve serializing the lease and sending it to this remote client. While serializing it, the landlord field will also be serialized and sent to the client. 
Jan: I’m not sure why the landlord will be remote from its origin in the following sentence. Could that be clarified a bit? Andy
When the client methods such as renew() are called, the implementation of the LandlordLease will make a call to the landlord, which by then will be remote from its origin. So the landlord object invoked by the lease will need to be a remote object making a remote call. The Landlord interface already extends Remote, but if it is to run as a remote object, then the easiest way is for FooLandlord to extend the UnicastRemoteObject class.
Jan: What is the following? Is it a class, an interface, an implementation, package etc.? What is the best term to describe it? Andy
Putting all this together for the FooLandlord class gives us this:
/**
 * FooLandlord.java
 */

package foolandlord;

import com.sun.jini.lease.landlord.*;
import net.jini.core.lease.LeaseDeniedException;
import net.jini.core.lease.Lease;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.Remote;

public class FooLandlord extends  UnicastRemoteObject
                         implements Landlord {

    FooLeaseManager manager;

    public FooLandlord() throws java.rmi.RemoteException {
        manager = new FooLeaseManager(this);
    }
   
    public void cancel(Object cookie) {
        manager.cancel(cookie);
    }

    public void cancelAll(Object[] cookies) {
        manager.cancelAll(cookies);
    }

    public long renew(java.lang.Object cookie,
                      long extension)
        throws net.jini.core.lease.LeaseDeniedException,
               net.jini.core.lease.UnknownLeaseException {
        LeasedResource resource = manager.getResource(cookie);
        if (resource != null) {
            return manager.getPolicy().renew(resource, extension);
        }
        return -1;
    }

    public Lease newFooLease(Foo foo, long duration)
        throws LeaseDeniedException {
        FooLeasedResource r = new FooLeasedResource(foo);
        return manager.getPolicy().leaseFor(r, duration);
    }

    public Landlord.RenewResults renewAll(java.lang.Object[] cookies,
                                          long[] extensions) {
        long[] granted = new long[cookies.length];
        Exception[] denied = new Exception[cookies.length];

        for (int n = cookies.length; --n >= 0; ) {
            try {
                granted[n] = renew(cookies[n], extensions[n]);
                denied[n] = null;
            } catch(Exception e) {
                granted[n] = -1;
                denied[n] = e;
            }
        }
        return new Landlord.RenewResults(granted, denied);
    }
} // FooLandlord
Summary
Jan: What is LeaseRenewalManager in the second sentence below? It hasn’t been mentioned in this chapter. Andy
Leasing allows resources to be managed without complex garbage-collection mechanisms. Leases received from services can be dealt with easily, using LeaseRenewalManager. Entities that need to hand out leases can use a system, such as the landlord system, to handle these leases.