feat(jdk8): move files to new folder to avoid resources compiled.

This commit is contained in:
2025-09-07 15:25:52 +08:00
parent 3f0047bf6f
commit 8c35cfb1c0
17415 changed files with 217 additions and 213 deletions
@@ -0,0 +1,341 @@
/*
* 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.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.
*/
private void fireVmStatusChangedEvents(Set active, Set started,
Set terminated) {
ArrayList registered = null;
VmStatusChangeEvent ev = null;
synchronized(listeners) {
registered = (ArrayList)listeners.clone();
}
for (Iterator i = registered.iterator(); i.hasNext(); /* empty */) {
HostListener l = (HostListener)i.next();
if (ev == null) {
ev = new VmStatusChangeEvent(this, active, started, terminated);
}
l.vmStatusChanged(ev);
}
}
/**
* Fire hostDisconnectEvent events.
*/
void fireDisconnectedEvents() {
ArrayList registered = null;
HostEvent ev = null;
synchronized(listeners) {
registered = (ArrayList)listeners.clone();
}
for (Iterator i = registered.iterator(); i.hasNext(); /* empty */) {
HostListener l = (HostListener)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 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<Integer>();
Set<Object> terminatedVms = new HashSet<Object>();
for (Iterator i = activeVms.iterator(); i.hasNext(); /* empty */ ) {
Integer vmid = (Integer)i.next();
if (!lastActiveVms.contains(vmid)) {
// a new file has been detected, add to set
startedVms.add(vmid);
}
}
for (Iterator i = lastActiveVms.iterator(); i.hasNext();
/* empty */ ) {
Object 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);
}
}
}
}
@@ -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());
}
}
}
@@ -0,0 +1,298 @@
/*
* 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.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.
*/
void fireMonitorStatusChangedEvents(List inserted, List removed) {
ArrayList registered = null;
MonitorStatusChangeEvent ev = null;
synchronized(listeners) {
registered = (ArrayList)listeners.clone();
}
for (Iterator i = registered.iterator(); i.hasNext(); /* empty */) {
VmListener l = (VmListener)i.next();
if (ev == null) {
ev = new MonitorStatusChangeEvent(this, inserted, removed);
}
l.monitorStatusChanged(ev);
}
}
/**
* Fire MonitoredVmStructureChanged events.
*/
void fireMonitorsUpdatedEvents() {
ArrayList registered = null;
VmEvent ev = null;
synchronized(listeners) {
registered = (ArrayList)listeners.clone();
}
for (Iterator i = registered.iterator(); i.hasNext(); /* empty */) {
VmListener l = (VmListener)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 inserted = status.getInserted();
List 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();
}
}
}
}
@@ -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(new Integer(active[i]));
}
return activeSet;
}
}