changeset 13139:88e2545d5e6d

8043138: Attach API should not require jvmstat rmi protocol Reviewed-by: alanb, mchung, erikj, ihse
author jbachorik
date Fri, 13 Nov 2015 14:44:05 +0100
parents 59fce7947e90
children 26c671e2768b
files make/gensrc/Gensrc-jdk.jvmstat.gmk make/launcher/Launcher-jdk.jvmstat.gmk make/launcher/Launcher-jdk.jvmstat.rmi.gmk src/jdk.jvmstat.rmi/share/classes/META-INF/services/sun.jvmstat.monitor.MonitoredHostService src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/RemoteHost.java src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/RemoteVm.java src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/package.html src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostProvider.java src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostRmiService.java src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/PerfDataBuffer.java src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteMonitoredVm.java src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteVmManager.java src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/package.html src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/Jstatd.java src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/RemoteHostImpl.java src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/RemoteVmImpl.java src/jdk.jvmstat/share/classes/META-INF/services/sun.jvmstat.monitor.MonitoredHostService src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/remote/RemoteHost.java src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/remote/RemoteVm.java src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/remote/package.html src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractMonitoredVm.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostProvider.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostRmiService.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/PerfDataBuffer.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteMonitoredVm.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteVmManager.java src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/package.html src/jdk.jvmstat/share/classes/sun/tools/jstatd/Jstatd.java src/jdk.jvmstat/share/classes/sun/tools/jstatd/RemoteHostImpl.java src/jdk.jvmstat/share/classes/sun/tools/jstatd/RemoteVmImpl.java
diffstat 30 files changed, 1571 insertions(+), 1519 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/gensrc/Gensrc-jdk.jvmstat.gmk	Fri Nov 13 14:44:05 2015 +0100
@@ -0,0 +1,55 @@
+#
+# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+include GensrcCommon.gmk
+
+################################################################################
+
+define merge-providers
+	$(MKDIR) -p $(@D)
+	$(CAT) $^ > $@
+endef
+
+PROVIDER_FILE := META-INF/services/sun.jvmstat.monitor.MonitoredHostService
+
+# Merge the local and remote sevice providers into jdk.jvmstat/META-INF/services
+$(SUPPORT_OUTPUTDIR)/gensrc/jdk.jvmstat/$(PROVIDER_FILE): \
+    $(JDK_TOPDIR)/src/jdk.jvmstat/share/classes/$(PROVIDER_FILE) \
+    $(JDK_TOPDIR)/src/jdk.jvmstat.rmi/share/classes/$(PROVIDER_FILE)
+	$(merge-providers)
+
+# Copy the same service file into jdk.jvmstat.rmi so that they are kept the same.
+$(SUPPORT_OUTPUTDIR)/gensrc/jdk.jvmstat.rmi/$(PROVIDER_FILE): \
+    $(SUPPORT_OUTPUTDIR)/gensrc/jdk.jvmstat/$(PROVIDER_FILE)
+	$(install-file)
+
+################################################################################
+
+jdk.jvmstat: $(SUPPORT_OUTPUTDIR)/gensrc/jdk.jvmstat/$(PROVIDER_FILE) \
+    $(SUPPORT_OUTPUTDIR)/gensrc/jdk.jvmstat.rmi/$(PROVIDER_FILE)
+
+all: jdk.jvmstat
+
+.PHONY: all
\ No newline at end of file
--- a/make/launcher/Launcher-jdk.jvmstat.gmk	Sun Nov 29 20:27:38 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.  Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-include LauncherCommon.gmk
-
-$(eval $(call SetupBuildLauncher, jstatd, \
-    MAIN_CLASS := sun.tools.jstatd.Jstatd, \
-))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/launcher/Launcher-jdk.jvmstat.rmi.gmk	Fri Nov 13 14:44:05 2015 +0100
@@ -0,0 +1,30 @@
+#
+# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+include LauncherCommon.gmk
+
+$(eval $(call SetupBuildLauncher, jstatd, \
+    MAIN_CLASS := sun.tools.jstatd.Jstatd, \
+))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jvmstat.rmi/share/classes/META-INF/services/sun.jvmstat.monitor.MonitoredHostService	Fri Nov 13 14:44:05 2015 +0100
@@ -0,0 +1,1 @@
+sun.jvmstat.perfdata.monitor.protocol.rmi.MonitoredHostRmiService
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/RemoteHost.java	Fri Nov 13 14:44:05 2015 +0100
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.jvmstat.monitor.remote;
+
+import sun.jvmstat.monitor.*;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.io.IOException;
+
+/**
+ * Remote Interface for discovering and attaching to remote
+ * monitorable Java Virtual Machines.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public interface RemoteHost extends Remote {
+
+    /**
+     * Remote method to attach to a remote HotSpot Java Virtual Machine
+     * identified by <code>vmid</code>.
+     *
+     * @param vmid The identifier for the target virtual machine.
+     * @return RemoteVm - A remote object for accessing the remote Java
+     *                    Virtual Machine.
+     *
+     * @throws MonitorException Thrown when any other error is encountered
+     *                          while communicating with the target virtual
+     *                          machine.
+     * @throws RemoteException
+     *
+     */
+    RemoteVm attachVm(int vmid, String mode) throws RemoteException,
+                                                    MonitorException;
+
+    /**
+     * Remote method to detach from a remote HotSpot Java Virtual Machine
+     * identified by <code>vmid</code>.
+     *
+     * @param rvm The remote object for the target Java Virtual
+     *            Machine.
+     *
+     * @throws MonitorException Thrown when any other error is encountered
+     *                          while communicating with the target virtual
+     *                          machine.
+     * @throws RemoteException
+     */
+    void detachVm(RemoteVm rvm) throws RemoteException, MonitorException;
+
+    /**
+     * Get a list of Local Virtual Machine Identifiers for the active
+     * Java Virtual Machine the remote system. A Local Virtual Machine
+     * Identifier is also known as an <em>lvmid</em>.
+     *
+     * @return int[] - A array of <em>lvmid</em>s.
+     * @throws MonitorException Thrown when any other error is encountered
+     *                          while communicating with the target virtual
+     *                          machine.
+     * @throws RemoteException
+     */
+    int[] activeVms() throws RemoteException, MonitorException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/RemoteVm.java	Fri Nov 13 14:44:05 2015 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.jvmstat.monitor.remote;
+
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+/**
+ * Interface for accessing the instrumentation exported by a
+ * Java Virtual Machine running on a remote host.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public interface RemoteVm extends Remote {
+
+    /**
+     * Interface to get the bytes associated with the instrumentation
+     * for the remote Java Virtual Machine.
+     *
+     * @return byte[] - a byte array containing the current bytes
+     *                  for the instrumentation exported by the
+     *                  remote Java Virtual Machine.
+     * @throws RemoteException Thrown on any communication error
+     */
+    byte[] getBytes() throws RemoteException;
+
+    /**
+     * Interface to get the size of the instrumentation buffer
+     * for the target Java Virtual Machine.
+     *
+     * @return int - the size of the instrumentation buffer for the
+     *               remote Java Virtual Machine.
+     * @throws RemoteException Thrown on any communication error
+     */
+    int getCapacity() throws RemoteException;
+
+    /**
+     * Interface to return the Local Virtual Machine Identifier for
+     * the remote Java Virtual Machine. The Local Virtual Machine
+     * Identifier is also know as the <em>lvmid</em>.
+     *
+     * @throws RemoteException Thrown on any communication error
+     */
+    int getLocalVmId() throws RemoteException;
+
+    /**
+     * Interface to detach from the remote Java Virtual Machine.
+     *
+     * @throws RemoteException Thrown on any communication error
+     */
+    void detach() throws RemoteException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/package.html	Fri Nov 13 14:44:05 2015 +0100
@@ -0,0 +1,39 @@
+<!doctype html public "-//IETF//DTD HTML/EN">
+<html>
+<head>
+<!--
+ 
+
+ Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ This code is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License version 2 only, as
+ published by the Free Software Foundation.  Oracle designates this
+ particular file as subject to the "Classpath" exception as provided
+ by Oracle in the LICENSE file that accompanied this code.
+
+ This code is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ version 2 for more details (a copy is included in the LICENSE file that
+ accompanied this code).
+
+ You should have received a copy of the GNU General Public License version
+ 2 along with this work; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ or visit www.oracle.com if you need additional information or have any
+ questions.
+
+
+-->
+</head>
+<body bgcolor="white">
+<p>
+Provides interfaces supporting remote monitoring for instrumented
+HotSpot Java Virtual Machines.
+</p>
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostProvider.java	Fri Nov 13 14:44:05 2015 +0100
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.jvmstat.perfdata.monitor.protocol.rmi;
+
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.event.*;
+import sun.jvmstat.monitor.remote.*;
+import sun.jvmstat.perfdata.monitor.*;
+import java.util.*;
+import java.net.*;
+import java.io.*;
+import java.rmi.*;
+import java.util.HashMap;
+
+/**
+ * Concrete implementation of the MonitoredHost interface for the
+ * <em>rmi</em> protocol of the HotSpot PerfData monitoring implementation.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class MonitoredHostProvider extends MonitoredHost {
+    private static final String serverName = "/JStatRemoteHost";
+    private static final int DEFAULT_POLLING_INTERVAL = 1000;
+
+    private ArrayList<HostListener> listeners;
+    private NotifierTask task;
+    private HashSet<Integer> activeVms;
+    private RemoteVmManager vmManager;
+    private RemoteHost remoteHost;
+    private Timer timer;
+
+    /**
+     * Create a MonitoredHostProvider instance using the given HostIdentifier.
+     *
+     * @param hostId the host identifier for this MonitoredHost
+     * @throws MonitorException Thrown on any error encountered while
+     *                          communicating with the remote host.
+     */
+    public MonitoredHostProvider(HostIdentifier hostId)
+           throws MonitorException {
+        this.hostId = hostId;
+        this.listeners = new ArrayList<HostListener>();
+        this.interval = DEFAULT_POLLING_INTERVAL;
+        this.activeVms = new HashSet<Integer>();
+
+        String rmiName;
+        String sn = serverName;
+        String path = hostId.getPath();
+
+        if ((path != null) && (path.length() > 0)) {
+            sn = path;
+        }
+
+        if (hostId.getPort() != -1) {
+            rmiName = "rmi://" + hostId.getHost() + ":" + hostId.getPort() + sn;
+        } else {
+            rmiName = "rmi://" + hostId.getHost() + sn;
+        }
+
+        try {
+            remoteHost = (RemoteHost)Naming.lookup(rmiName);
+
+        } catch (RemoteException e) {
+            /*
+             * rmi registry not available
+             *
+             * Access control exceptions, where the rmi server refuses a
+             * connection based on policy file configuration, come through
+             * here on the client side. Unfortunately, the RemoteException
+             * doesn't contain enough information to determine the true cause
+             * of the exception. So, we have to output a rather generic message.
+             */
+            String message = "RMI Registry not available at "
+                             + hostId.getHost();
+
+            if (hostId.getPort() == -1) {
+                message = message + ":"
+                          + java.rmi.registry.Registry.REGISTRY_PORT;
+            } else {
+                message = message + ":" + hostId.getPort();
+            }
+
+            if (e.getMessage() != null) {
+                throw new MonitorException(message + "\n" + e.getMessage(), e);
+            } else {
+                throw new MonitorException(message, e);
+            }
+
+        } catch (NotBoundException e) {
+            // no server with given name
+            String message = e.getMessage();
+            if (message == null) message = rmiName;
+            throw new MonitorException("RMI Server " + message
+                                       + " not available", e);
+        } catch (MalformedURLException e) {
+            // this is a programming problem
+            e.printStackTrace();
+            throw new IllegalArgumentException("Malformed URL: " + rmiName);
+        }
+        this.vmManager = new RemoteVmManager(remoteHost);
+        this.timer = new Timer(true);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public MonitoredVm getMonitoredVm(VmIdentifier vmid)
+                       throws MonitorException {
+        return getMonitoredVm(vmid, DEFAULT_POLLING_INTERVAL);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public MonitoredVm getMonitoredVm(VmIdentifier vmid, int interval)
+                       throws MonitorException {
+        VmIdentifier nvmid = null;
+        try {
+            nvmid = hostId.resolve(vmid);
+            RemoteVm rvm = remoteHost.attachVm(vmid.getLocalVmId(),
+                                               vmid.getMode());
+            RemoteMonitoredVm rmvm = new RemoteMonitoredVm(rvm, nvmid, timer,
+                                                           interval);
+            rmvm.attach();
+            return rmvm;
+
+        } catch (RemoteException e) {
+            throw new MonitorException("Remote Exception attaching to "
+                                       + nvmid.toString(), e);
+        } catch (URISyntaxException e) {
+            /*
+             * the VmIdentifier is expected to be a valid and should resolve
+             * easonably against the host identifier. A URISyntaxException
+             * here is most likely a programming error.
+             */
+            throw new IllegalArgumentException("Malformed URI: "
+                                               + vmid.toString(), e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void detach(MonitoredVm vm) throws MonitorException {
+        RemoteMonitoredVm rmvm = (RemoteMonitoredVm)vm;
+        rmvm.detach();
+        try {
+            remoteHost.detachVm(rmvm.getRemoteVm());
+
+        } catch (RemoteException e) {
+            throw new MonitorException("Remote Exception detaching from "
+                                       + vm.getVmIdentifier().toString(), e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void addHostListener(HostListener listener) {
+        synchronized(listeners) {
+            listeners.add(listener);
+            if (task == null) {
+                task = new NotifierTask();
+                timer.schedule(task, 0, interval);
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void removeHostListener(HostListener listener) {
+        /*
+         * XXX: if a disconnect method is added, make sure it calls
+         * this method to unregister this object from the watcher. otherwise,
+         * an unused MonitoredHostProvider instance may go uncollected.
+         */
+        synchronized(listeners) {
+            listeners.remove(listener);
+            if (listeners.isEmpty() && (task != null)) {
+                task.cancel();
+                task = null;
+            }
+        }
+    }
+
+    public void setInterval(int newInterval) {
+        synchronized(listeners) {
+            if (newInterval == interval) {
+                return;
+            }
+
+            int oldInterval = interval;
+            super.setInterval(newInterval);
+
+            if (task != null) {
+                task.cancel();
+                NotifierTask oldTask = task;
+                task = new NotifierTask();
+                CountedTimerTaskUtils.reschedule(timer, oldTask, task,
+                                                 oldInterval, newInterval);
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Set<Integer> activeVms() throws MonitorException {
+        return vmManager.activeVms();
+    }
+
+    /**
+     * Fire VmStatusChangeEvent events to HostListener objects
+     *
+     * @param active Set of Integer objects containing the local
+     *               Vm Identifiers of the active JVMs
+     * @param started Set of Integer objects containing the local
+     *                Vm Identifiers of new JVMs started since last
+     *                interval.
+     * @param terminated Set of Integer objects containing the local
+     *                   Vm Identifiers of terminated JVMs since last
+     *                   interval.
+     */
+    @SuppressWarnings("unchecked") // Cast of result of clone
+    private void fireVmStatusChangedEvents(Set<Integer> active, Set<Integer> started,
+                                           Set<Integer> terminated) {
+        ArrayList<HostListener> registered = null;
+        VmStatusChangeEvent ev = null;
+
+        synchronized(listeners) {
+            registered = (ArrayList)listeners.clone();
+        }
+
+        for (Iterator<HostListener> i = registered.iterator(); i.hasNext(); /* empty */) {
+            HostListener l = i.next();
+            if (ev == null) {
+                ev = new VmStatusChangeEvent(this, active, started, terminated);
+            }
+            l.vmStatusChanged(ev);
+        }
+    }
+
+    /**
+     * Fire hostDisconnectEvent events.
+     */
+    @SuppressWarnings("unchecked") // Cast of result of clone
+    void fireDisconnectedEvents() {
+        ArrayList<HostListener> registered = null;
+        HostEvent ev = null;
+
+        synchronized(listeners) {
+            registered = (ArrayList)listeners.clone();
+        }
+
+        for (Iterator<HostListener> i = registered.iterator(); i.hasNext(); /* empty */) {
+            HostListener l = i.next();
+            if (ev == null) {
+                ev = new HostEvent(this);
+            }
+            l.disconnected(ev);
+        }
+    }
+
+    /**
+     * class to poll the remote machine and generate local event notifications.
+     */
+    private class NotifierTask extends CountedTimerTask {
+        public void run() {
+            super.run();
+
+            // save the last set of active JVMs
+            Set<Integer> lastActiveVms = activeVms;
+
+            try {
+                // get the current set of active JVMs
+                activeVms = (HashSet<Integer>)vmManager.activeVms();
+
+            } catch (MonitorException e) {
+                // XXX: use logging api
+                System.err.println("MonitoredHostProvider: polling task "
+                                   + "caught MonitorException:");
+                e.printStackTrace();
+
+                // mark the HostManager as errored and notify listeners
+                setLastException(e);
+                fireDisconnectedEvents();
+            }
+
+            if (activeVms.isEmpty()) {
+                return;
+            }
+
+            Set<Integer> startedVms = new HashSet<>();
+            Set<Integer> terminatedVms = new HashSet<>();
+
+            for (Iterator<Integer> i = activeVms.iterator(); i.hasNext(); /* empty */ ) {
+                Integer vmid = i.next();
+                if (!lastActiveVms.contains(vmid)) {
+                    // a new file has been detected, add to set
+                    startedVms.add(vmid);
+                }
+            }
+
+            for (Iterator<Integer> i = lastActiveVms.iterator(); i.hasNext();
+                    /* empty */ ) {
+                Integer o = i.next();
+                if (!activeVms.contains(o)) {
+                    // JVM has terminated, remove it from the active list
+                    terminatedVms.add(o);
+                }
+            }
+
+            if (!startedVms.isEmpty() || !terminatedVms.isEmpty()) {
+                fireVmStatusChangedEvents(activeVms, startedVms, terminatedVms);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostRmiService.java	Fri Nov 13 14:44:05 2015 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.jvmstat.perfdata.monitor.protocol.rmi;
+
+import sun.jvmstat.monitor.HostIdentifier;
+import sun.jvmstat.monitor.MonitorException;
+import sun.jvmstat.monitor.MonitoredHost;
+import sun.jvmstat.monitor.MonitoredHostService;
+
+public final class MonitoredHostRmiService implements MonitoredHostService {
+
+    @Override
+    public MonitoredHost getMonitoredHost(HostIdentifier hostId) throws MonitorException {
+        return new MonitoredHostProvider(hostId);
+    }
+
+    @Override
+    public String getScheme() {
+        return "rmi";
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/PerfDataBuffer.java	Fri Nov 13 14:44:05 2015 +0100
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.jvmstat.perfdata.monitor.protocol.rmi;
+
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.remote.*;
+import sun.jvmstat.perfdata.monitor.*;
+import java.io.*;
+import java.rmi.RemoteException;
+import java.nio.ByteBuffer;
+
+/**
+ * The concrete PerfDataBuffer implementation for the <em>rmi:</em>
+ * protocol for the HotSpot PerfData monitoring implementation.
+ * <p>
+ * This class is responsible for acquiring the instrumentation buffer
+ * data for a remote target HotSpot Java Virtual Machine.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class PerfDataBuffer extends AbstractPerfDataBuffer {
+
+    private RemoteVm rvm;
+
+    /**
+     * Create a PerfDataBuffer instance for accessing the specified
+     * instrumentation buffer.
+     *
+     * @param rvm the proxy to the remote MonitredVm object
+     * @param lvmid the local Java Virtual Machine Identifier of the
+     *              remote target.
+     *
+     * @throws MonitorException
+     */
+    public PerfDataBuffer(RemoteVm rvm, int lvmid) throws MonitorException {
+
+        this.rvm = rvm;
+        try {
+            ByteBuffer buffer = ByteBuffer.allocate(rvm.getCapacity());
+            sample(buffer);
+            createPerfDataBuffer(buffer, lvmid);
+
+        } catch (RemoteException e) {
+            throw new MonitorException("Could not read data for remote JVM "
+                                       + lvmid, e);
+        }
+    }
+
+    /**
+     * Get a copy of the remote instrumentation buffer.
+     *<p>
+     * The data in the remote instrumentation buffer is copied into
+     * the local byte buffer.
+     *
+     * @param buffer the buffer to receive the copy of the remote
+     *               instrumentation buffer.
+     * @throws RemoteException Thrown on any communications errors with
+     *                         the remote system.
+     */
+    public void sample(ByteBuffer buffer) throws RemoteException {
+        assert buffer != null;
+        assert rvm != null;
+        synchronized(buffer) {
+            buffer.clear();
+            buffer.put(rvm.getBytes());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteMonitoredVm.java	Fri Nov 13 14:44:05 2015 +0100
@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.jvmstat.perfdata.monitor.protocol.rmi;
+
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.event.*;
+import sun.jvmstat.monitor.remote.*;
+import sun.jvmstat.perfdata.monitor.*;
+import java.lang.reflect.*;
+import java.util.*;
+import java.io.*;
+import java.nio.ByteBuffer;
+import java.rmi.*;
+
+/**
+ * Concrete implementation of the AbstractMonitoredVm class for the
+ * <em>rmi:</em> protocol for the HotSpot PerfData monitoring implementation.
+ * <p>
+ * This class provides the ability to acquire to the instrumentation buffer
+ * of a live, remote target Java Virtual Machine through an RMI server.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class RemoteMonitoredVm extends AbstractMonitoredVm {
+
+    private ArrayList<VmListener> listeners;
+    private NotifierTask notifierTask;
+    private SamplerTask samplerTask;
+    private Timer timer;
+
+    private RemoteVm rvm;
+    private ByteBuffer updateBuffer;
+
+    /**
+     * Create a RemoteMonitoredVm instance.
+     *
+     * @param rvm the proxy to the remote MonitoredVm instance.
+     * @param vmid the vm identifier specifying the remot target JVM
+     * @param timer the timer used to run polling tasks
+     * @param interval the sampling interval
+     */
+    public RemoteMonitoredVm(RemoteVm rvm, VmIdentifier vmid,
+                             Timer timer, int interval)
+           throws MonitorException {
+        super(vmid, interval);
+        this.rvm = rvm;
+        pdb = new PerfDataBuffer(rvm, vmid.getLocalVmId());
+        this.listeners = new ArrayList<VmListener>();
+        this.timer = timer;
+    }
+
+    /**
+     * Method to attach to the remote MonitoredVm.
+     */
+    public void attach() throws MonitorException {
+        updateBuffer = pdb.getByteBuffer().duplicate();
+
+        // if continuous sampling is requested, register with the sampler thread
+        if (interval > 0) {
+            samplerTask = new SamplerTask();
+            timer.schedule(samplerTask, 0, interval);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void detach() {
+        try {
+            if (interval > 0) {
+                if (samplerTask != null) {
+                    samplerTask.cancel();
+                    samplerTask = null;
+                }
+                if (notifierTask != null) {
+                    notifierTask.cancel();
+                    notifierTask = null;
+                }
+                sample();
+            }
+        } catch (RemoteException e) {
+            // XXX: - use logging api? throw an exception instead?
+            System.err.println("Could not read data for remote JVM " + vmid);
+            e.printStackTrace();
+
+        } finally {
+            super.detach();
+        }
+    }
+
+    /**
+     * Get a copy of the remote instrumentation buffer.
+     *<p>
+     * The data in the remote instrumentation buffer is copied into
+     * a local byte buffer.
+     *
+     * @throws RemoteException Thrown on any communications errors with
+     *                         the remote system.
+     */
+    public void sample() throws RemoteException {
+        assert updateBuffer != null;
+        ((PerfDataBuffer)pdb).sample(updateBuffer);
+    }
+
+    /**
+     * Get the proxy to the remote MonitoredVm.
+     *
+     * @return RemoteVm - the proxy to the remote MonitoredVm.
+     */
+    public RemoteVm getRemoteVm() {
+        return rvm;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void addVmListener(VmListener l) {
+        synchronized(listeners) {
+            listeners.add(l);
+            if (notifierTask == null) {
+                notifierTask = new NotifierTask();
+                timer.schedule(notifierTask, 0, interval);
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void removeVmListener(VmListener l) {
+        synchronized(listeners) {
+            listeners.remove(l);
+            if (listeners.isEmpty() && (notifierTask != null)) {
+                notifierTask.cancel();
+                notifierTask = null;
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setInterval(int newInterval) {
+        synchronized(listeners) {
+            if (newInterval == interval) {
+                return;
+            }
+
+            int oldInterval = interval;
+            super.setInterval(newInterval);
+
+            if (samplerTask != null) {
+                samplerTask.cancel();
+                SamplerTask oldSamplerTask = samplerTask;
+                samplerTask = new SamplerTask();
+                CountedTimerTaskUtils.reschedule(timer, oldSamplerTask,
+                                                 samplerTask, oldInterval,
+                                                 newInterval);
+            }
+            if (notifierTask != null) {
+                notifierTask.cancel();
+                NotifierTask oldNotifierTask = notifierTask;
+                notifierTask = new NotifierTask();
+                CountedTimerTaskUtils.reschedule(timer, oldNotifierTask,
+                                                 notifierTask, oldInterval,
+                                                 newInterval);
+            }
+        }
+    }
+
+    /**
+     * Fire MonitoredVmStructureChanged events.
+     *
+     * @param inserted List of Monitor objects inserted.
+     * @param removed List of Monitor objects removed.
+     */
+    @SuppressWarnings("unchecked") // Cast of result of clone
+    void fireMonitorStatusChangedEvents(List<Monitor> inserted, List<Monitor> removed) {
+        ArrayList<VmListener> registered = null;
+        MonitorStatusChangeEvent ev = null;
+
+        synchronized(listeners) {
+            registered = (ArrayList)listeners.clone();
+        }
+
+        for (Iterator<VmListener> i = registered.iterator(); i.hasNext(); /* empty */) {
+            VmListener l = i.next();
+            if (ev == null) {
+                ev = new MonitorStatusChangeEvent(this, inserted, removed);
+            }
+            l.monitorStatusChanged(ev);
+        }
+    }
+
+    /**
+     * Fire MonitoredVmStructureChanged events.
+     */
+    @SuppressWarnings("unchecked") // Cast of result of clone
+    void fireMonitorsUpdatedEvents() {
+        ArrayList<VmListener> registered = null;
+        VmEvent ev = null;
+
+        synchronized(listeners) {
+            registered = (ArrayList)listeners.clone();
+        }
+
+        for (Iterator<VmListener> i = registered.iterator(); i.hasNext(); /* empty */) {
+            VmListener l = i.next();
+            if (ev == null) {
+                ev = new VmEvent(this);
+            }
+            l.monitorsUpdated(ev);
+        }
+    }
+
+    /*
+     * Timer Tasks. There are two separate timer tasks here. The SamplerTask
+     * is active whenever we are attached to the remote JVM with a periodic
+     * sampling interval > 0. The NotifierTask is only active if a VmListener
+     * has registered with this RemoteMonitoredVm instance. Also, in the future
+     * we may want to run these tasks at different intervals. Currently,
+     * they run at the same interval and some significant work may
+     * need to be done to complete the separation of these two intervals.
+     */
+
+    /**
+     * Class to periodically check the state of the defined monitors
+     * for the remote MonitoredVm instance and to notify listeners of
+     * any detected changes.
+     */
+    private class NotifierTask extends CountedTimerTask {
+        public void run() {
+            super.run();
+            try {
+                MonitorStatus status = getMonitorStatus();
+
+                List<Monitor> inserted = status.getInserted();
+                List<Monitor> removed = status.getRemoved();
+
+                if (!inserted.isEmpty() || !removed.isEmpty()) {
+                    fireMonitorStatusChangedEvents(inserted, removed);
+                }
+            } catch (MonitorException e) {
+                // XXX: use logging api? fire disconnect events? mark errored?
+                // fireDisconnectedEvents();
+                System.err.println("Exception updating monitors for "
+                                   + getVmIdentifier());
+                e.printStackTrace();
+                // XXX: should we cancle the notifierTask here?
+                // this.cancel();
+            }
+        }
+    }
+
+    /**
+     * Class to periodically sample the remote instrumentation byte buffer
+     * and refresh the local copy. Registered listeners are notified of
+     * the completion of a sampling event.
+     */
+    private class SamplerTask extends CountedTimerTask {
+        public void run() {
+            super.run();
+            try {
+                sample();
+                fireMonitorsUpdatedEvents();
+
+            } catch (RemoteException e) {
+                // XXX: use logging api, mark vm as errored.
+                System.err.println("Exception taking sample for "
+                                   + getVmIdentifier());
+                e.printStackTrace();
+                this.cancel();
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteVmManager.java	Fri Nov 13 14:44:05 2015 +0100
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.jvmstat.perfdata.monitor.protocol.rmi;
+
+import java.util.*;
+import java.util.regex.*;
+import java.io.*;
+import java.rmi.RemoteException;
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.event.*;
+import sun.jvmstat.monitor.remote.*;
+
+/**
+ * Class for managing the RemoteMonitoredVm instances on a remote system.
+ * <p>
+ * This class is responsible for the mechanism that detects the active
+ * HotSpot Java Virtual Machines on the remote host and possibly for a
+ * specific user. The ability to detect all possible HotSpot Java Virtual
+ * Machines on the remote host may be limited by the permissions of the
+ * principal running the RMI server application on the remote host.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class RemoteVmManager {
+
+    private RemoteHost remoteHost;
+    private String user;
+
+    /**
+     * Creates a RemoteVmManager instance for the remote system.
+     * <p>
+     * Manages RemoteMonitordVm instances for which the principal
+     * running the remote server has appropriate permissions.
+     *
+     * @param remoteHost the remote proxy object to the RMI server on
+     *                   the remote system.
+     */
+    public RemoteVmManager(RemoteHost remoteHost) {
+        this(remoteHost, null);
+    }
+
+    /**
+     * Creates a RemoteVmManager instance for the given user.
+     * <p>
+     * Manages RemoteMonitoredVm instances for all remote Java Virtual
+     * machines owned by the specified user on the remote system. The
+     * RMI server on the remote system must have the appropriate permissions
+     * to access the named users Java Virtual Machines.
+     *
+     * @param remoteHost the remote proxy object to the RMI server on
+     *                   the remote system.
+     * @param user the name of the user
+     */
+    public RemoteVmManager(RemoteHost remoteHost, String user) {
+        this.user = user;
+        this.remoteHost = remoteHost;
+    }
+
+    /**
+     * Return the current set of monitorable Java Virtual Machines.
+     * <p>
+     * The set returned by this method depends on the user name passed
+     * to the constructor. If no user name was specified, then this
+     * method will return all candidate JVMs on the system. Otherwise,
+     * only the JVMs for the given user will be returned. This assumes
+     * that the RMI server process has the appropriate permissions to
+     * access the target set of JVMs.
+     *
+     * @return Set - the Set of monitorable Java Virtual Machines
+     */
+    public Set<Integer> activeVms() throws MonitorException {
+        int[] active = null;
+
+        try {
+            active = remoteHost.activeVms();
+
+        } catch (RemoteException e) {
+            throw new MonitorException("Error communicating with remote host: "
+                                       + e.getMessage(), e);
+        }
+
+        Set<Integer> activeSet = new HashSet<Integer>(active.length);
+
+        for (int i = 0; i < active.length; i++) {
+            activeSet.add(active[i]);
+        }
+
+        return activeSet;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/package.html	Fri Nov 13 14:44:05 2015 +0100
@@ -0,0 +1,47 @@
+<!doctype html public "-//IETF//DTD HTML/EN">
+<html>
+<head>
+<!--
+ 
+
+ Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ This code is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License version 2 only, as
+ published by the Free Software Foundation.  Oracle designates this
+ particular file as subject to the "Classpath" exception as provided
+ by Oracle in the LICENSE file that accompanied this code.
+
+ This code is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ version 2 for more details (a copy is included in the LICENSE file that
+ accompanied this code).
+
+ You should have received a copy of the GNU General Public License version
+ 2 along with this work; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ or visit www.oracle.com if you need additional information or have any
+ questions.
+
+-->
+</head>
+<body bgcolor="white">
+<p>
+Provides the implementation classes for the <em>rmi:</em> protocol for
+the HotSpot PerfData instrumentation buffer monitoring implementation.
+</p>
+<p>
+The <em>rmi:</em> protocol is the default protocol for the PerfData
+implementation when a hostname is specified as part of a HostIdentifier
+or VMIdentifier. It communicates with an RMI server on the remote machine
+that provides functions to get a list of available Java Virtual Machines
+and to acquire a copy of a Java Virtual Machine's instrumentation buffer.
+The RMI server may or may not use the PerfData implementation on the
+remote host to acquire this information. The <em>jstatd</em> server
+provides a PerfData implementation of the RMI server.
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/Jstatd.java	Fri Nov 13 14:44:05 2015 +0100
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.tools.jstatd;
+
+import java.rmi.*;
+import java.rmi.server.*;
+import java.rmi.registry.Registry;
+import java.rmi.registry.LocateRegistry;
+import java.net.MalformedURLException;
+import sun.jvmstat.monitor.remote.*;
+
+/**
+ * Application providing remote access to the jvmstat instrumentation
+ * exported by local Java Virtual Machine processes. Remote access is
+ * provided through an RMI interface.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class Jstatd {
+
+    private static Registry registry;
+    private static int port = -1;
+    private static boolean startRegistry = true;
+
+    private static void printUsage() {
+        System.err.println("usage: jstatd [-nr] [-p port] [-n rminame]");
+    }
+
+    static void bind(String name, RemoteHostImpl remoteHost)
+                throws RemoteException, MalformedURLException, Exception {
+
+        try {
+            Naming.rebind(name, remoteHost);
+        } catch (java.rmi.ConnectException e) {
+            /*
+             * either the registry is not running or we cannot contact it.
+             * start an internal registry if requested.
+             */
+            if (startRegistry && registry == null) {
+                int localport = (port < 0) ? Registry.REGISTRY_PORT : port;
+                registry = LocateRegistry.createRegistry(localport);
+                bind(name, remoteHost);
+            } else {
+                throw e;
+            }
+        }
+    }
+
+    @SuppressWarnings("deprecation") // Use of RMISecurityManager
+    public static void main(String[] args) {
+        String rminame = null;
+        int argc = 0;
+
+        for ( ; (argc < args.length) && (args[argc].startsWith("-")); argc++) {
+            String arg = args[argc];
+
+            if (arg.compareTo("-nr") == 0) {
+                startRegistry = false;
+            } else if (arg.startsWith("-p")) {
+                if (arg.compareTo("-p") != 0) {
+                    port = Integer.parseInt(arg.substring(2));
+                } else {
+                  argc++;
+                  if (argc >= args.length) {
+                      printUsage();
+                      System.exit(1);
+                  }
+                  port = Integer.parseInt(args[argc]);
+                }
+            } else if (arg.startsWith("-n")) {
+                if (arg.compareTo("-n") != 0) {
+                    rminame = arg.substring(2);
+                } else {
+                    argc++;
+                    if (argc >= args.length) {
+                        printUsage();
+                        System.exit(1);
+                    }
+                    rminame = args[argc];
+                }
+            } else {
+                printUsage();
+                System.exit(1);
+            }
+        }
+
+        if (argc < args.length) {
+            printUsage();
+            System.exit(1);
+        }
+
+        if (System.getSecurityManager() == null) {
+            System.setSecurityManager(new RMISecurityManager());
+        }
+
+        StringBuilder name = new StringBuilder();
+
+        if (port >= 0) {
+            name.append("//:").append(port);
+        }
+
+        if (rminame == null) {
+            rminame = "JStatRemoteHost";
+        }
+
+        name.append("/").append(rminame);
+
+        try {
+            // use 1.5.0 dynamically generated subs.
+            System.setProperty("java.rmi.server.ignoreSubClasses", "true");
+            RemoteHostImpl remoteHost = new RemoteHostImpl();
+            RemoteHost stub = (RemoteHost) UnicastRemoteObject.exportObject(
+                    remoteHost, 0);
+            bind(name.toString(), remoteHost);
+            System.out.println("jstatd started (bound to " + name.toString() + ")");
+            System.out.flush();
+        } catch (MalformedURLException e) {
+            if (rminame != null) {
+                System.out.println("Bad RMI server name: " + rminame);
+            } else {
+                System.out.println("Bad RMI URL: " + name);
+            }
+            e.printStackTrace(System.out);
+            System.exit(1);
+        } catch (java.rmi.ConnectException e) {
+            // could not attach to or create a registry
+            System.out.println("Could not contact RMI registry");
+            e.printStackTrace(System.out);
+            System.exit(1);
+        } catch (RemoteException e) {
+            System.out.println("Could not bind " + name + " to RMI Registry");
+            e.printStackTrace(System.out);
+            System.exit(1);
+        } catch (Exception e) {
+            System.out.println("Could not create remote object");
+            e.printStackTrace(System.out);
+            System.exit(1);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/RemoteHostImpl.java	Fri Nov 13 14:44:05 2015 +0100
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.tools.jstatd;
+
+import java.util.*;
+import java.nio.*;
+import java.io.*;
+import java.net.*;
+import java.rmi.*;
+import java.rmi.server.*;
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.event.*;
+import sun.jvmstat.monitor.remote.*;
+
+/**
+ * Concrete implementation of the RemoteHost interface for the HotSpot
+ * PerfData <em>rmi:</em> protocol.
+ * <p>
+ * This class provides remote access to the instrumentation exported
+ * by HotSpot Java Virtual Machines through the PerfData shared memory
+ * interface.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class RemoteHostImpl implements RemoteHost, HostListener {
+
+    private MonitoredHost monitoredHost;
+    private Set<Integer> activeVms;
+
+    public RemoteHostImpl() throws MonitorException {
+        try {
+            monitoredHost = MonitoredHost.getMonitoredHost("localhost");
+        } catch (URISyntaxException e) { }
+
+        activeVms = monitoredHost.activeVms();
+        monitoredHost.addHostListener(this);
+    }
+
+    public RemoteVm attachVm(int lvmid, String mode)
+                    throws RemoteException, MonitorException {
+        Integer v = lvmid;
+        RemoteVm stub = null;
+        StringBuilder sb = new StringBuilder();
+
+        sb.append("local://").append(lvmid).append("@localhost");
+        if (mode != null) {
+            sb.append("?mode=").append(mode);
+        }
+
+        String vmidStr = sb.toString();
+
+        try {
+            VmIdentifier vmid = new VmIdentifier(vmidStr);
+            MonitoredVm mvm = monitoredHost.getMonitoredVm(vmid);
+            RemoteVmImpl rvm = new RemoteVmImpl((BufferedMonitoredVm)mvm);
+            stub = (RemoteVm) UnicastRemoteObject.exportObject(rvm, 0);
+        }
+        catch (URISyntaxException e) {
+            throw new RuntimeException("Malformed VmIdentifier URI: "
+                                       + vmidStr, e);
+        }
+        return stub;
+    }
+
+    public void detachVm(RemoteVm rvm) throws RemoteException {
+        rvm.detach();
+    }
+
+    public int[] activeVms() throws MonitorException {
+        Object[] vms = null;
+        int[] vmids = null;
+
+        vms = monitoredHost.activeVms().toArray();
+        vmids = new int[vms.length];
+
+        for (int i = 0; i < vmids.length; i++) {
+            vmids[i] = ((Integer)vms[i]).intValue();
+        }
+        return vmids;
+    }
+
+    public void vmStatusChanged(VmStatusChangeEvent ev) {
+        synchronized(this.activeVms) {
+            activeVms.retainAll(ev.getActive());
+        }
+    }
+
+    public void disconnected(HostEvent ev) {
+        // we only monitor the local host, so this event shouldn't occur.
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/RemoteVmImpl.java	Fri Nov 13 14:44:05 2015 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.tools.jstatd;
+
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.remote.*;
+
+/**
+ * Concrete implementation of the RemoteVm interface for the HotSpot PerfData
+ * shared memory implementation of the jvmstat monitoring APIs. This class
+ * providing remote access to the instrumentation exported by a local HotSpot
+ * Java Virtual Machine. The instrumentation buffer is shipped in whole to
+ * the remote machine, which is responsible for parsing and provide access
+ * to the contained data.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class RemoteVmImpl implements RemoteVm {
+
+    private BufferedMonitoredVm mvm;
+
+    RemoteVmImpl(BufferedMonitoredVm mvm) {
+        this.mvm = mvm;
+    }
+
+    public byte[] getBytes() {
+        return mvm.getBytes();
+    }
+
+    public int getCapacity() {
+        return mvm.getCapacity();
+    }
+
+    public void detach() {
+        mvm.detach();
+    }
+
+    public int getLocalVmId() {
+        return mvm.getVmIdentifier().getLocalVmId();
+    }
+}
--- a/src/jdk.jvmstat/share/classes/META-INF/services/sun.jvmstat.monitor.MonitoredHostService	Sun Nov 29 20:27:38 2015 +0000
+++ b/src/jdk.jvmstat/share/classes/META-INF/services/sun.jvmstat.monitor.MonitoredHostService	Fri Nov 13 14:44:05 2015 +0100
@@ -1,3 +1,2 @@
 sun.jvmstat.perfdata.monitor.protocol.file.MonitoredHostFileService
 sun.jvmstat.perfdata.monitor.protocol.local.MonitoredHostLocalService
-sun.jvmstat.perfdata.monitor.protocol.rmi.MonitoredHostRmiService
--- a/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/remote/RemoteHost.java	Sun Nov 29 20:27:38 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.jvmstat.monitor.remote;
-
-import sun.jvmstat.monitor.*;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.io.IOException;
-
-/**
- * Remote Interface for discovering and attaching to remote
- * monitorable Java Virtual Machines.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public interface RemoteHost extends Remote {
-
-    /**
-     * Remote method to attach to a remote HotSpot Java Virtual Machine
-     * identified by <code>vmid</code>.
-     *
-     * @param vmid The identifier for the target virtual machine.
-     * @return RemoteVm - A remote object for accessing the remote Java
-     *                    Virtual Machine.
-     *
-     * @throws MonitorException Thrown when any other error is encountered
-     *                          while communicating with the target virtual
-     *                          machine.
-     * @throws RemoteException
-     *
-     */
-    RemoteVm attachVm(int vmid, String mode) throws RemoteException,
-                                                    MonitorException;
-
-    /**
-     * Remote method to detach from a remote HotSpot Java Virtual Machine
-     * identified by <code>vmid</code>.
-     *
-     * @param rvm The remote object for the target Java Virtual
-     *            Machine.
-     *
-     * @throws MonitorException Thrown when any other error is encountered
-     *                          while communicating with the target virtual
-     *                          machine.
-     * @throws RemoteException
-     */
-    void detachVm(RemoteVm rvm) throws RemoteException, MonitorException;
-
-    /**
-     * Get a list of Local Virtual Machine Identifiers for the active
-     * Java Virtual Machine the remote system. A Local Virtual Machine
-     * Identifier is also known as an <em>lvmid</em>.
-     *
-     * @return int[] - A array of <em>lvmid</em>s.
-     * @throws MonitorException Thrown when any other error is encountered
-     *                          while communicating with the target virtual
-     *                          machine.
-     * @throws RemoteException
-     */
-    int[] activeVms() throws RemoteException, MonitorException;
-}
--- a/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/remote/RemoteVm.java	Sun Nov 29 20:27:38 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.jvmstat.monitor.remote;
-
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-/**
- * Interface for accessing the instrumentation exported by a
- * Java Virtual Machine running on a remote host.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public interface RemoteVm extends Remote {
-
-    /**
-     * Interface to get the bytes associated with the instrumentation
-     * for the remote Java Virtual Machine.
-     *
-     * @return byte[] - a byte array containing the current bytes
-     *                  for the instrumentation exported by the
-     *                  remote Java Virtual Machine.
-     * @throws RemoteException Thrown on any communication error
-     */
-    byte[] getBytes() throws RemoteException;
-
-    /**
-     * Interface to get the size of the instrumentation buffer
-     * for the target Java Virtual Machine.
-     *
-     * @return int - the size of the instrumentation buffer for the
-     *               remote Java Virtual Machine.
-     * @throws RemoteException Thrown on any communication error
-     */
-    int getCapacity() throws RemoteException;
-
-    /**
-     * Interface to return the Local Virtual Machine Identifier for
-     * the remote Java Virtual Machine. The Local Virtual Machine
-     * Identifier is also know as the <em>lvmid</em>.
-     *
-     * @throws RemoteException Thrown on any communication error
-     */
-    int getLocalVmId() throws RemoteException;
-
-    /**
-     * Interface to detach from the remote Java Virtual Machine.
-     *
-     * @throws RemoteException Thrown on any communication error
-     */
-    void detach() throws RemoteException;
-}
--- a/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/remote/package.html	Sun Nov 29 20:27:38 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-<!doctype html public "-//IETF//DTD HTML/EN">
-<html>
-<head>
-<!--
- 
-
- Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-
- This code is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License version 2 only, as
- published by the Free Software Foundation.  Oracle designates this
- particular file as subject to the "Classpath" exception as provided
- by Oracle in the LICENSE file that accompanied this code.
-
- This code is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- version 2 for more details (a copy is included in the LICENSE file that
- accompanied this code).
-
- You should have received a copy of the GNU General Public License version
- 2 along with this work; if not, write to the Free Software Foundation,
- Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-
- Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- or visit www.oracle.com if you need additional information or have any
- questions.
-
-
--->
-</head>
-<body bgcolor="white">
-<p>
-Provides interfaces supporting remote monitoring for instrumented
-HotSpot Java Virtual Machines.
-</p>
-</body>
-</html>
--- a/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractMonitoredVm.java	Sun Nov 29 20:27:38 2015 +0000
+++ b/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractMonitoredVm.java	Fri Nov 13 14:44:05 2015 +0100
@@ -26,11 +26,8 @@
 package sun.jvmstat.perfdata.monitor;
 
 import java.util.List;
-import java.lang.reflect.*;
-import java.io.*;
 
 import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.remote.*;
 import sun.jvmstat.monitor.event.VmListener;
 
 /**
--- a/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostProvider.java	Sun Nov 29 20:27:38 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,343 +0,0 @@
-/*
- * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.jvmstat.perfdata.monitor.protocol.rmi;
-
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.event.*;
-import sun.jvmstat.monitor.remote.*;
-import sun.jvmstat.perfdata.monitor.*;
-import java.util.*;
-import java.net.*;
-import java.io.*;
-import java.rmi.*;
-import java.util.HashMap;
-
-/**
- * Concrete implementation of the MonitoredHost interface for the
- * <em>rmi</em> protocol of the HotSpot PerfData monitoring implementation.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class MonitoredHostProvider extends MonitoredHost {
-    private static final String serverName = "/JStatRemoteHost";
-    private static final int DEFAULT_POLLING_INTERVAL = 1000;
-
-    private ArrayList<HostListener> listeners;
-    private NotifierTask task;
-    private HashSet<Integer> activeVms;
-    private RemoteVmManager vmManager;
-    private RemoteHost remoteHost;
-    private Timer timer;
-
-    /**
-     * Create a MonitoredHostProvider instance using the given HostIdentifier.
-     *
-     * @param hostId the host identifier for this MonitoredHost
-     * @throws MonitorException Thrown on any error encountered while
-     *                          communicating with the remote host.
-     */
-    public MonitoredHostProvider(HostIdentifier hostId)
-           throws MonitorException {
-        this.hostId = hostId;
-        this.listeners = new ArrayList<HostListener>();
-        this.interval = DEFAULT_POLLING_INTERVAL;
-        this.activeVms = new HashSet<Integer>();
-
-        String rmiName;
-        String sn = serverName;
-        String path = hostId.getPath();
-
-        if ((path != null) && (path.length() > 0)) {
-            sn = path;
-        }
-
-        if (hostId.getPort() != -1) {
-            rmiName = "rmi://" + hostId.getHost() + ":" + hostId.getPort() + sn;
-        } else {
-            rmiName = "rmi://" + hostId.getHost() + sn;
-        }
-
-        try {
-            remoteHost = (RemoteHost)Naming.lookup(rmiName);
-
-        } catch (RemoteException e) {
-            /*
-             * rmi registry not available
-             *
-             * Access control exceptions, where the rmi server refuses a
-             * connection based on policy file configuration, come through
-             * here on the client side. Unfortunately, the RemoteException
-             * doesn't contain enough information to determine the true cause
-             * of the exception. So, we have to output a rather generic message.
-             */
-            String message = "RMI Registry not available at "
-                             + hostId.getHost();
-
-            if (hostId.getPort() == -1) {
-                message = message + ":"
-                          + java.rmi.registry.Registry.REGISTRY_PORT;
-            } else {
-                message = message + ":" + hostId.getPort();
-            }
-
-            if (e.getMessage() != null) {
-                throw new MonitorException(message + "\n" + e.getMessage(), e);
-            } else {
-                throw new MonitorException(message, e);
-            }
-
-        } catch (NotBoundException e) {
-            // no server with given name
-            String message = e.getMessage();
-            if (message == null) message = rmiName;
-            throw new MonitorException("RMI Server " + message
-                                       + " not available", e);
-        } catch (MalformedURLException e) {
-            // this is a programming problem
-            e.printStackTrace();
-            throw new IllegalArgumentException("Malformed URL: " + rmiName);
-        }
-        this.vmManager = new RemoteVmManager(remoteHost);
-        this.timer = new Timer(true);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public MonitoredVm getMonitoredVm(VmIdentifier vmid)
-                       throws MonitorException {
-        return getMonitoredVm(vmid, DEFAULT_POLLING_INTERVAL);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public MonitoredVm getMonitoredVm(VmIdentifier vmid, int interval)
-                       throws MonitorException {
-        VmIdentifier nvmid = null;
-        try {
-            nvmid = hostId.resolve(vmid);
-            RemoteVm rvm = remoteHost.attachVm(vmid.getLocalVmId(),
-                                               vmid.getMode());
-            RemoteMonitoredVm rmvm = new RemoteMonitoredVm(rvm, nvmid, timer,
-                                                           interval);
-            rmvm.attach();
-            return rmvm;
-
-        } catch (RemoteException e) {
-            throw new MonitorException("Remote Exception attaching to "
-                                       + nvmid.toString(), e);
-        } catch (URISyntaxException e) {
-            /*
-             * the VmIdentifier is expected to be a valid and should resolve
-             * easonably against the host identifier. A URISyntaxException
-             * here is most likely a programming error.
-             */
-            throw new IllegalArgumentException("Malformed URI: "
-                                               + vmid.toString(), e);
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void detach(MonitoredVm vm) throws MonitorException {
-        RemoteMonitoredVm rmvm = (RemoteMonitoredVm)vm;
-        rmvm.detach();
-        try {
-            remoteHost.detachVm(rmvm.getRemoteVm());
-
-        } catch (RemoteException e) {
-            throw new MonitorException("Remote Exception detaching from "
-                                       + vm.getVmIdentifier().toString(), e);
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void addHostListener(HostListener listener) {
-        synchronized(listeners) {
-            listeners.add(listener);
-            if (task == null) {
-                task = new NotifierTask();
-                timer.schedule(task, 0, interval);
-            }
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void removeHostListener(HostListener listener) {
-        /*
-         * XXX: if a disconnect method is added, make sure it calls
-         * this method to unregister this object from the watcher. otherwise,
-         * an unused MonitoredHostProvider instance may go uncollected.
-         */
-        synchronized(listeners) {
-            listeners.remove(listener);
-            if (listeners.isEmpty() && (task != null)) {
-                task.cancel();
-                task = null;
-            }
-        }
-    }
-
-    public void setInterval(int newInterval) {
-        synchronized(listeners) {
-            if (newInterval == interval) {
-                return;
-            }
-
-            int oldInterval = interval;
-            super.setInterval(newInterval);
-
-            if (task != null) {
-                task.cancel();
-                NotifierTask oldTask = task;
-                task = new NotifierTask();
-                CountedTimerTaskUtils.reschedule(timer, oldTask, task,
-                                                 oldInterval, newInterval);
-            }
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public Set<Integer> activeVms() throws MonitorException {
-        return vmManager.activeVms();
-    }
-
-    /**
-     * Fire VmStatusChangeEvent events to HostListener objects
-     *
-     * @param active Set of Integer objects containing the local
-     *               Vm Identifiers of the active JVMs
-     * @param started Set of Integer objects containing the local
-     *                Vm Identifiers of new JVMs started since last
-     *                interval.
-     * @param terminated Set of Integer objects containing the local
-     *                   Vm Identifiers of terminated JVMs since last
-     *                   interval.
-     */
-    @SuppressWarnings("unchecked") // Cast of result of clone
-    private void fireVmStatusChangedEvents(Set<Integer> active, Set<Integer> started,
-                                           Set<Integer> terminated) {
-        ArrayList<HostListener> registered = null;
-        VmStatusChangeEvent ev = null;
-
-        synchronized(listeners) {
-            registered = (ArrayList)listeners.clone();
-        }
-
-        for (Iterator<HostListener> i = registered.iterator(); i.hasNext(); /* empty */) {
-            HostListener l = i.next();
-            if (ev == null) {
-                ev = new VmStatusChangeEvent(this, active, started, terminated);
-            }
-            l.vmStatusChanged(ev);
-        }
-    }
-
-    /**
-     * Fire hostDisconnectEvent events.
-     */
-    @SuppressWarnings("unchecked") // Cast of result of clone
-    void fireDisconnectedEvents() {
-        ArrayList<HostListener> registered = null;
-        HostEvent ev = null;
-
-        synchronized(listeners) {
-            registered = (ArrayList)listeners.clone();
-        }
-
-        for (Iterator<HostListener> i = registered.iterator(); i.hasNext(); /* empty */) {
-            HostListener l = i.next();
-            if (ev == null) {
-                ev = new HostEvent(this);
-            }
-            l.disconnected(ev);
-        }
-    }
-
-    /**
-     * class to poll the remote machine and generate local event notifications.
-     */
-    private class NotifierTask extends CountedTimerTask {
-        public void run() {
-            super.run();
-
-            // save the last set of active JVMs
-            Set<Integer> lastActiveVms = activeVms;
-
-            try {
-                // get the current set of active JVMs
-                activeVms = (HashSet<Integer>)vmManager.activeVms();
-
-            } catch (MonitorException e) {
-                // XXX: use logging api
-                System.err.println("MonitoredHostProvider: polling task "
-                                   + "caught MonitorException:");
-                e.printStackTrace();
-
-                // mark the HostManager as errored and notify listeners
-                setLastException(e);
-                fireDisconnectedEvents();
-            }
-
-            if (activeVms.isEmpty()) {
-                return;
-            }
-
-            Set<Integer> startedVms = new HashSet<>();
-            Set<Integer> terminatedVms = new HashSet<>();
-
-            for (Iterator<Integer> i = activeVms.iterator(); i.hasNext(); /* empty */ ) {
-                Integer vmid = i.next();
-                if (!lastActiveVms.contains(vmid)) {
-                    // a new file has been detected, add to set
-                    startedVms.add(vmid);
-                }
-            }
-
-            for (Iterator<Integer> i = lastActiveVms.iterator(); i.hasNext();
-                    /* empty */ ) {
-                Integer o = i.next();
-                if (!activeVms.contains(o)) {
-                    // JVM has terminated, remove it from the active list
-                    terminatedVms.add(o);
-                }
-            }
-
-            if (!startedVms.isEmpty() || !terminatedVms.isEmpty()) {
-                fireVmStatusChangedEvents(activeVms, startedVms, terminatedVms);
-            }
-        }
-    }
-}
--- a/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostRmiService.java	Sun Nov 29 20:27:38 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.jvmstat.perfdata.monitor.protocol.rmi;
-
-import sun.jvmstat.monitor.HostIdentifier;
-import sun.jvmstat.monitor.MonitorException;
-import sun.jvmstat.monitor.MonitoredHost;
-import sun.jvmstat.monitor.MonitoredHostService;
-
-public final class MonitoredHostRmiService implements MonitoredHostService {
-
-    @Override
-    public MonitoredHost getMonitoredHost(HostIdentifier hostId) throws MonitorException {
-        return new MonitoredHostProvider(hostId);
-    }
-
-    @Override
-    public String getScheme() {
-        return "rmi";
-    }
-
-}
--- a/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/PerfDataBuffer.java	Sun Nov 29 20:27:38 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.jvmstat.perfdata.monitor.protocol.rmi;
-
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.remote.*;
-import sun.jvmstat.perfdata.monitor.*;
-import java.io.*;
-import java.rmi.RemoteException;
-import java.nio.ByteBuffer;
-
-/**
- * The concrete PerfDataBuffer implementation for the <em>rmi:</em>
- * protocol for the HotSpot PerfData monitoring implementation.
- * <p>
- * This class is responsible for acquiring the instrumentation buffer
- * data for a remote target HotSpot Java Virtual Machine.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class PerfDataBuffer extends AbstractPerfDataBuffer {
-
-    private RemoteVm rvm;
-
-    /**
-     * Create a PerfDataBuffer instance for accessing the specified
-     * instrumentation buffer.
-     *
-     * @param rvm the proxy to the remote MonitredVm object
-     * @param lvmid the local Java Virtual Machine Identifier of the
-     *              remote target.
-     *
-     * @throws MonitorException
-     */
-    public PerfDataBuffer(RemoteVm rvm, int lvmid) throws MonitorException {
-
-        this.rvm = rvm;
-        try {
-            ByteBuffer buffer = ByteBuffer.allocate(rvm.getCapacity());
-            sample(buffer);
-            createPerfDataBuffer(buffer, lvmid);
-
-        } catch (RemoteException e) {
-            throw new MonitorException("Could not read data for remote JVM "
-                                       + lvmid, e);
-        }
-    }
-
-    /**
-     * Get a copy of the remote instrumentation buffer.
-     *<p>
-     * The data in the remote instrumentation buffer is copied into
-     * the local byte buffer.
-     *
-     * @param buffer the buffer to receive the copy of the remote
-     *               instrumentation buffer.
-     * @throws RemoteException Thrown on any communications errors with
-     *                         the remote system.
-     */
-    public void sample(ByteBuffer buffer) throws RemoteException {
-        assert buffer != null;
-        assert rvm != null;
-        synchronized(buffer) {
-            buffer.clear();
-            buffer.put(rvm.getBytes());
-        }
-    }
-}
--- a/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteMonitoredVm.java	Sun Nov 29 20:27:38 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,300 +0,0 @@
-/*
- * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.jvmstat.perfdata.monitor.protocol.rmi;
-
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.event.*;
-import sun.jvmstat.monitor.remote.*;
-import sun.jvmstat.perfdata.monitor.*;
-import java.lang.reflect.*;
-import java.util.*;
-import java.io.*;
-import java.nio.ByteBuffer;
-import java.rmi.*;
-
-/**
- * Concrete implementation of the AbstractMonitoredVm class for the
- * <em>rmi:</em> protocol for the HotSpot PerfData monitoring implementation.
- * <p>
- * This class provides the ability to acquire to the instrumentation buffer
- * of a live, remote target Java Virtual Machine through an RMI server.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class RemoteMonitoredVm extends AbstractMonitoredVm {
-
-    private ArrayList<VmListener> listeners;
-    private NotifierTask notifierTask;
-    private SamplerTask samplerTask;
-    private Timer timer;
-
-    private RemoteVm rvm;
-    private ByteBuffer updateBuffer;
-
-    /**
-     * Create a RemoteMonitoredVm instance.
-     *
-     * @param rvm the proxy to the remote MonitoredVm instance.
-     * @param vmid the vm identifier specifying the remot target JVM
-     * @param timer the timer used to run polling tasks
-     * @param interval the sampling interval
-     */
-    public RemoteMonitoredVm(RemoteVm rvm, VmIdentifier vmid,
-                             Timer timer, int interval)
-           throws MonitorException {
-        super(vmid, interval);
-        this.rvm = rvm;
-        pdb = new PerfDataBuffer(rvm, vmid.getLocalVmId());
-        this.listeners = new ArrayList<VmListener>();
-        this.timer = timer;
-    }
-
-    /**
-     * Method to attach to the remote MonitoredVm.
-     */
-    public void attach() throws MonitorException {
-        updateBuffer = pdb.getByteBuffer().duplicate();
-
-        // if continuous sampling is requested, register with the sampler thread
-        if (interval > 0) {
-            samplerTask = new SamplerTask();
-            timer.schedule(samplerTask, 0, interval);
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void detach() {
-        try {
-            if (interval > 0) {
-                if (samplerTask != null) {
-                    samplerTask.cancel();
-                    samplerTask = null;
-                }
-                if (notifierTask != null) {
-                    notifierTask.cancel();
-                    notifierTask = null;
-                }
-                sample();
-            }
-        } catch (RemoteException e) {
-            // XXX: - use logging api? throw an exception instead?
-            System.err.println("Could not read data for remote JVM " + vmid);
-            e.printStackTrace();
-
-        } finally {
-            super.detach();
-        }
-    }
-
-    /**
-     * Get a copy of the remote instrumentation buffer.
-     *<p>
-     * The data in the remote instrumentation buffer is copied into
-     * a local byte buffer.
-     *
-     * @throws RemoteException Thrown on any communications errors with
-     *                         the remote system.
-     */
-    public void sample() throws RemoteException {
-        assert updateBuffer != null;
-        ((PerfDataBuffer)pdb).sample(updateBuffer);
-    }
-
-    /**
-     * Get the proxy to the remote MonitoredVm.
-     *
-     * @return RemoteVm - the proxy to the remote MonitoredVm.
-     */
-    public RemoteVm getRemoteVm() {
-        return rvm;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void addVmListener(VmListener l) {
-        synchronized(listeners) {
-            listeners.add(l);
-            if (notifierTask == null) {
-                notifierTask = new NotifierTask();
-                timer.schedule(notifierTask, 0, interval);
-            }
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void removeVmListener(VmListener l) {
-        synchronized(listeners) {
-            listeners.remove(l);
-            if (listeners.isEmpty() && (notifierTask != null)) {
-                notifierTask.cancel();
-                notifierTask = null;
-            }
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void setInterval(int newInterval) {
-        synchronized(listeners) {
-            if (newInterval == interval) {
-                return;
-            }
-
-            int oldInterval = interval;
-            super.setInterval(newInterval);
-
-            if (samplerTask != null) {
-                samplerTask.cancel();
-                SamplerTask oldSamplerTask = samplerTask;
-                samplerTask = new SamplerTask();
-                CountedTimerTaskUtils.reschedule(timer, oldSamplerTask,
-                                                 samplerTask, oldInterval,
-                                                 newInterval);
-            }
-            if (notifierTask != null) {
-                notifierTask.cancel();
-                NotifierTask oldNotifierTask = notifierTask;
-                notifierTask = new NotifierTask();
-                CountedTimerTaskUtils.reschedule(timer, oldNotifierTask,
-                                                 notifierTask, oldInterval,
-                                                 newInterval);
-            }
-        }
-    }
-
-    /**
-     * Fire MonitoredVmStructureChanged events.
-     *
-     * @param inserted List of Monitor objects inserted.
-     * @param removed List of Monitor objects removed.
-     */
-    @SuppressWarnings("unchecked") // Cast of result of clone
-    void fireMonitorStatusChangedEvents(List<Monitor> inserted, List<Monitor> removed) {
-        ArrayList<VmListener> registered = null;
-        MonitorStatusChangeEvent ev = null;
-
-        synchronized(listeners) {
-            registered = (ArrayList)listeners.clone();
-        }
-
-        for (Iterator<VmListener> i = registered.iterator(); i.hasNext(); /* empty */) {
-            VmListener l = i.next();
-            if (ev == null) {
-                ev = new MonitorStatusChangeEvent(this, inserted, removed);
-            }
-            l.monitorStatusChanged(ev);
-        }
-    }
-
-    /**
-     * Fire MonitoredVmStructureChanged events.
-     */
-    @SuppressWarnings("unchecked") // Cast of result of clone
-    void fireMonitorsUpdatedEvents() {
-        ArrayList<VmListener> registered = null;
-        VmEvent ev = null;
-
-        synchronized(listeners) {
-            registered = (ArrayList)listeners.clone();
-        }
-
-        for (Iterator<VmListener> i = registered.iterator(); i.hasNext(); /* empty */) {
-            VmListener l = i.next();
-            if (ev == null) {
-                ev = new VmEvent(this);
-            }
-            l.monitorsUpdated(ev);
-        }
-    }
-
-    /*
-     * Timer Tasks. There are two separate timer tasks here. The SamplerTask
-     * is active whenever we are attached to the remote JVM with a periodic
-     * sampling interval > 0. The NotifierTask is only active if a VmListener
-     * has registered with this RemoteMonitoredVm instance. Also, in the future
-     * we may want to run these tasks at different intervals. Currently,
-     * they run at the same interval and some significant work may
-     * need to be done to complete the separation of these two intervals.
-     */
-
-    /**
-     * Class to periodically check the state of the defined monitors
-     * for the remote MonitoredVm instance and to notify listeners of
-     * any detected changes.
-     */
-    private class NotifierTask extends CountedTimerTask {
-        public void run() {
-            super.run();
-            try {
-                MonitorStatus status = getMonitorStatus();
-
-                List<Monitor> inserted = status.getInserted();
-                List<Monitor> removed = status.getRemoved();
-
-                if (!inserted.isEmpty() || !removed.isEmpty()) {
-                    fireMonitorStatusChangedEvents(inserted, removed);
-                }
-            } catch (MonitorException e) {
-                // XXX: use logging api? fire disconnect events? mark errored?
-                // fireDisconnectedEvents();
-                System.err.println("Exception updating monitors for "
-                                   + getVmIdentifier());
-                e.printStackTrace();
-                // XXX: should we cancle the notifierTask here?
-                // this.cancel();
-            }
-        }
-    }
-
-    /**
-     * Class to periodically sample the remote instrumentation byte buffer
-     * and refresh the local copy. Registered listeners are notified of
-     * the completion of a sampling event.
-     */
-    private class SamplerTask extends CountedTimerTask {
-        public void run() {
-            super.run();
-            try {
-                sample();
-                fireMonitorsUpdatedEvents();
-
-            } catch (RemoteException e) {
-                // XXX: use logging api, mark vm as errored.
-                System.err.println("Exception taking sample for "
-                                   + getVmIdentifier());
-                e.printStackTrace();
-                this.cancel();
-            }
-        }
-    }
-}
--- a/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteVmManager.java	Sun Nov 29 20:27:38 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.jvmstat.perfdata.monitor.protocol.rmi;
-
-import java.util.*;
-import java.util.regex.*;
-import java.io.*;
-import java.rmi.RemoteException;
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.event.*;
-import sun.jvmstat.monitor.remote.*;
-
-/**
- * Class for managing the RemoteMonitoredVm instances on a remote system.
- * <p>
- * This class is responsible for the mechanism that detects the active
- * HotSpot Java Virtual Machines on the remote host and possibly for a
- * specific user. The ability to detect all possible HotSpot Java Virtual
- * Machines on the remote host may be limited by the permissions of the
- * principal running the RMI server application on the remote host.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class RemoteVmManager {
-
-    private RemoteHost remoteHost;
-    private String user;
-
-    /**
-     * Creates a RemoteVmManager instance for the remote system.
-     * <p>
-     * Manages RemoteMonitordVm instances for which the principal
-     * running the remote server has appropriate permissions.
-     *
-     * @param remoteHost the remote proxy object to the RMI server on
-     *                   the remote system.
-     */
-    public RemoteVmManager(RemoteHost remoteHost) {
-        this(remoteHost, null);
-    }
-
-    /**
-     * Creates a RemoteVmManager instance for the given user.
-     * <p>
-     * Manages RemoteMonitoredVm instances for all remote Java Virtual
-     * machines owned by the specified user on the remote system. The
-     * RMI server on the remote system must have the appropriate permissions
-     * to access the named users Java Virtual Machines.
-     *
-     * @param remoteHost the remote proxy object to the RMI server on
-     *                   the remote system.
-     * @param user the name of the user
-     */
-    public RemoteVmManager(RemoteHost remoteHost, String user) {
-        this.user = user;
-        this.remoteHost = remoteHost;
-    }
-
-    /**
-     * Return the current set of monitorable Java Virtual Machines.
-     * <p>
-     * The set returned by this method depends on the user name passed
-     * to the constructor. If no user name was specified, then this
-     * method will return all candidate JVMs on the system. Otherwise,
-     * only the JVMs for the given user will be returned. This assumes
-     * that the RMI server process has the appropriate permissions to
-     * access the target set of JVMs.
-     *
-     * @return Set - the Set of monitorable Java Virtual Machines
-     */
-    public Set<Integer> activeVms() throws MonitorException {
-        int[] active = null;
-
-        try {
-            active = remoteHost.activeVms();
-
-        } catch (RemoteException e) {
-            throw new MonitorException("Error communicating with remote host: "
-                                       + e.getMessage(), e);
-        }
-
-        Set<Integer> activeSet = new HashSet<Integer>(active.length);
-
-        for (int i = 0; i < active.length; i++) {
-            activeSet.add(active[i]);
-        }
-
-        return activeSet;
-    }
-}
--- a/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/package.html	Sun Nov 29 20:27:38 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-<!doctype html public "-//IETF//DTD HTML/EN">
-<html>
-<head>
-<!--
- 
-
- Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-
- This code is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License version 2 only, as
- published by the Free Software Foundation.  Oracle designates this
- particular file as subject to the "Classpath" exception as provided
- by Oracle in the LICENSE file that accompanied this code.
-
- This code is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- version 2 for more details (a copy is included in the LICENSE file that
- accompanied this code).
-
- You should have received a copy of the GNU General Public License version
- 2 along with this work; if not, write to the Free Software Foundation,
- Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-
- Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- or visit www.oracle.com if you need additional information or have any
- questions.
-
--->
-</head>
-<body bgcolor="white">
-<p>
-Provides the implementation classes for the <em>rmi:</em> protocol for
-the HotSpot PerfData instrumentation buffer monitoring implementation.
-</p>
-<p>
-The <em>rmi:</em> protocol is the default protocol for the PerfData
-implementation when a hostname is specified as part of a HostIdentifier
-or VMIdentifier. It communicates with an RMI server on the remote machine
-that provides functions to get a list of available Java Virtual Machines
-and to acquire a copy of a Java Virtual Machine's instrumentation buffer.
-The RMI server may or may not use the PerfData implementation on the
-remote host to acquire this information. The <em>jstatd</em> server
-provides a PerfData implementation of the RMI server.
-</body>
-</html>
--- a/src/jdk.jvmstat/share/classes/sun/tools/jstatd/Jstatd.java	Sun Nov 29 20:27:38 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,164 +0,0 @@
-/*
- * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.tools.jstatd;
-
-import java.rmi.*;
-import java.rmi.server.*;
-import java.rmi.registry.Registry;
-import java.rmi.registry.LocateRegistry;
-import java.net.MalformedURLException;
-import sun.jvmstat.monitor.remote.*;
-
-/**
- * Application providing remote access to the jvmstat instrumentation
- * exported by local Java Virtual Machine processes. Remote access is
- * provided through an RMI interface.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class Jstatd {
-
-    private static Registry registry;
-    private static int port = -1;
-    private static boolean startRegistry = true;
-
-    private static void printUsage() {
-        System.err.println("usage: jstatd [-nr] [-p port] [-n rminame]");
-    }
-
-    static void bind(String name, RemoteHostImpl remoteHost)
-                throws RemoteException, MalformedURLException, Exception {
-
-        try {
-            Naming.rebind(name, remoteHost);
-        } catch (java.rmi.ConnectException e) {
-            /*
-             * either the registry is not running or we cannot contact it.
-             * start an internal registry if requested.
-             */
-            if (startRegistry && registry == null) {
-                int localport = (port < 0) ? Registry.REGISTRY_PORT : port;
-                registry = LocateRegistry.createRegistry(localport);
-                bind(name, remoteHost);
-            } else {
-                throw e;
-            }
-        }
-    }
-
-    @SuppressWarnings("deprecation") // Use of RMISecurityManager
-    public static void main(String[] args) {
-        String rminame = null;
-        int argc = 0;
-
-        for ( ; (argc < args.length) && (args[argc].startsWith("-")); argc++) {
-            String arg = args[argc];
-
-            if (arg.compareTo("-nr") == 0) {
-                startRegistry = false;
-            } else if (arg.startsWith("-p")) {
-                if (arg.compareTo("-p") != 0) {
-                    port = Integer.parseInt(arg.substring(2));
-                } else {
-                  argc++;
-                  if (argc >= args.length) {
-                      printUsage();
-                      System.exit(1);
-                  }
-                  port = Integer.parseInt(args[argc]);
-                }
-            } else if (arg.startsWith("-n")) {
-                if (arg.compareTo("-n") != 0) {
-                    rminame = arg.substring(2);
-                } else {
-                    argc++;
-                    if (argc >= args.length) {
-                        printUsage();
-                        System.exit(1);
-                    }
-                    rminame = args[argc];
-                }
-            } else {
-                printUsage();
-                System.exit(1);
-            }
-        }
-
-        if (argc < args.length) {
-            printUsage();
-            System.exit(1);
-        }
-
-        if (System.getSecurityManager() == null) {
-            System.setSecurityManager(new RMISecurityManager());
-        }
-
-        StringBuilder name = new StringBuilder();
-
-        if (port >= 0) {
-            name.append("//:").append(port);
-        }
-
-        if (rminame == null) {
-            rminame = "JStatRemoteHost";
-        }
-
-        name.append("/").append(rminame);
-
-        try {
-            // use 1.5.0 dynamically generated subs.
-            System.setProperty("java.rmi.server.ignoreSubClasses", "true");
-            RemoteHostImpl remoteHost = new RemoteHostImpl();
-            RemoteHost stub = (RemoteHost) UnicastRemoteObject.exportObject(
-                    remoteHost, 0);
-            bind(name.toString(), remoteHost);
-            System.out.println("jstatd started (bound to " + name.toString() + ")");
-            System.out.flush();
-        } catch (MalformedURLException e) {
-            if (rminame != null) {
-                System.out.println("Bad RMI server name: " + rminame);
-            } else {
-                System.out.println("Bad RMI URL: " + name);
-            }
-            e.printStackTrace(System.out);
-            System.exit(1);
-        } catch (java.rmi.ConnectException e) {
-            // could not attach to or create a registry
-            System.out.println("Could not contact RMI registry");
-            e.printStackTrace(System.out);
-            System.exit(1);
-        } catch (RemoteException e) {
-            System.out.println("Could not bind " + name + " to RMI Registry");
-            e.printStackTrace(System.out);
-            System.exit(1);
-        } catch (Exception e) {
-            System.out.println("Could not create remote object");
-            e.printStackTrace(System.out);
-            System.exit(1);
-        }
-    }
-}
--- a/src/jdk.jvmstat/share/classes/sun/tools/jstatd/RemoteHostImpl.java	Sun Nov 29 20:27:38 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.tools.jstatd;
-
-import java.util.*;
-import java.nio.*;
-import java.io.*;
-import java.net.*;
-import java.rmi.*;
-import java.rmi.server.*;
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.event.*;
-import sun.jvmstat.monitor.remote.*;
-
-/**
- * Concrete implementation of the RemoteHost interface for the HotSpot
- * PerfData <em>rmi:</em> protocol.
- * <p>
- * This class provides remote access to the instrumentation exported
- * by HotSpot Java Virtual Machines through the PerfData shared memory
- * interface.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class RemoteHostImpl implements RemoteHost, HostListener {
-
-    private MonitoredHost monitoredHost;
-    private Set<Integer> activeVms;
-
-    public RemoteHostImpl() throws MonitorException {
-        try {
-            monitoredHost = MonitoredHost.getMonitoredHost("localhost");
-        } catch (URISyntaxException e) { }
-
-        activeVms = monitoredHost.activeVms();
-        monitoredHost.addHostListener(this);
-    }
-
-    public RemoteVm attachVm(int lvmid, String mode)
-                    throws RemoteException, MonitorException {
-        Integer v = lvmid;
-        RemoteVm stub = null;
-        StringBuilder sb = new StringBuilder();
-
-        sb.append("local://").append(lvmid).append("@localhost");
-        if (mode != null) {
-            sb.append("?mode=").append(mode);
-        }
-
-        String vmidStr = sb.toString();
-
-        try {
-            VmIdentifier vmid = new VmIdentifier(vmidStr);
-            MonitoredVm mvm = monitoredHost.getMonitoredVm(vmid);
-            RemoteVmImpl rvm = new RemoteVmImpl((BufferedMonitoredVm)mvm);
-            stub = (RemoteVm) UnicastRemoteObject.exportObject(rvm, 0);
-        }
-        catch (URISyntaxException e) {
-            throw new RuntimeException("Malformed VmIdentifier URI: "
-                                       + vmidStr, e);
-        }
-        return stub;
-    }
-
-    public void detachVm(RemoteVm rvm) throws RemoteException {
-        rvm.detach();
-    }
-
-    public int[] activeVms() throws MonitorException {
-        Object[] vms = null;
-        int[] vmids = null;
-
-        vms = monitoredHost.activeVms().toArray();
-        vmids = new int[vms.length];
-
-        for (int i = 0; i < vmids.length; i++) {
-            vmids[i] = ((Integer)vms[i]).intValue();
-        }
-        return vmids;
-    }
-
-    public void vmStatusChanged(VmStatusChangeEvent ev) {
-        synchronized(this.activeVms) {
-            activeVms.retainAll(ev.getActive());
-        }
-    }
-
-    public void disconnected(HostEvent ev) {
-        // we only monitor the local host, so this event shouldn't occur.
-    }
-}
--- a/src/jdk.jvmstat/share/classes/sun/tools/jstatd/RemoteVmImpl.java	Sun Nov 29 20:27:38 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.tools.jstatd;
-
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.remote.*;
-
-/**
- * Concrete implementation of the RemoteVm interface for the HotSpot PerfData
- * shared memory implementation of the jvmstat monitoring APIs. This class
- * providing remote access to the instrumentation exported by a local HotSpot
- * Java Virtual Machine. The instrumentation buffer is shipped in whole to
- * the remote machine, which is responsible for parsing and provide access
- * to the contained data.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class RemoteVmImpl implements RemoteVm {
-
-    private BufferedMonitoredVm mvm;
-
-    RemoteVmImpl(BufferedMonitoredVm mvm) {
-        this.mvm = mvm;
-    }
-
-    public byte[] getBytes() {
-        return mvm.getBytes();
-    }
-
-    public int getCapacity() {
-        return mvm.getCapacity();
-    }
-
-    public void detach() {
-        mvm.detach();
-    }
-
-    public int getLocalVmId() {
-        return mvm.getVmIdentifier().getLocalVmId();
-    }
-}