Adding Java Management Extensions (JMX) Instrumentation to a Java Application
Expected duration: 60 minutes
The NetBeans JMX Wizard Module integrates JMX technology right into your workflow
in the NetBeans IDE. This module allows you to quickly develop management applications,
add management to existing applications, develop manager applications, and
monitor the state of the Virtual Machine.
This tutorial shows you how to add management to an existing application (the
NetBeans sample Anagrams Game application). You will first create a non-manageable
Anagram Java Project. You will then use JMX Wizards to generate 90% of the management.
Then you will implement the management behavior specific to the application.
You will finally use the Run/Debug project with JConsole to visualize the Anagram
MBeans.
Tutorial exercises
Prerequisites
This tutorial assumes you have some basic knowledge of, or programming experience
with, the following technologies.
You will also benefit from having some knowledge on
Monitoring and Management for the Java Platform
Software Needed for the Tutorial
For this tutorial you need to have the following software installed on your computer:
To install the JMX and JConsole plugins, choose Tools > Plugins and download the module from the NetBeans Update Center.
Resources
- NetBeans help contents (Help > Help Contents > JMX). This help is
also available from Wizards.
Exercise 1: Creating the NetBeans sample Anagram Game project
The goal of this exercise is to create a runnable Java Project. The Anagram
game is a Swing Application that displays a scrambled word to the user and waits
for the user to solve the anagram.
- Choose File > New Project (Ctrl-Shift-N).
- Select the Samples > Java category.
- Select the Anagram Game project. Click Next.
- In the Project Name and Location panel,
set the project location or keep the default value if it suits you.
Select "Set as Main Project" checkbox if not selected because it will make subsequent
actions easier. Click Finish.
When you click Finish the IDE creates the Anagram Game project and displays the project in the Projects window.
- Right-click the AnagramGame project and select Properties.
- Select the Sources category and confirm that the Source/Binary format is set to JDK 5
or JDK 6. Click OK.
Note. To select JDK 5 or JDK 6, the Java Platform
for the AnagramGame project must also be at least JDK 5 or JDK 6, respectively.
You can change the Java Platform for the AnagramGame in the Libraries category in the Properties window.
- Right-click the Anagram Game project node and choose Run.
When you choose Run, the IDE builds and launches the Anagram Game application.
Exercise 2: Creating the AnagramsStats JMX Standard MBean and its Management interface
The goal of this exercise is to create a skeleton JMX Standard MBean,
which is composed of its implementation class and its management interface.
Perform the following steps to create the JMX Standard MBean.
- Confirm that the Anagram Game project is set as the main project.
- Choose File > New File (Ctrl-N).
- From the JMX category, select Standard MBean. Click Next.

- Enter the following information Name and Location panel:
- Class Name: AnagramsStats
- Location: Source Packages (default)
- Package: com.toy.anagrams.mbeans
- Description: Monitoring and Management of the Anagrams Game
- Click Finish.
When you click Finish the AnagramsStats MBean class and AnagramsStatsMBean
MBean interface are generated in the com.toy.anagrams.mbeans
package of the AnagramGame project. These are now several empty skeletons
that you will populate in the next exercise.
Exercise 3: Adding attributes, operation and notification to the AnagramsStats JMX Standard MBean
The goal of this exercise is to populate the generated MBean skeleton,
so that it monitors the time spent by the user to solve a new anagram and a JMX notification is sent
each time an anagram is solved.
The MBean will contain the following:
- Two Attributes named LastThinkingTime and NumResolvedAnagrams
- An Operation named resetAll.
- A notification of type AttributeChangeNotification. This notification is emitted when LastThinkingTime is updated.
Perform the following steps to populate the MBean skeleton.
- Open the AnagramsStats.java MBean implementation file in the NetBeans editor.
- Right-click in the source editor and select JMX > Add MBean Attributes in the popup menu.
- Add the LastThinkingTime attribute by clicking the Add Attribute button and
supplying the following information.
- Attribute Name: LastThinkingTime
- Type: int
- Access: ReadOnly
- Description: Elapsed time to solve last anagram
Note. Do not click OK yet!
- Click Add Attribute again and add the following NumSolvedAnagrams attribute. Click OK.
- Attribute Name: NumSolvedAnagrams
- Type: int
- Access: ReadOnly
- Description: Number of solved anagrams
The necessary code to expose the read only LastThinkingTime
and NumSolvedAnagrams attributes is generated in both the
AnagramsStats MBean class and its interface.
You can see the private fields declaration and the public getter methods.
More precisely, looking at the members view and at the generated code, you will notice
that the getLastThinkingTime and getNumSolvedAnagrams methods
are generated both in the AnagramsStats class and in its
AnagramsStatsMBean interface. The private fields lastThinkingTime
and numSolvedAnagrams of type int were also generated and will be used to
store the actual attribute values.
Next you will add three more attributes to keep track
of the minimum and maximum thinking time the user took, and of the current
anagram being proposed to the user.
- Right-click in the source editor and select JMX > Add MBean Attributes in the popup menu.
- Click the Add Attribute button and add the following attributes.
| Attribute Name |
Type |
Access |
Description |
| MinThinkingTime |
int |
ReadOnly |
Minimum elapsed time to solve an anagram |
| MaxThinkingTime |
int |
ReadOnly |
Maximum elapsed time to solve an anagram |
| CurrentAnagram |
String |
ReadOnly |
Current anagram to solve |
The dialog box should be similar to the following image.
Note. Notice that the attributes that you already created are listed in the dialog box.
- Click OK and save your changes.
- Right-click in the source editor and select JMX > Add MBeans Operations in the popup menu.
- Click Add Operation and add the resetAll() operation and specify the following details. Click OK.
- Operation Name: resetAll
- Return Type: void
- Parameters: (leave empty)
- Exceptions: (leave empty)
- Description: Reset MBean state
After you click OK you can see that the necessary code to expose the resetAll
operation was generated in both the AnagramsStats MBean class and its interface.
- Right-click in the source editor and select the JMX > Implement NotificationEmitter interface in the popup menu.
- Specify the following details in the Implement NotificationEmitter interface dialog box.
- Select Generate Delegation to Broadcaster. All methods
declared by the NotificationEmitter interface will be implemented
by delegating to a notification broadcaster. A notification broadcaster
simplifies the way the MBean will send notifications.
- Select Generate Private Seq Number and Accessor. Some code will be
generated to handle the unique sequence number value that must be added
to each notification that is sent.
- Click Add Notification. Specify the following details in the Notifications table.
- Notification Class: javax.management.AttributeChangeNotification
- Notification Type: (it is automatically set to ATTRIBUTE_CHANGE)
- Description: Anagram is Solved
Click OK.
You can see that the necessary code to implement the NotificationEmitter
interface was generated in the AnagramsStats MBean class.
You can see how the generated implementation delegates the handling of notifications
to the NotificationBroadcasterSupport class.
- Save your changes.
In this exercise you learned how to add attributes, operations and
notifications emission to an MBean using the JMX Wizard module.
The steps needed to populate your MBean with the necessary infrastructure
to expose the management information you want are now finished.
You now need to add internal logic to the AnagramsStats MBean
class implementation, then build the bridge between the MBean and the
Anagram Game application.
Exercise 4: Adding implementation code to the AnagramsStats JMX Standard MBean
In this exercise you will add some internal logic to the AnagramsStats MBean class implementation.
Perform the following steps to add the implementation code.
- The attributes already have their private fields declared, and nothing needs to be added
to their getter methods.
- The resetAll() method needs to be implemented. The generated body
is empty. When resetAll() is called, we simply set all counters
to 0. Add the following lines of code (in bold) in the resetAll() method body:
public void resetAll() {
minThinkingTime = 0;
maxThinkingTime = 0;
lastThinkingTime = 0;
numSolvedAnagrams = 0;
}
- You also need to add some implementation code that will do the following:
- calculate the thinking time the user took to solve the last anagram,
- calculate the minimum and maximum thinking times,
- increment the counter of solved anagrams,
- know wich is the current anagram,
- create and send a notification when an anagram is solved.
For that purpose you will add a private field startTime to store the
time at which the last anagram was presented to the user, two methods
startThinking() and stopThinking() to perform the operations
listed above, and a setCurrentAnagram() method.
Add the following code to AnagramsStats.java, e.g. at the end of the class implementation.
/*
* Methods exposed to Anagrams application to feed management with data.
*/
//Stores the time at which a new anagram is proposed to the user.
private long startTime;
/**
* A new Anagram is proposed to the user: store current time.
*/
public void startThinking() {
startTime = System.currentTimeMillis();
}
/**
* An Anagram has been resolved.
*/
public void stopThinking() {
//Update the number of resolved anagrams
numSolvedAnagrams++;
// Compute last, min and max thinking times
lastThinkingTime = (int) (System.currentTimeMillis() - startTime) / 1000 ;
minThinkingTime = (lastThinkingTime < minThinkingTime || minThinkingTime == 0) ?
lastThinkingTime :
minThinkingTime;
maxThinkingTime = (lastThinkingTime > maxThinkingTime) ?
lastThinkingTime :
maxThinkingTime;
//Create a JMX Notification
Notification notification = new Notification(AttributeChangeNotification.ATTRIBUTE_CHANGE,
this,
getNextSeqNumber(),
"Anagram solved: " + currentAnagram);
// Send a JMX notification.
broadcaster.sendNotification(notification);
}
/**
* Set latest anagram which has been computed by the Anagram application
*/
public void setCurrentAnagram(String currentAnagram) {
this.currentAnagram = currentAnagram;
}
Note that the three methods startThinking(), stopThinking() and
setCurrentAnagram() are not part of the MBean management interface, because they
are not declared in the AnagramsStatsMBean interface, but they are
public because they will be called by the Anagram Game application to tell the MBean
each time that a new anagram is presented to the user and when it is solved, and
which is the current anagram.
So, they are a necessary part of the bridge between the application and our MBean.
Notice also how a JMX notification of type ATTRIBUTE_CHANGE is sent
each time an anagram is solved.
You are now done with the MBean implementation.
In this section you added code and methods to allow the following:
- internal MBean state updates
- calls from the application
- sending of JMX notifications
Exercise 5: Connecting Management and the Application Together
In this exercise, we will add code to the Anagram Game application so that it
can access the MBean to pass management information.
Perform the following steps to
- Open Anagrams.java in the editor.
The Anagrams class in the com.toy.anagrams.ui package
is the main class of the Anagram Game application.
The file opens in the Editor's Design view because the Anagrams class is also the User Interface class.
- Click the Source button at the top of the Editor window to edit the class in the Source view.
- Add the following empty initManagement() private method to the Anagrams class:
after the Anagrams constructor.
/**
* JMX initialization:
* Create and register Anagrams MBean in Platform MBeanServer.
* Initialize thinking time and current anagram.
*/
private void initManagement() throws Exception {
}
- Add the following call to the initManagement() method at the end of
the Anagrams class constructor before the enclosing
curly brace marking the end of the constructor.
//JMX Management initialization
initManagement();
You also need to add a throws Exception clause to the
Anagrams() constructor and to the Main() method declarations
for your code to compile.
Here is what you should see at this stage [click to view larger image]:
- We now add the MBean registration code to the initManagement()
method, using the JMX Module MBean registration wizard:
In the Anagrams.java source editor window, right-click
inside the initManagement() method body,
select the JMX submenu and then the
"Generate MBean Registration..." action.
In the "Instantiate and Register MBean" panel that shows up,
keep the "Register Existing MBean" radio-button selected,
click the Browse button, choose the AnagramsStats MBean class and
click OK in the Browse panel. You should now see:
No need to change the automatically specified MBean Object Name and Constructor.
Click OK, and you will see the generated MBean registration code
in the initManagement() method body.
Best practice for naming your MBeans
- When naming your MBean, use the "type=" key in the Object Name. The value
of this key should be the MBean class (in our case AnagramsStats).
- In the case of a singleton MBean (an MBean that has a single instance within
your application), having this unique key is sufficient for naming purposes.
- Avoid creating too many domain names. Use your application Java package names.
You can also use the default domain name: not specifying a domain before the ObjectName
":" separator implicitly references the default domain.
Applying best practices will make the way you name your MBeans more formalized.
So, the ObjectName created by default in our case above is:
com.toy.anagrams.mbeans:type=AnagramsStats
In the context of this tutorial, an extra step is required. You want the
application to have access to the class implementing the management interface
(AnagramsStats). This is not a general rule but it can be useful
when your application needs to push data to an MBean. In this case, the
startThinking(), stopThinking() and setCurrentAnagram()
methods are not management methods but are used
by the Anagrams Game application to notify the
MBean that some events have occured. In turn, the MBean updates its state.
In order to make AnagramsStats accessible from the Anagrams
UI class, we need the Anagrams class to keep a direct reference to the
instance of the AnagramsStats MBean.
Therefore, you need to make the following changes to the code of the Anagrams.java file.
- Add the following private field to the Anagrams class.
// Reference to the AnagramsStats MBean
private AnagramsStats mbean;
- Initialize the reference to the AnagramsStats MBean in the
initManagement() method by modifying the generated MBean Registration
code so that it reads:
private void initManagement() throws Exception {
try { // Register MBean in Platform MBeanServer
mbean = new AnagramsStats();
ManagementFactory.getPlatformMBeanServer().
registerMBean(mbean,
new ObjectName("com.toy.anagrams.mbeans:type=AnagramsStats"));
} catch (JMException ex) {
ex.printStackTrace();
}
- Initialize the AnagramsStats MBean state:
when the Anagrams Game application starts up, an anagram is immediately displayed,
so we need to pass to the MBean the anagram string value and to start
computing thinking time. Copy and paste the lines below at the end of the
initManagement() method:
// When the Anagrams game is first displayed, a word is proposed to the user.
// We must start time computing and set the current anagram
mbean.startThinking();
mbean.setCurrentAnagram(wordLibrary.getScrambledWord(wordIdx));
Here is what you should see at this stage [click to view larger image]:
You now need to add code to track the user's anagram solving experience.
- Locate the nextTrialActionPerformed() method and paste the following code at the end of the
nextTrialActionPerformed() method.
//Update management statistics and values
try {
mbean.setCurrentAnagram(wordLibrary.getScrambledWord(wordIdx));
mbean.startThinking();
} catch (Exception e) {e.printStackTrace();}
Each time that a new anagram is proposed to the user, the code tells the MBean
which anagram it is and to start counting the user thinking time.
- Locate the guessedWordActionPerformed() method and add
the following lines to the code. Save your changes.
//Update management stats
try {
mbean.stopThinking();
} catch(Exception e) {e.printStackTrace();}
The stopThinking() method in the MBean is called each time that an anagram is guessed correctly.
You should now see the following in the editor [click to view larger image]:
You have now finished linking the JMX management layer to the application layer.
In the next section you will build and run the Anagrams Game application and
look at the exposed management information through the JConsole GUI.
Exercise 6: Running the Application with JConsole
In this exercise, you will learn how to build and run your project, and connect
JConsole to visualize the JVM state, as well as the application MBeans.
Perform the following steps to run the application and view the management information.
- A single step performs these three tasks: simply click the
"Run Main Project with Monitoring and Management" button in the toolbar (
)
You can also invoke the action from the Run menu in the main menu.
Note. The first time that you build and run the
application the IDE displays a warning dialog that informs you that the build.xml files will be updated.
You can click OK in the dialog.
You can follow the execution in the Output window.
The IDE will build and launch the Anagram game and will automatically open the JConsole window.
- Select the MBeans tab in the JConsole window.
- In the tree layout in the left pane, expand all the nodes under com.toy.anagrams.mbeans.
- Select the Notifications node and click on the Subscribe button at the
bottom so that JConsole will receive a new notification each time an anagram is solved.
- In the Anagrams Game window, and solve the first three or four anagrams.
The solutions to the anagrams (abstraction, ambiguous, arithmetic, backslash,...)
are contained in the WordLibrary class.
- In the JConsole window, and notice that it received notifications for each of the solutions.
- Click on the Attributes node and notice the attributes values are updated:
You can experiment with the JConsole interface and the Anagrams Game.
For example, if you invoke the management operation resetAll()
you will see that the MBean attribute values are reset to 0.
And now, you are done! You did a really good job, congratulations!
See Also
For more information, see the following: