Tutorial Download |
VisualVM is a tool for visualizing data sources. By default, it visualizes the following types of data sources—applications, hosts, snapshots, core dumps, heap dumps, and thread dumps. These data sources are visualized in VisualVM so that they can be monitored for purposes of analysis, management, and troubleshooting.
In this tutorial you will be introduced to the VisualVM APIs so that you can provide additional features to VisualVM. Principally, you will be shown how to get started using them and be given pointers for further resources, such as templates and samples.
In general, there are two types of reasons why you would want to extend VisualVM:
|
Entry points into VisualVM fall into the following categories:
A visual representation of the entry points into VisualVM:
Entry points into VisualVM are implemented via the factory pattern. In that light, the main VisualVM APIs are as follows:
To make your tabs extendable, the following API must be extended,
instead of com.sun.tools.visualvm.core.ui.DataSourceViewProvider:
com.sun.tools.visualvm.core.ui.PluggableDataSourceViewProvider
The lifecycle of a VisualVM plugin is determined by a ModuleInstall class, which comes from the NetBeans APIs. Whenever you implement a new entry point into VisualVM, you need to provide code for registering and unregistering the entry point implementation. The relevant initialization code must be provided in the ModuleInstall class. When the plugin is loaded into VisualVM, the ModuleInstall.restored method is the first method that is called from your plugin. That is the method that should initialize the entry points. When the plugin is uninstalled, or when VisualVM closes down, the plugin's entry points need to be deregistered, from the ModuleInstall.uninstalled method. You will be shown some typical registration/deregistration code in the "Hello World" scenario that follows.
When you are planning to extend VisualVM, you need to do the following:
Now, we'll say "Hello World". We will create a new tab that looks as follows:
There will be no data in our tab, we'll simply create it and add some placeholders for content.
Click Next and fill out the next step as follows:
Click Finish.
@Override public void restored() { HelloWorldViewProvider.initialize(); } @Override public void uninstalled() { HelloWorldViewProvider.unregister(); }
As you can see, we will define the above two methods in a class called "HelloWorldViewProvider", which we will define later. Therefore you can ignore the red error lines, because you will create the methods later.
class HelloWorldViewProvider extends DataSourceViewProvider<Application> { private static DataSourceViewProvider<Application> instance = new HelloWorldViewProvider(); @Override public boolean supportsViewFor(Application application) { //Always shown: return true; } @Override public synchronized DataSourceView createView(final Application application) { return new HelloWorldView(application); } static void initialize() { DataSourceViewsManager.sharedInstance().addViewProvider(instance, Application.class); } static void unregister() { DataSourceViewsManager.sharedInstance().removeViewProvider(instance); } }
By reading the Javadoc that you downloaded earlier, you'll know what the two overridden methods above are all about.
class HelloWorldView extends DataSourceView { private DataViewComponent dvc; //Reusing an image from the sources: private static final String IMAGE_PATH = "com/sun/tools/visualvm/coredump/resources/coredump.png"; // NOI18N public HelloWorldView(Application application) { super(application, "Hello World", new ImageIcon(Utilities.loadImage(IMAGE_PATH, true)).getImage(), 60, false); } @Override protected DataViewComponent createComponent() { //Data area for master view: JEditorPane generalDataArea = new JEditorPane(); generalDataArea.setBorder(BorderFactory.createEmptyBorder(14, 8, 14, 8)); //Panel, which we'll reuse in all four of our detail views for this sample: JPanel panel = new JPanel(); //Master view: DataViewComponent.MasterView masterView = new DataViewComponent.MasterView ("Hello World Overview", null, generalDataArea); //Configuration of master view: DataViewComponent.MasterViewConfiguration masterConfiguration = new DataViewComponent.MasterViewConfiguration(false); //Add the master view and configuration view to the component: dvc = new DataViewComponent(masterView, masterConfiguration); //Add configuration details to the component, which are the show/hide checkboxes at the top: dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration( "Hello World Details 1", true), DataViewComponent.TOP_LEFT); dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration( "Hello World Details 2", true), DataViewComponent.TOP_RIGHT); dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration( "Hello World Details 3 & 4", true), DataViewComponent.BOTTOM_RIGHT); //Add detail views to the component: dvc.addDetailsView(new DataViewComponent.DetailsView( "Hello World Details 1", null, 10, panel, null), DataViewComponent.TOP_LEFT); dvc.addDetailsView(new DataViewComponent.DetailsView( "Hello World Details 2", null, 10, panel, null), DataViewComponent.TOP_RIGHT); dvc.addDetailsView(new DataViewComponent.DetailsView( "Hello World Details 3", null, 10, panel, null), DataViewComponent.BOTTOM_RIGHT); dvc.addDetailsView(new DataViewComponent.DetailsView( "Hello World Details 4", null, 10, panel, null), DataViewComponent.BOTTOM_RIGHT); return dvc; } }
Congratulations you have completed the Hello World scenario!
If the instructions for the Hello World sample, as described above, do not work for you, do the following:
Click Next and then click Finish.
Now inspect the sources of the sample and compare them to your own to see where the problem is.
The NetBeans Plugin Portal provides wizards that you might find helpful when getting started extending VisualVM:
In each case, the Plugin Portal page describes the steps to take when using the template and it also shows you most of the code that is generated for you.
The NetBeans Plugin Portal provides a collection of 7 samples, covering the most common ways in which you would want to plug into VisualVM:
Go here to get the samples, which are described here on Javalobby.
When you check out the VisualVM sources, you will find that the following modules make up the application. Each provides a set of APIs that you can use to extend the module in question:
A brief overview of the API-related packages provided
by the VisualVM modules that you see above, together
with FAQs that you might have about concepts
relating to the packages in question:
Package | Description | Related FAQs |
---|---|---|
com.sun.tools.visualvm.core.datasource | Provides the classes that represent DataSources. A DataSource can either be an Application, a Host, a CoreDump, a SnapShot, or a custom-defined DataSource that is contributed by a third party plugin. | |
com.sun.tools.visualvm.core.datasupport | Provides listeners and interfaces for supporting data sources. | |
com.sun.tools.visualvm.application.views.monitor | Provides the entry point into the "Monitor" tab. | |
com.sun.tools.visualvm.application.views.overview | Provides the entry point into the "Overview" tab. | |
com.sun.tools.visualvm.application.views.threads | Provides the entry point into the "Threads" tab. | |
com.sun.tools.visualvm.core.explorer | Provides entry points into the explorer view. For example, you can create new menu items on a node in the explorer view, you can listen to changes, and you can specify what should happen when a node is expanded or collapsed. | |
com.sun.tools.visualvm.heapdump | Provides the entry point into the "Heap Dump" tab. | |
com.sun.tools.visualvm.core.model | Provides classes that define the backing model of new DataSources. For example, these classes are used for synchronization purposes. | |
com.sun.tools.visualvm.application.type | Provides predefined generic application types. For example, an application type is provided for Java Web Start applications, so that when an application is deployed via Java Web Start, a distinct text is shown in VisualVM, to easily identify the deployed application. There is also a default application type so that all applications are recognized in one way or another. | |
com.sun.tools.visualvm.core.datasource.descriptor | Provides classes that you need to use when creating new data sources, such as new application types. | |
com.sun.tools.visualvm.host | Provides a common interface for DataSources that represent a host, that is, localhost or remote host. | |
com.sun.tools.visualvm.jmx | Provides classes that let you work with Java Management Extensions (JMX). For example, you can check whether JMX is enabled for an application and then enable/disable functionality provided by your plugin. | |
com.sun.tools.visualvm.jvm | Provides classes that let you define functionality for specific versions of the JVM. For example, there is a "SunJVM_6" class, as well as a "SunJVM_7" class. Per class, you can check whether features, such as JVM monitoring, are enabled and then enable/disable functionality provided by your plugin. | |
com.sun.tools.visualvm.core.scheduler | Provides scheduler services. For example, it provides an interval based scheduler service that you can use to execute tasks at predefined intervals. | |
com.sun.tools.visualvm.application.snapshot | Provides entry points into snapshots. For example, you can retrieve a list of registered snapshots. | |
com.sun.tools.visualvm.threaddump | Provides the entry point into the "Thread Dump" tab. | |
com.sun.tools.visualvm.core.ui | Provides entry points that let you create new tabs and subtabs. For example, in addition to creating tabs and subtabs, you can define where they should be displayed relative to existing tabs and subtabs and define whether they are pluggable. | |
com.sun.tools.visualvm.core.ui.components | Provides the components that you can use to define the tabs and subtabs. For example, each tab is divided into a master area with four detail areas, each of which can have configuration areas for showing/hiding them. |
To continue learning about the VisualVM APIs, you are recommended to consult the following resources:
Note: Several APIs have changed since these blog entries were written, but they should at least give you an idea of what is involved in each particular scenario described.
The relevant blog entries are as follows: