Adding Java Management Extensions (JMX) Instrumentation to a Java Application
This tutorial needs a review. You can edit it in GitHub following these contribution guidelines. |
- Tutorial exercises
- Exercise 1: Creating the NetBeans sample Anagram Game project
- Exercise 2: Creating the AnagramsStats JMX Standard MBean and its Management interface
- Exercise 3: Adding attributes, operation and notification to the AnagramsStats JMX Standard MBean
- Exercise 4: Adding implementation code to the AnagramsStats JMX Standard MBean
- Exercise 5: Connecting Management and the Application Together
- Exercise 6: Running the Application with JConsole
- See Also
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
-
Exercise 1: Creating the NetBeans sample Anagram Game project
-
Exercise 2: Creating the AnagramsStats JMX Standard MBean and its Management interface
-
Exercise 3: Adding attributes, operation and notification to the AnagramsStats JMX Standard MBean
-
Exercise 4: Adding implementation code to the AnagramsStats JMX Standard MBean
-
Exercise 5: Connecting the management and the application together
Prerequisites
This tutorial assumes you have some basic knowledge of, or programming experience with, the following technologies.
-
JMX technology: + JMX online documentation+
-
Java technology: + Java SE Technologies at a Glance+
-
NetBeans IDE
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:
Software or Resource | Version Required |
---|---|
7.2, 7.3, 7.4, 8.0, Java version |
|
version 7 or 8 |
|
JMX plugin |
Available from NetBeans Update Center |
JConsole plugin |
Available from NetBeans Update Center |
To install the JMX and JConsole plugins, choose Tools > Plugins and download the module from the NetBeans Update Center.
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 7 or JDK 8. Click OK.
Note. To select JDK 7 or JDK 8, the Java Platform for the AnagramGame project must also be at least JDK 7 or JDK 8, 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
andNumResolvedAnagrams
-
An Operation named
resetAll
. -
A notification of type
AttributeChangeNotification
. This notification is emitted whenLastThinkingTime
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. WhenresetAll()
is called, we simply set all counters to 0. Add the following lines of code (in bold) in theresetAll()
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 theAnagrams
class: after theAnagrams
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 theAnagrams
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 surround the statement new Anagrams().setVisible(true);
with a try-catch in the Main()
method to compile. You can see the suggestion glyph in the left margin of the editor. You can place your insert cursor in the line in the code and type Alt-Enter to invoke the code hint in the source editor.
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 caseAnagramsStats
). -
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 theinitManagement()
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 theinitManagement()
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 thenextTrialActionPerformed()
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.
Notes. You might see a Connection Failed warning in the Java Monitoring & Management Console when the console attempts to connect to the Anagram Game process. For this tutorial you can click Insecure when you are prompted to authorize the connection.
-
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! *