Activatable Jini services, Part 2: Patterns of use
- JavaWorld
October 2000
Tutorial Details:
Activatable Jini services, Part 2: Patterns of use
Activatable Jini services, Part 2: Patterns of use
By: By Frank Sommers
The RMI activation framework can produce self-sufficient and flexible Jini services
n Part 1 of this series, I defined activation as the process of creating and exporting an object via the RMI activation system, making it available for remote method calls. I also presented the chief goal of the RMI activation system: to help remote objects manage their computational resources. The JDK's activation mechanism does just that; it helps objects manage their computational resources, it does not do it for them. It is up to the developer of Jini services to properly utilize RMI activation to support resource management. In Part 2, I will present the consequences of Jini activation and some helpful patterns of use. The first important area to consider is deactivation.
Activatable Jini services: Read the whole series!
Part 1: Implement RMI activation
Part 2: Patterns of use
When to deactivate
An object informs the activation group that it is no longer active by calling Activatable.inactive() , which essentially calls the current activation group's inactiveObject() method. If no remote method calls to the object are pending -- i.e., the object really is inactive -- the group unexports the object and notifies its monitor. Thereafter, the activation monitor will consider the object's remote references as stale, causing activate() requests with the object's activation ID to trigger the activation protocol (described in Part 1).
If Activatable.inactive() succeeds, and if the group has no more active objects and is not activating objects, the activation system will shut down the group's Java VM. If an object fails to call Activatable.inactive() , it will never be garbage-collected because the activation group holds strong references to every object it creates. (Hence, if that object is the last one running in the Java VM, the Java VM will not shut down either.) The rules for garbage collection still hold, though: the object needs to make sure that it has no nondaemon threads running, and that it nulls out enough references to be eligible for garbage collection.
The remote object decides when to call inactive() ; this decision warrants some stipulations. One requirement for calling this method is that the remote object should not handle remote method calls. Also, reactivating the object should not require more effort than keeping it active for long periods of time. For instance, if a server only runs a few activatable Jini service implementations -- each of which might receive a remote method call once every few hours -- and the server is loaded lightly, running those objects continually would be the best option.
The last deactivation issue we'll consider is leases. In the Jini programming model, services typically lease their resources. For instance, not only does LoanApprovalService lease its residency in lookup services, but clients that wish to use this service lease their access to it as well. When first contacted by a client, the service should return a Registration object that contains a lease and the remote service reference, not a direct remote reference to itself.
Suppose that our LoanApprovalService implementation runs inside a bank for the benefit of loan officers, and the employees' work schedule begins at 9 a.m. and ends at 5 p.m. In this scenario, the LoanApprovalService might decide to deactivate after 5 p.m., even if it holds leases to clients. Those leases will expire when the services reinitiate at 9 a.m.
If the service knows that many leases will expire soon, it might delay deactivation if someone will soon call it to renew those leases. For instance, if the LoanApprovalService implementation had 100 outstanding leases to clients, all due to expire shortly after 5 p.m., the service might want to postpone deactivation in anticipation of renewal requests for those leases. I'll discuss shortly how a service can delegate lease renewal.
The service should also not deactivate if it must be available at a certain time. Currently, no mechanism exists in rmid to send a wake-up call to a service. A service can arrange for another service to wake it up by making a remote call to trigger activation, but that service must be awake at the given time. Thus, in a Jini federation, at least one service must remain awake if other services need periodic notifications. We'll see an example of this later in the LeaseRenewalService .
When a service does not need to be available for longer time periods, it can decide to deactivate. If the service holds references to numerous objects, which could hold references to even more objects, the object tree takes up significant computational space -- signaling an appropriate time to deactivate.
Recall our LoanApprovalService example from Part 1: it utilized Bank objects to represent a bank's loan approval criteria, essentially representing a decision-support system. Imagine an implementation with several hundred, even thousands, of Bank objects, each of which might hold many other resources. For instance, each might open socket connections to remote hosts and database management systems (via JDBC, for example) to obtain information necessary to approve or reject a loan. (Decision-support systems typically access many data sources concurrently.) When running the loan-approval object, many thousands of other objects could run, and several hundred database connections might need to be kept open.
In such situations, the programmer weighs the alternatives: keep the objects active and continuously occupy computational resources, or stop and start the services as needed. Actions like starting up objects and opening database connections always incur overhead. For instance, opening a database connection might take several seconds. Therefore, deciding the proper criteria for deactivating an object is complex, and discussing it in general terms might lead one down a slippery slope.
A side note: Properly deploying activatable services might require techniques that minimize the startup latency of objects, even the Java VM. Some specialized Java VMs, like Sun Labs's orthogonally persistent Java implementation, PJama, might prove especially useful in this regard. Everything in PJama is persistent by default, including all objects and even threads. When a PJama VM shuts down, it persistently saves its execution state (including the threads' execution states). When that VM initiates, it typically recreates its execution state from disk much faster than if all the objects and threads had to start up anew.
The RMI activation API provides for these specialized VMs' use, since the ActivationGroupDesc class allows you to specify the Java VM executable. If you designate the PJama VM for an activation group, PJama will persist all objects running in that group and recreate them at the VM's startup. If the PJama VM significantly reduces a large object tree's startup latency, the scales will tip toward deactivating the service more often. At the other end of the spectrum are some just-in-time compilers that cause additional startup latency by compiling Java byte code to native codes for faster execution.
A service must clean up after itself before signaling that it is inactive, as does any Java object that wishes to be garbage-collected. Developers should not depend on Object 's finalize() method and expect it to clean up all finite nonmemory resources (such as socket connections and references to open files). As Bill Venners points out in "Cleaning up after Jini Services," ( JavaWorld , March 2000): "Don't design your Java programs such that correctness depends upon 'timely' finalization." Before calling inactive() , a service must reach a final state, meaning the object has released all nonmemory resources and is eligible for garbage collection. Therefore, inactive means clients aren't accessing the service, and the service has reached its final state (has released all nonmemory resources).
To illustrate object deactivation, we will use a simple, and somewhat contrived, criterion: we will deactivate the object if it has no outstanding leases and no remote call was made to it within N seconds. This approach might make sense if a large number of rarely used services register with an activation system. RemoteLoanServiceImpl will mark the last remote call to its requestLoan() method. It will also start a separate thread that wakes up every N seconds to check for any remote calls made since its last wake-up. If there are none, our service will inform the RMI runtime that the object is inactive. The activation group will then unexport the object and remove all strong references to it. If no other references to the object remain, it is eligible for garbage collection. Because this object is the only one running inside the activation group, the activation system will shut down the VM. Subsequent method calls will then reactivate the group -- creating the VM -- and the group will activate the object. (See the activation protocol in Part 1.)
In the following code segment, the object's constructor fires up a thread that monitors usage. This thread wakes up after secondsToStayAlive number of seconds and checks if a special flag is set to true , which indicates that requestLoan() received a method call. We extended requestLoan to set this flag each time it is called. If the flag's value is false, the usage monitoring thread calls inactive() . We do not include provisions for releasing resources, since resources should be properly managed independent of activation (i.e., they should be released when not used), and we want to keep this example simple.
private Bank decisionSystem;
int secondsToStayActive = 15;
boolean calledMethod = false;
protected ActivationID id = null;
//hold outstanding leases granted by this service
private Map leases;
//Activation constructor. When the o
Read
Tutorial at: Click here to view the tutorial
Rate Tutorial: Activatable Jini services, Part 2: Patterns of use
- JavaWorld
October 2000
View Tutorial: Activatable Jini services, Part 2: Patterns of use
- JavaWorld
October 2000
Related
Tutorials:
Locate services with the Jini lookup
service
Locate services with the Jini lookup
service |
Web services hits
the Java scene,
Part 1
Web services hits
the Java scene,
Part 1 |
Jini-like
discovery for RMI
Jini-like
discovery for RMI |
Java security evolution
and concepts, Part 5
Java security evolution
and concepts, Part 5 |
Deploy code
servers in Jini systems
Deploy code
servers in Jini systems |
A birds-eye view of Web services
A birds-eye view of Web services |
Jtrix: Web
services beyond SOAP
Jtrix: Web
services beyond SOAP |
Jabber away with instant
messaging
Jabber away with instant
messaging |
Jini's relevance emerges, Part
1
Jini's relevance emerges, Part
1 |
Yes, you can secure your Web services documents, Part 1
Yes, you can secure your Web services documents, Part 1 |
Jini's relevance emerges, Part
2
Jini's relevance emerges, Part
2 |
Effort on the
edge, Part 1
Effort on the
edge, Part 1 |
Sun boosts
Sun boosts enterprise Java |
Jini Starter Kit 2.0 tightens Jini's security framework
Jini Starter Kit 2.0 tightens Jini's security framework |
Good
introduction
Good
introduction |
Once again, only
introduction
Once again, only
introduction |
Finally, getting hands in !
Finally, getting hands in ! |
Turn EJB components into Web services
Summary
Web services have become the de facto standard for communication among applications. J2EE 1.4 allows stateless Enterprise JavaBeans (EJB) components to be exposed as Web services via a JAX-RPC (Java API for XML Remote Procedure Call) endpoint, al |
Access Windows Performance Monitor counters from Java, Part 1
Access Windows Performance Monitor counters from Java, Part 1
Use a simple Java API to gather valuable performance statistics
Summary
Windows NT, 2000, 2003, and XP contain a utility called the Performance Monitor that provides a rich array of perform |
The JavaTM Web Services Tutorial
A beginner's guide to developing Web services and Web applications on the Java Web Services Developer Pack |
|
|
|