Listeners
Any listener you define must be an interface containing one or more methods. Each method must have exactly one input parameter. The input parameter must specify the event object that the listener listens for. The event object must be as described in "Event Objects." An event listener class must always be declared as a public class. The definition of a listener interface named SimpleListener interface is given in CODE EXAMPLE 14-2. The listener in this example listens for SimpleEvent objects as defined in CODE EXAMPLE 14-1.
| CODE EXAMPLE 14-2 Definition of a Listener Interface |
Listener Methods in an M-Bean
When writing an m-bean that provides event handling services, you have to define methods for adding and removing listeners. These methods must conform to the design patterns for event sources defined in Chapter 3. An example of how to register and remove listeners is shown in CODE EXAMPLE 14-3.
| CODE EXAMPLE 14-3 Listeners in an M-Bean |
Developing a Manager to Receive Events
The steps in developing a manager to receive events from an m-bean are:
| CODE EXAMPLE 14-4 Receiving Framework Events |
The mogen compiler is described in detail in Chapter 6.
Output From mogen for an M-Bean With Listeners and Events
An m-bean that uses a listener is associated with Java classes that represent the listener and the event that is listened for. For example, an m-bean that defines the Java class example is associated with:
For such an m-bean, the mogen compiler generates:
When compiling the Simple m-bean, mogen generates interfaces and stubs as
illustrated in FIGURE 14-1. The interfaces and stubs generated are described in
TABLE 14-1.

FIGURE 14-1 Output of the mogen Compiler for Listeners and Events
|
M-Bean Class |
C-Bean Code Generated |
Comment |
|
Simple.class |
SimpleMO.java |
Defines which of the methods of the m-bean are accessible to a Java manager. CODE EXAMPLE 14-5 shows the generated code corresponding to the methods in the m-bean for adding and removing listeners. |
|
|
SimpleMOStub.java |
Implements the methods defined in the Java interface SimpleMO. |
|
SimpleListener.class |
SimpleListenerMO.java |
Defines the interface to be implemented to register for events on SimpleMO. In the SimpleListenerMO interface, the event object is called SimpleEventMO. |
|
|
SimpleListenerStub.java |
Implements the SimpleListener interface for catching events emitted by the Simple m-bean and forwarding them to SimpleMO. |
|
SimpleEvent.class |
SimpleEventMO.java |
Defines the event type emitted by the SimpleMO c-bean whenever its associated Simple m-bean emits an event of type SimpleEvent |
CODE EXAMPLE 14-5 shows the code generated in SimpleMO.java corresponding to the methods in the Simple m-bean for adding and removing listeners. The code shown in CODE EXAMPLE 14-5 is a subset of the code mogen generates in the SimpleMO.java when compiling the Simple m-bean.
| CODE EXAMPLE 14-5 Generated Code for the SimpleMO Interface |
Suppressing Code Generation for Listeners
Options of the mogen compiler enable you to generate a c-bean without any code for listeners or events. This is useful if you want to reduce the size of a c-bean, or if you want to prevent a user of the Java manager from listening for events. If you modify an m-bean without modifying its listeners, you can use these options to regenerate the c-bean without affecting code already generated for listeners and events.
-nl to generate a c-bean without code for listeners, even if the m-bean contains listeners
-nlmo to generate a c-bean without code for the Java interface for the listener
-nlas to generate a c-bean without code for the listener stub
-ne to generate a c-bean without code for events, even if the m-bean contains events
Using Code Generated for Listeners and Events
To use a c-bean generated for a listener, you have to implement the beanListenerMO interface to add or remove the listener on the c-bean. To add a beanListenerMO on a beanMO object, include a call to addbeanListenerMO in the Java manager you develop. The listener waits for events sent by the corresponding bean object. CODE EXAMPLE 14-6 shows code for adding and removing a listener in a manager.
| CODE EXAMPLE 14-6 Creating and Removing an Event Listener in a Manager |
In the example shown in CODE EXAMPLE 14-6:
When the m-bean emits an event (beanEvent), the registered beanListenerStub forwards the event to the c-bean. The c-bean (beanMOStub) then calls all the beanListenerMO listeners registered. The mechanism for adding event listeners is illustrated in FIGURE 14-2.

FIGURE 14-2 Mechanism for Adding an Event Listener
Defining Your Own Event Handler
Any event handling service you define must implement the com.sun.jaw.reference.agent.services.EventHandlerIf interface. To enable an event handling service to be identified, the class part of its object name must be ServiceName.EVENT.
Alarm Clock Service
The alarm clock service activates (or "wakes up") alarm clock event listeners when the timeout elapses. The alarm clock service is not manageable as no MO stubs are provided, therefore it must be used locally. To add an alarm clock, create an instance of the com.sun.jaw.impl.agent.services.alarm.AlarmClock class.
| CODE EXAMPLE 14-7 Prototype of the handleAlarmClockEvent Method |
Setting the Alarm Clock Timeout
To set an alarm clock timeout, use the setTimeout method specifying the required elapsed time, in milliseconds, after which the alarm clock event will be sent. CODE EXAMPLE 14-8 shows the instantiation of an an alarm clock and use of the setTimeout method to set the timeout for the alarm clock.
| CODE EXAMPLE 14-8 Instantiating and Setting the Alarm Clock |
Getting the Alarm Clock Timeout
CODE EXAMPLE 14-9 shows how to get the timeout for the alarm clock service that was instantiated in CODE EXAMPLE 14-8.
| CODE EXAMPLE 14-9 Getting the Alarm Clock Timeout |
The alarm clock service is used by the scheduler service and the monitoring service.
Scheduler Service
The scheduler service enables you to create alarms for specific dates and times. The alarms or `scheduler events' are sent to all objects registered to receive scheduler events. An object is registered to receive scheduler events by adding a scheduler listener interface. The scheduler service is not manageable as no MO stubs are provided, therefore it must be used locally.
| CODE EXAMPLE 14-10 Creating a Scheduler |
Scheduler Listener
You must implement a SchedulerListener interface in any object that receives scheduler event objects. This registers the object as a scheduler listener. To add a SchedulerListener, invoke the addSchedulerListener method of the scheduler. CODE EXAMPLE 14-11 shows the code for registering as a scheduler listener with the sch scheduler created in CODE EXAMPLE 14-10.
| CODE EXAMPLE 14-11 Scheduler Listener Interface |
Scheduler Events
Scheduler events are defined as instances of the Java class: com.sun.jaw.impl.agent.services.scheduler.SchedulerEvent.
| CODE EXAMPLE 14-12 Creating a Scheduler Event |
There are two types of scheduler events:
If the scheduler event has a non-null periodicity, the performAddEvent method updates the event date by adding the periodicity until the event date is later than the current date. When the event date is later than the current date, the method inserts the scheduler event into the vector.
If a number of repetitions is specified with the periodicity, the performAddEvent method updates the event date as before. The number of times that the method adds the period is limited to the specified number of repetitions. If the event date remains earlier than the current date, the method generates an exception.
After an event has been added to the scheduler vector, it cannot be updated.
CODE EXAMPLE 14-13 shows the addition of an evtSpring object to the scheduler sch that was created in CODE EXAMPLE 14-10. The variable ONE_SECOND is defined in the scheduler class.
| CODE EXAMPLE 14-13 Adding Events to the Scheduler |
Removing Events From the Scheduler
Events are removed from the scheduler vector using the scheduler's performRemoveEvent method. The performRemoveEvent method is overloaded and can take either the scheduler event or the position of the event in the vector as parameters. If the event specified is not in the vector or the index is invalid, the method throws an InstanceNotFoundException.
| CODE EXAMPLE 14-14 Removing Events From the Scheduler |
Starting and Stopping the Scheduler
The scheduler is started using the scheduler performStart method and stopped using the performStop method. If the vector is empty when the scheduler is started, the scheduler waits for an event to be added. If events are added later, the associated alarm clock is instantiated and started. The alarm clock timeout is set for the required event date.
|
notifyPastEvents = true |
All events with a date before the current date are handled; |
|
notifyPastEvents = false |
Events with a date before the current date are ignored; |
Setting the notifyPastEvents flag to false can be used to suppress a flood of scheduler events being sent out when the scheduler is started. The default value for this flag is false.
| CODE EXAMPLE 14-15 Starting and Stopping the Scheduler |
Scheduler Event Handling
When the date of an event in the event list is reached, the handleScheduler method is invoked. CODE EXAMPLE 14-16 shows an example of how the events can be handled. This example uses four events:
| CODE EXAMPLE 14-16 Scheduler Event Handling |
If the counter can wrap around its maximum value, then the modulus of the counter needs to be specified. The modulus is the value at which the counter is reset to zero. The operation of the counter monitor is illustrated in FIGURE 14-3.
Note - The counter monitor can only be used with properties of type integer. The property must be increased in increments of one unit only.
Gauge Monitor
A gauge monitor observes a property that is continuously variable with time. A high threshold value and a low threshold value are specified. Events are sent as follows:
The operation of the gauge monitor is illustrated in FIGURE 14-4.
Note - The gauge monitor can only be used with properties of type integer or float.
Adding a Monitor
You can add a monitor to an agent or a manager, depending on where you want the events the monitor sends to be processed. To add a monitor, create an instance of the Java class that implements the monitor you want to add.
|
Monitor |
Java Class |
|
Counter: |
|
|
|
com.sun.jaw.impl.agent.services.monitor.CounterMonitor |
|
|
com.sun.jaw.impl.agent.services.monitor.CounterMonitorMO |
|
Gauge: |
|
|
|
com.sun.jaw.impl.agent.services.monitor.GaugeMonitor |
|
|
com.sun.jaw.impl.agent.services.monitor.GaugeMonitorMO |
CODE EXAMPLE 14-17 shows code for creating and initializing a counter monitor in an agent.
| CODE EXAMPLE 14-17 Creating and Initializing a Counter Monitor |
CODE EXAMPLE 14-18 shows code for creating and initializing a gauge monitor in an agent.
| CODE EXAMPLE 14-18 Creating and Initializing a Gauge Monitor |
Listening for Monitor Events
All events sent by a monitor are instances of the class com.sun.jaw.impl.agent.services.monitor.MonitorEvent, regardless of the type of monitor. The constructor for this class requires that the monitor that sent the event, the event type, and information about the cause of the event are specified.
|
Application |
Java Interface |
|
Agent |
com.sun.jaw.impl.agent.services.monitor.MonitorListener |
|
Manager |
com.sun.jaw.impl.agent.services.monitor.MonitorListenerMO |
Both of these interfaces contain a single method for handling monitor events. The prototype of this method on the agent side is defined in CODE EXAMPLE 14-19.
| CODE EXAMPLE 14-19 Prototype of the handleMonitorEvent Method |
An application that receives monitor events must also include code for registering itself as a monitor listener. To add a monitor listener, invoke the addMonitorListener method of the monitor as shown in CODE EXAMPLE 14-20. In this example, gm is an instance of the GaugeMonitor class instantiated, as shown in CODE EXAMPLE 14-18.
| CODE EXAMPLE 14-20 Adding a Monitor Listener |
Specifying the Property to be Monitored
A monitor observes a particular property in a particular m-bean instance. To specify the property to be monitored, invoke both of these methods of the monitor:
NbChanges in the only instance of the SimpleBean class present in the default domain of the agent.| CODE EXAMPLE 14-21 Specifying a Property to be Monitored |
Setting the Granularity Period
The observed property is monitored at intervals specified by the granularity period. It is specified in milliseconds. To set the granularity period, invoke the setGranularityPeriod method of the monitor, as shown in CODE EXAMPLE 14-22. In this example, cm is an instance of the CounterMonitor class instantiated as shown in CODE EXAMPLE 14-17. The granularity period is set to 30 000 milliseconds (30 seconds).
| CODE EXAMPLE 14-22 Setting the Granularity Period of a Monitor |
Specify a granularity period that is consistent with the rate at which the property changes.
Setting Parameters for Counter Monitors
FIGURE 14-3 shows the operation of a counter monitor. The monitor monitors a counter C(t) which varies with time t. The granularity period is G and the comparison level is T.

FIGURE 14-3 Operation of the Counter Monitor
Setting the Comparison Level for a Counter Monitor
When a monitored counter reaches or exceeds its comparison level, an event is sent if specified. To set the comparison level, invoke the setComparisonLevel method of the counter monitor. To specify whether an event is sent, invoke the setNotifyOnOff method of the counter monitor. This is shown in CODE EXAMPLE 14-23. In this example, cm is an instance of the CounterMonitor class instantiated as shown in CODE EXAMPLE 14-17. The comparison level is three and an event will be sent when the counter reaches or exceeds this value.
| CODE EXAMPLE 14-23 Setting the Threshold Value of a Counter Monitor |
As shown in FIGURE 14-3, an event is sent as soon as the counter is monitored after its value has reached the initial comparison level of three.
Setting the Offset for a Counter Monitor
The counter monitor provides an offset mechanism to enable a counting interval to be detected. If you specify an offset value, the comparison level is increased by the offset value each time the current comparison level is reached. This takes place before the counter is increased to avoid duplicate events being sent. To set the offset value, invoke the setOffsetValue method of the counter monitor, as shown in CODE EXAMPLE 14-24. In this example, cm is an instance of the CounterMonitor class instantiated as shown in CODE EXAMPLE 14-17. The offset value is two.
| CODE EXAMPLE 14-24 Setting the Offset Value |
As shown in FIGURE 14-3, an event is sent as soon as the counter is monitored after its value reaches the comparison level (after the first addition of the offset) at five, and (after the second addition of the offset) at seven.
Setting the Modulus Value for a Counter Monitor
If the counter you are monitoring is able to wrap around when it reaches its maximum value, you must set its modulus value. The modulus is the value at which a counter is reset to 0. To set the modulus, invoke the setModulusValue method of the counter monitor. This is shown in CODE EXAMPLE 14-25. The modulus value is 500.
| CODE EXAMPLE 14-25 Setting the Modulus Value |
Using a Counter Monitor to Track Differences
Using a counter monitor to track differences enables you to observe the rate at which a counter changes. If you specify the counter difference option, an event is sent when the derived gauge reaches or exceeds the comparison level. The derived gauge is calculated as the difference between the observed counter values for two successive observations. If this difference is negative, that is, the counter has wrapped around, then the value of the derived gauge is increased by the value of the modulus. This can be expressed algebraically as follows:
| CODE EXAMPLE 14-26 Monitoring Counter Differences |
Setting Parameters for a Gauge Monitor
FIGURE 14-4 shows the operation of a gauge monitor. The monitor monitors a property P(t) that varies with time t. The granularity period is G, the lower threshold is TL, and the higher threshold is TH.

FIGURE 14-4 Operation of the Gauge Monitor
Setting the Threshold Values for a Gauge Monitor
To set the threshold values invoke these methods of the gauge monitor:
The high threshold value and the low threshold value must be of the same type as the observed property. The high threshold value must be greater than or equal to the low threshold value.
To specify whether an event is sent, invoke these methods of the gauge monitor:
| CODE EXAMPLE 14-27 Setting the Threshold Values for a Gauge Monitor |
Using a Gauge Monitor to Track Differences
Using a gauge monitor to track differences enables you to observe the rate at which a gauge property changes. If you specify the gauge difference option, an event is sent when the derived gauge exceeds its specified upper or lower threshold according to the hysteresis mechanism. The derived gauge is calculated as the difference between the observed property values for two successive observations. This can be expressed algebraically as follows:
| CODE EXAMPLE 14-28 Monitoring Gauge Differences |
Setting Multiple Thresholds for a Property
For a single monitor you are allowed to specify only one pair of threshold values. To specify more than one pair of threshold values, create one monitor for each pair of threshold values you want to specify. Make sure that each monitor you create monitors the same property in the same m-bean instance. Starting and Stopping a Monitor
To start or stop a monitor, invoke the performStart or performStop method of the monitor. CODE EXAMPLE 14-29 shows how to start and stop a monitor. In this example, gm is an instance of the GaugeMonitor class instantiated as shown in CODE EXAMPLE 14-18.
| CODE EXAMPLE 14-29 Starting and Stopping a Monitor |
When a monitor is stopped, it is reset. For a counter monitor, this means that when the monitor is restarted, the comparison level is reset to the value specified in the last invocation of the setComparisonLevel method. For a gauge monitor, this means that when the monitor is restarted, there is no record of the type (TH or TL) of the last event sent. An event is sent as soon as one of the thresholds is reached or exceeded.
Discovery Service
The discovery service enables you to discover Java Dynamic Management agents in a network. Only agents that have a discovery responder registered in their framework can be discovered using this service. The discovery service can be functionally divided into two parts:

You can instantiate multiple discovery clients on a single agent or manager. Each discovery client can be configured to use different multicast groups or ports. This allows you to use a single agent or manager for monitoring different groups of agents.
To instantiate a discovery client, create an instance of the Java class: com.sun.jaw.impl.agent.services.jawdiscovery.DiscoveryClient. The scope of the discovery depends on the time-to-live used by the multicast socket. Time-to-live is defined by the Java class java.net.MulticastSocket. By default, the time-to-live is 1. It can be changed by setting the property timeToLive on the discovery client.
After it has sent a discovery request, a discovery client waits for responses for a specific time. By default the time is 1 second. This can be customized by setting the timeOut property, in milliseconds, on the discovery client. The discovery client also requests the DiscoveryResponder response type; this can be unicast or multicast. The response type is specified using the returnPort variable, a negative number specifies a multicast response. For further information, see page 212. CODE EXAMPLE 14-30 shows the instantiation, initialization, and starting of a discovery client using a non-default multicast group and port.
| CODE EXAMPLE 14-30 Instantiating and Initializing a Discovery Client |
Discovery Responder
The agents must have a DiscoveryResponder registered in their framework to be found by the discovery service. When a new DiscoveryResponder object registers in an agent, or when its performStart method is invoked, it sends out a multicast registration message. Similarly, a responder that deregisters or has its performStop method invoked, sends a multicast deregistration message. These messages are proprietary and are not exposed to the user. The registration/deregistration messages enable you to keep an accurate record of agents with discovery responders in the network; for further information, see "Discovery Support Service" on page 214.
Discovery responders reply to a request from a discovery client by sending a response that contains information on the hostname of the agent and, optionally, a list of adaptors available in the agent. The message is proprietary and is decoded and represented in the DiscoveryClient by the DiscoveryResponse object. The DiscoveryResponse object consists of a string representing the hostnames of discovered agents and a vector of ObjectName representing the adaptors found on each agent. CODE EXAMPLE 14-31 shows the initialization of a discovery responder.
| CODE EXAMPLE 14-31 Initializing a Discovery Responder |
The discovery responder registered in the discovered agent can respond using one of two modes:
TRUE.

FALSE.
| CODE EXAMPLE 14-32 Performing a Discovery Operation |
Discovery Support Service
The discovery support service enables you to monitor discovery responders in a multicast group. A DiscoveryMonitor object listens for discovery responder objects registering or deregistering in the multicast group. When the discovery monitor hears a discovery responder registering or deregistering, it sends a discovery responder event to its listener. The listener is an instance of the Java class that implements the DiscoveryResponderListener interface. 
FIGURE 14-8 Discovery Support Service
Discovery Monitor
The DiscoveryMonitor is an m-bean that listens for DiscoveryResponder objects registering or deregistering within a specific multicast group. The default multicast group is 224.224.224.224 and the default port is 9000.
| CODE EXAMPLE 14-33 Instantiating and Starting a Discovery Monitor |
A discovery monitor can be stopped using the performStop method. When it is stopped, the discovery monitor does not listen for registration/deregistration messages from DiscoveryResponder objects. The discovery monitor is restarted using the performStart method. The discovery monitor has a state property that allows you to determine whether it is ONLINE, OFFLINE, or STOPPING. The STOPPING state is seen only when the discovery monitor is still dealing with active requests. When a DiscoveryMonitor is added in a Java Dynamic Management Kit agent, it is automatically started. When a DiscoveryMonitor is removed from a Java Dynamic Management Kit agent, it is automatically stopped.
Discovery Responder Listener
A discovery responder listener is an instance of the Java class that implements the DiscoveryResponderListener interface. For example, it may be implemented to update a list of agents in the network.