Shutdown

A JVM shutdown sequence, shown in Figure 3.1, “Shutdown Sequence”, is triggered by:

The shutdown sequence waits a configurable amount of time for all transactional work to complete. Generally transactional work will automatically complete, either by committing or rolling back. However, long running transactions, or transactions blocked waiting for external resources, may exceed the shutdown wait value and cause the JVM to be forced down. The node must be restarted when this occurs. To ensure that a JVM exits cleanly make sure that an application's transactions complete within the shutdown timer interval specified using the shutdowntimeoutseconds parameter when the JVM was deployed.

These steps are taken during the JVM shutdown sequence:

  1. A shutdown timer is started to wait for all transactions to complete. The duration of the shutdown timer is specified using the shutdowntimeoutseconds deployment tool value.

  2. Execute any JVM shutdown hooks.

  3. Block new transactions from starting.

  4. Wait for all active transactions to complete.

These steps are shown in Figure 3.1, “Shutdown Sequence”.

Shutdown Sequence

Figure 3.1. Shutdown Sequence


There is one other timer used to ensure a clean JVM termination - the target JVM resolution timer. The duration of this timer is controlled by the noDestinationTimeoutSeconds configuration value. This timer controls how long a method call will block waiting for a target JVM to be available. The target JVM may be on the local or a remote node. If the method cannot be executed within the value of noDestinationTimeoutSeconds, the current transaction is aborted. During shutdown this transaction will not be restarted, ensuring that the JVM exits cleanly. See the TIBCO ActiveSpaces® Transactions Administration for details on configuring the noDestinationTimeoutSeconds value.

Example 3.1, “Calling Exit” is a snippet showing the use of exit() to initiate a JVM shutdown sequence.

Example 3.1. Calling Exit

//     $Revision: 1.1.2.1 $

package com.kabira.snippets.vmlifecycle;

/**
 *  Calling exit to return a non-zero return code to deployment tool
 * <p>
 * <h2> Target Nodes</h2>
 * <ul>
 * <li> <b>domainnode</b> = A
 * </ul>
 */
public class Exit
{
    /**
     * Main entry point
     * @param args  Not used
     */
    public static void main(String args [])
    {
        //
        //    This will return a value of -1 to the deployment client
        //
        System.out.println("Calling exit with a value of -1");
        Runtime.getRuntime().exit(-1);
    }
}


#
#     Output from IDE connection if exit is called
#
INFO: Application [com.kabira.snippets.vmlifecycle.Exit] running on node [A] exited with status [-1]
INFO: Run of distributed application [com.kabira.snippets.vmlifecycle.Exit] complete.
FATAL: Distributed application failed on [1] nodes.
INFO: Application [com.kabira.snippets.vmlifecycle.Exit] exited with status [-1].