Getting Started Extending VisualVM

Tutorial Download

Download the sample

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:

Contents

Introducing the VisualVM Entry Points

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:

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.

Preparing to Extend VisualVM

When you are planning to extend VisualVM, you need to do the following:

Creating a "Hello World" Plugin

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.

  1. In NetBeans IDE, choose File > New Project and then choose NetBeans Modules > Module. Click Next. Create a new NetBeans module called "HelloVisualVM" and make sure to specify that you want to build against the VisualVM binary that you registered earlier:

    Click Next and fill out the next step as follows:

    Click Finish.

  2. Right-click the "HelloVisualVM" project node and choose New > Other. In the New File dialog, use the "Module Installer" wizard, which will create the class that is called when the plugin is installed into VisualVM. Here's where you'll find the wizard in the New File dialog:

  3. Once you've completed the wizard, implement the ModuleInstall.restored method and the ModuleInstall.uninstalled methods as follows:

    @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.

  4. Now add a dependency on "VisualVM-Core", which provides the APIs into the VisualVM. Do this by right-clicking the project node, choosing "Properties", and then setting the dependency in the "Libraries" tab.

  5. Create a class called "HelloWorldViewProvider", as follows:

    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.

  6. Finally, we'll create our HelloWorldView class, which is created by our provider above:

    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;
    
        }
        
    }

  7. Right-click the project node and choose "Run". This will install the plugin in a new instance of VisualVM and you'll see your new tab, for all application types:

Congratulations you have completed the Hello World scenario!

Troubleshooting

If the instructions for the Hello World sample, as described above, do not work for you, do the following:

  1. Use the "Download Sample" link at the top of this page to download the sample.

  2. Install the downloaded NBM file into NetBeans IDE via Tools | Plugins | Downloaded.

  3. Open the New Project wizard (Ctrl-Shift-N) and find the sample in the Samples | NetBeans Modules category, as shown here:

  4. Complete the wizard and, if you have not set VisualVM as your NetBeans Platform, you will see the project, together with some error badges, as shown here:

  5. Choose Tools | NetBeans Platforms, click Add Platform, and browse to the installation folder of VisualVM, to register it:

    Click Next and then click Finish.

  6. Right-click the "HelloVisualVM" project node in the Projects window and choose Properties. In the Libraries panel, choose VisualVM as your NetBeans Platform. When you close the Project Properties dialog, the error marks should no longer be present.
  7. Run the project, and the result should be the same as the last step of the previous section.

Now inspect the sources of the sample and compare them to your own to see where the problem is.

Appendix A: VisualVM File Templates

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.

Appendix B: VisualVM API Samples

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.

Appendix C: VisualVM API Reference

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.

Appendix D: Further Reading

To continue learning about the VisualVM APIs, you are recommended to consult the following resources:

  1. VisualVM Javadoc. Get these from the "1.0 API Docs" link on the https://visualvm.dev.java.net/ page.
  2. VisualVM Developer FAQ. A complete list of typical questions that can be asked in relation to the VisualVM APIs, together with many code samples that answer them.
  3. VisualVM Sources. If you read the VisualVM sources, you will be able to answer several of your API implementation questions. For example, you can find several pluggable views in the sources that you can learn from when creating your own pluggable views.
  4. VisualVM Plugins. When you download the VisualVM sources, you will find that you have also downloaded the sources of a set of plugins. You can inspect these plugins and learn from them. Treat them as samples. At the time of writing, the plugins bundled with the sources are as follows:

  5. Blog entries by Geertjan Wielenga. Geertjan is the technical writer responsible for documenting the VisualVM APIs. While learning about the VisualVM APIs, he wrote a series of blog entries about the VisualVM APIs he was learning about.

    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: