8187443: Forest Consolidation: Move files to unified layout

Reviewed-by: darcy, ihse
This commit is contained in:
Erik Joelsson 2017-09-12 19:03:39 +02:00
parent 270fe13182
commit 3789983e89
56923 changed files with 3 additions and 15727 deletions

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2014, 2017, 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.
*/
/**
* Defines tools for diagnostics and troubleshooting a JVM
* such as the <em>{@index jcmd jcmd tool}</em>, <em>{@index jps jps tool}</em>,
* <em>{@index jstat jstat tool}</em> tools.
*
* <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
* <dt class="simpleTagLabel">Tool Guides:
* <dd>
* {@extLink jcmd_tool_reference jcmd},
* {@extLink jinfo_tool_reference jinfo},
* {@extLink jmap_tool_reference jmap},
* {@extLink jps_tool_reference jps},
* {@extLink jstack_tool_reference jstack},
* {@extLink jstat_tool_reference jstat}
* </dl>
*
* @moduleGraph
* @since 9
*/
module jdk.jcmd {
requires jdk.attach;
requires jdk.internal.jvmstat;
}

View file

@ -0,0 +1,161 @@
/*
* Copyright (c) 2016, 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.common;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor;
import sun.jvmstat.monitor.MonitorException;
import sun.jvmstat.monitor.MonitoredHost;
import sun.jvmstat.monitor.MonitoredVm;
import sun.jvmstat.monitor.MonitoredVmUtil;
import sun.jvmstat.monitor.VmIdentifier;
/**
* Class for finding process matching a process argument,
* excluding tool it self and returning a list containing
* the process identifiers.
*/
public class ProcessArgumentMatcher {
private String matchClass;
private String singlePid;
public ProcessArgumentMatcher(String pidArg) {
if (pidArg == null || pidArg.isEmpty()) {
throw new IllegalArgumentException("Pid string is invalid");
}
if (pidArg.charAt(0) == '-') {
throw new IllegalArgumentException("Unrecognized " + pidArg);
}
try {
long pid = Long.parseLong(pidArg);
if (pid != 0) {
singlePid = String.valueOf(pid);
}
} catch (NumberFormatException nfe) {
matchClass = pidArg;
}
}
private static String getExcludeStringFrom(Class<?> excludeClass) {
if (excludeClass == null) {
return "";
}
Module m = excludeClass.getModule();
if (m.isNamed()) {
return m.getName() + "/" + excludeClass.getName();
}
return excludeClass.getName();
}
private static boolean check(VirtualMachineDescriptor vmd, String excludeClass, String partialMatch) {
String mainClass = null;
try {
VmIdentifier vmId = new VmIdentifier(vmd.id());
MonitoredHost monitoredHost = MonitoredHost.getMonitoredHost(vmId);
MonitoredVm monitoredVm = monitoredHost.getMonitoredVm(vmId, -1);
mainClass = MonitoredVmUtil.mainClass(monitoredVm, true);
monitoredHost.detach(monitoredVm);
} catch (NullPointerException npe) {
// There is a potential race, where a running java app is being
// queried, unfortunately the java app has shutdown after this
// method is started but before getMonitoredVM is called.
// If this is the case, then the /tmp/hsperfdata_xxx/pid file
// will have disappeared and we will get a NullPointerException.
// Handle this gracefully....
return false;
} catch (MonitorException | URISyntaxException e) {
return false;
}
if (excludeClass != null && mainClass.equals(excludeClass)) {
return false;
}
if (partialMatch != null && mainClass.indexOf(partialMatch) == -1) {
return false;
}
return true;
}
private static Collection<VirtualMachineDescriptor> getSingleVMD(String pid) {
Collection<VirtualMachineDescriptor> vids = new ArrayList<>();
List<VirtualMachineDescriptor> vmds = VirtualMachine.list();
for (VirtualMachineDescriptor vmd : vmds) {
if (check(vmd, null, null)) {
if (pid.equals(vmd.id())) {
vids.add(vmd);
}
}
}
return vids;
}
private static Collection<VirtualMachineDescriptor> getVMDs(Class<?> excludeClass, String partialMatch) {
String excludeCls = getExcludeStringFrom(excludeClass);
Collection<VirtualMachineDescriptor> vids = new ArrayList<>();
List<VirtualMachineDescriptor> vmds = VirtualMachine.list();
for (VirtualMachineDescriptor vmd : vmds) {
if (check(vmd, excludeCls, partialMatch)) {
vids.add(vmd);
}
}
return vids;
}
public Collection<VirtualMachineDescriptor> getVirtualMachineDescriptors(Class<?> excludeClass) {
if (singlePid != null) {
return getSingleVMD(singlePid);
} else {
return getVMDs(excludeClass, matchClass);
}
}
public Collection<VirtualMachineDescriptor> getVirtualMachineDescriptors() {
return this.getVirtualMachineDescriptors(null);
}
public Collection<String> getVirtualMachinePids(Class<?> excludeClass) {
if (singlePid != null) {
// There is a bug in AttachProvider, when VM is debuggee-suspended it's not listed by the AttachProvider.
// If we are talking about a specific pid, just return it.
return List.of(singlePid);
} else {
return getVMDs(excludeClass, matchClass).stream().map(x -> {return x.id();}).collect(Collectors.toList());
}
}
public Collection<String> getVirtualMachinePids() {
return this.getVirtualMachinePids(null);
}
}

View file

@ -0,0 +1,121 @@
/*
* Copyright (c) 2011, 2012, 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.jcmd;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
class Arguments {
private boolean listProcesses = false;
private boolean listCounters = false;
private boolean showUsage = false;
private String command = null;
private String processString = null;
public boolean isListProcesses() { return listProcesses; }
public boolean isListCounters() { return listCounters; }
public boolean isShowUsage() { return showUsage; }
public String getCommand() { return command; }
public String getProcessString() { return processString; }
public Arguments(String[] args) {
if (args.length == 0 || args[0].equals("-l")) {
listProcesses = true;
/* list all processes */
processString = "0";
return;
}
if (args[0].equals("-h") || args[0].equals("-help") ) {
showUsage = true;
return;
}
processString = args[0];
StringBuilder sb = new StringBuilder();
for (int i = 1; i < args.length; i++) {
if (args[i].equals("-f")) {
if (args.length == i + 1) {
throw new IllegalArgumentException(
"No file specified for parameter -f");
} else if (args.length == i + 2) {
try {
readCommandFile(args[i + 1]);
} catch(IOException e) {
throw new IllegalArgumentException(
"Could not read from file specified with -f option: "
+ args[i + 1]);
}
return;
} else {
throw new IllegalArgumentException(
"Options after -f are not allowed");
}
} else if (args[i].equals("PerfCounter.print")) {
listCounters = true;
} else {
sb.append(args[i]).append(" ");
}
}
if (listCounters != true && sb.length() == 0) {
throw new IllegalArgumentException("No command specified");
}
command = sb.toString().trim();
}
private void readCommandFile(String path) throws IOException {
try (BufferedReader bf = new BufferedReader(new FileReader(path));) {
StringBuilder sb = new StringBuilder();
String s;
while ((s = bf.readLine()) != null) {
sb.append(s).append("\n");
}
command = sb.toString();
}
}
public static void usage() {
System.out.println("Usage: jcmd <pid | main class> <command ...|PerfCounter.print|-f file>");
System.out.println(" or: jcmd -l ");
System.out.println(" or: jcmd -h ");
System.out.println(" ");
System.out.println(" command must be a valid jcmd command for the selected jvm. ");
System.out.println(" Use the command \"help\" to see which commands are available. ");
System.out.println(" If the pid is 0, commands will be sent to all Java processes. ");
System.out.println(" The main class argument will be used to match (either partially ");
System.out.println(" or fully) the class used to start Java. ");
System.out.println(" If no options are given, lists Java processes (same as -l). ");
System.out.println(" ");
System.out.println(" PerfCounter.print display the counters exposed by this process ");
System.out.println(" -f read and execute commands from the file ");
System.out.println(" -l list JVM processes on the local machine ");
System.out.println(" -h this help ");
}
}

View file

@ -0,0 +1,181 @@
/*
* Copyright (c) 2011, 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.tools.jcmd;
import java.io.InputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.net.URISyntaxException;
import com.sun.tools.attach.AttachOperationFailedException;
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor;
import com.sun.tools.attach.AttachNotSupportedException;
import sun.tools.attach.HotSpotVirtualMachine;
import sun.tools.common.ProcessArgumentMatcher;
import sun.tools.jstat.JStatLogger;
import sun.jvmstat.monitor.Monitor;
import sun.jvmstat.monitor.MonitoredHost;
import sun.jvmstat.monitor.MonitoredVm;
import sun.jvmstat.monitor.MonitorException;
import sun.jvmstat.monitor.VmIdentifier;
public class JCmd {
public static void main(String[] args) {
Arguments arg = null;
try {
arg = new Arguments(args);
} catch (IllegalArgumentException ex) {
System.err.println("Error parsing arguments: " + ex.getMessage()
+ "\n");
Arguments.usage();
System.exit(1);
}
if (arg.isShowUsage()) {
Arguments.usage();
System.exit(1);
}
ProcessArgumentMatcher ap = null;
try {
ap = new ProcessArgumentMatcher(arg.getProcessString());
} catch (IllegalArgumentException iae) {
System.err.println("Invalid pid '" + arg.getProcessString() + "' specified");
System.exit(1);
}
if (arg.isListProcesses()) {
for (VirtualMachineDescriptor vmd : ap.getVirtualMachineDescriptors(/* include jcmd in listing */)) {
System.out.println(vmd.id() + " " + vmd.displayName());
}
System.exit(0);
}
Collection<String> pids = ap.getVirtualMachinePids(JCmd.class);
if (pids.isEmpty()) {
System.err.println("Could not find any processes matching : '"
+ arg.getProcessString() + "'");
System.exit(1);
}
boolean success = true;
for (String pid : pids) {
System.out.println(pid + ":");
if (arg.isListCounters()) {
listCounters(pid);
} else {
try {
executeCommandForPid(pid, arg.getCommand());
} catch(AttachOperationFailedException ex) {
System.err.println(ex.getMessage());
success = false;
} catch(Exception ex) {
ex.printStackTrace();
success = false;
}
}
}
System.exit(success ? 0 : 1);
}
private static void executeCommandForPid(String pid, String command)
throws AttachNotSupportedException, IOException,
UnsupportedEncodingException {
VirtualMachine vm = VirtualMachine.attach(pid);
// Cast to HotSpotVirtualMachine as this is an
// implementation specific method.
HotSpotVirtualMachine hvm = (HotSpotVirtualMachine) vm;
String lines[] = command.split("\\n");
for (String line : lines) {
if (line.trim().equals("stop")) {
break;
}
try (InputStream in = hvm.executeJCmd(line);) {
// read to EOF and just print output
byte b[] = new byte[256];
int n;
boolean messagePrinted = false;
do {
n = in.read(b);
if (n > 0) {
String s = new String(b, 0, n, "UTF-8");
System.out.print(s);
messagePrinted = true;
}
} while (n > 0);
if (!messagePrinted) {
System.out.println("Command executed successfully");
}
}
}
vm.detach();
}
private static void listCounters(String pid) {
// Code from JStat (can't call it directly since it does System.exit)
VmIdentifier vmId = null;
try {
vmId = new VmIdentifier(pid);
} catch (URISyntaxException e) {
System.err.println("Malformed VM Identifier: " + pid);
return;
}
try {
MonitoredHost monitoredHost = MonitoredHost.getMonitoredHost(vmId);
MonitoredVm monitoredVm = monitoredHost.getMonitoredVm(vmId, -1);
JStatLogger logger = new JStatLogger(monitoredVm);
logger.printSnapShot("\\w*", // all names
new AscendingMonitorComparator(), // comparator
false, // not verbose
true, // show unsupported
System.out);
monitoredHost.detach(monitoredVm);
} catch (MonitorException ex) {
ex.printStackTrace();
}
}
/**
* Class to compare two Monitor objects by name in ascending order.
* (from jstat)
*/
static class AscendingMonitorComparator implements Comparator<Monitor> {
public int compare(Monitor m1, Monitor m2) {
String name1 = m1.getName();
String name2 = m2.getName();
return name1.compareTo(name2);
}
}
}

View file

@ -0,0 +1,261 @@
/*
* Copyright (c) 2006, 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.tools.jinfo;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor;
import sun.tools.attach.HotSpotVirtualMachine;
import sun.tools.common.ProcessArgumentMatcher;
/*
* This class is the main class for the JInfo utility. It parses its arguments
* and decides if the command should be satisfied using the VM attach mechanism
* or an SA tool.
*/
final public class JInfo {
public static void main(String[] args) throws Exception {
if (args.length == 0) {
usage(1); // no arguments
}
checkForUnsupportedOptions(args);
boolean doFlag = false;
boolean doFlags = false;
boolean doSysprops = false;
int flag = -1;
// Parse the options (arguments starting with "-" )
int optionCount = 0;
while (optionCount < args.length) {
String arg = args[optionCount];
if (!arg.startsWith("-")) {
break;
}
optionCount++;
if (arg.equals("-help") || arg.equals("-h")) {
usage(0);
}
if (arg.equals("-flag")) {
doFlag = true;
// Consume the flag
if (optionCount < args.length) {
flag = optionCount++;
break;
}
usage(1);
}
if (arg.equals("-flags")) {
doFlags = true;
break;
}
if (arg.equals("-sysprops")) {
doSysprops = true;
break;
}
}
int paramCount = args.length - optionCount;
if (paramCount != 1) {
usage(1);
}
String parg = args[optionCount];
ProcessArgumentMatcher ap = new ProcessArgumentMatcher(parg);
Collection<String> pids = ap.getVirtualMachinePids(JInfo.class);
if (pids.isEmpty()) {
System.err.println("Could not find any processes matching : '" + parg + "'");
System.exit(1);
}
for (String pid : pids) {
if (pids.size() > 1) {
System.out.println("Pid:" + pid);
}
if (!doFlag && !doFlags && !doSysprops) {
// Print flags and sysporps if no options given
sysprops(pid);
System.out.println();
flags(pid);
System.out.println();
commandLine(pid);
}
if (doFlag) {
if (flag < 0) {
System.err.println("Missing flag");
usage(1);
}
flag(pid, args[flag]);
}
if (doFlags) {
flags(pid);
}
if (doSysprops) {
sysprops(pid);
}
}
}
private static void flag(String pid, String option) throws IOException {
HotSpotVirtualMachine vm = (HotSpotVirtualMachine) attach(pid);
String flag;
InputStream in;
int index = option.indexOf('=');
if (index != -1) {
flag = option.substring(0, index);
String value = option.substring(index + 1);
in = vm.setFlag(flag, value);
} else {
char c = option.charAt(0);
switch (c) {
case '+':
flag = option.substring(1);
in = vm.setFlag(flag, "1");
break;
case '-':
flag = option.substring(1);
in = vm.setFlag(flag, "0");
break;
default:
flag = option;
in = vm.printFlag(flag);
break;
}
}
drain(vm, in);
}
private static void flags(String pid) throws IOException {
HotSpotVirtualMachine vm = (HotSpotVirtualMachine) attach(pid);
InputStream in = vm.executeJCmd("VM.flags");
System.out.println("VM Flags:");
drain(vm, in);
}
private static void commandLine(String pid) throws IOException {
HotSpotVirtualMachine vm = (HotSpotVirtualMachine) attach(pid);
InputStream in = vm.executeJCmd("VM.command_line");
drain(vm, in);
}
private static void sysprops(String pid) throws IOException {
HotSpotVirtualMachine vm = (HotSpotVirtualMachine) attach(pid);
InputStream in = vm.executeJCmd("VM.system_properties");
System.out.println("Java System Properties:");
drain(vm, in);
}
// Attach to <pid>, exiting if we fail to attach
private static VirtualMachine attach(String pid) {
try {
return VirtualMachine.attach(pid);
} catch (Exception x) {
String msg = x.getMessage();
if (msg != null) {
System.err.println(pid + ": " + msg);
} else {
x.printStackTrace();
}
System.exit(1);
return null; // keep compiler happy
}
}
// Read the stream from the target VM until EOF, then detach
private static void drain(VirtualMachine vm, InputStream in) throws IOException {
// read to EOF and just print output
byte b[] = new byte[256];
int n;
do {
n = in.read(b);
if (n > 0) {
String s = new String(b, 0, n, "UTF-8");
System.out.print(s);
}
} while (n > 0);
in.close();
vm.detach();
}
private static void checkForUnsupportedOptions(String[] args) {
// Check arguments for -F, and non-numeric value
// and warn the user that SA is not supported anymore
int maxCount = 1;
int paramCount = 0;
for (String s : args) {
if (s.equals("-F")) {
SAOptionError("-F option used");
}
if (s.equals("-flag")) {
maxCount = 2;
}
if (! s.startsWith("-")) {
paramCount += 1;
}
}
if (paramCount > maxCount) {
SAOptionError("More than " + maxCount + " non-option argument");
}
}
private static void SAOptionError(String msg) {
System.err.println("Error: " + msg);
System.err.println("Cannot connect to core dump or remote debug server. Use jhsdb jinfo instead");
System.exit(1);
}
// print usage message
private static void usage(int exit) {
System.err.println("Usage:");
System.err.println(" jinfo <option> <pid>");
System.err.println(" (to connect to a running process)");
System.err.println("");
System.err.println("where <option> is one of:");
System.err.println(" -flag <name> to print the value of the named VM flag");
System.err.println(" -flag [+|-]<name> to enable or disable the named VM flag");
System.err.println(" -flag <name>=<value> to set the named VM flag to the given value");
System.err.println(" -flags to print VM flags");
System.err.println(" -sysprops to print Java system properties");
System.err.println(" <no option> to print both VM flags and system properties");
System.err.println(" -h | -help to print this help message");
System.exit(exit);
}
}

View file

@ -0,0 +1,260 @@
/*
* Copyright (c) 2005, 2013, 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.jmap;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Collection;
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor;
import com.sun.tools.attach.AttachNotSupportedException;
import sun.tools.attach.HotSpotVirtualMachine;
import sun.tools.common.ProcessArgumentMatcher;
/*
* This class is the main class for the JMap utility. It parses its arguments
* and decides if the command should be satisfied using the VM attach mechanism
* or an SA tool. At this time the only option that uses the VM attach mechanism
* is the -dump option to get a heap dump of a running application. All other
* options are mapped to SA tools.
*/
public class JMap {
public static void main(String[] args) throws Exception {
if (args.length == 0) {
usage(1); // no arguments
}
checkForUnsupportedOptions(args);
// the chosen option
String option = null;
// First iterate over the options (arguments starting with -). There should be
// one.
int optionCount = 0;
while (optionCount < args.length) {
String arg = args[optionCount];
if (!arg.startsWith("-")) {
break;
}
if (arg.equals("-help") || arg.equals("-h")) {
usage(0);
} else {
if (option != null) {
usage(1); // option already specified
}
option = arg;
}
optionCount++;
}
// if no option provided then use default.
if (option == null) {
usage(0);
}
// Next we check the parameter count.
int paramCount = args.length - optionCount;
if (paramCount != 1) {
usage(1);
}
String pidArg = args[1];
// Here we handle the built-in options
// As more options are added we should create an abstract tool class and
// have a table to map the options
ProcessArgumentMatcher ap = new ProcessArgumentMatcher(pidArg);
Collection<String> pids = ap.getVirtualMachinePids(JMap.class);
if (pids.isEmpty()) {
System.err.println("Could not find any processes matching : '" + pidArg + "'");
System.exit(1);
}
for (String pid : pids) {
if (pids.size() > 1) {
System.out.println("Pid:" + pid);
}
if (option.equals("-histo")) {
histo(pid, "");
} else if (option.startsWith("-histo:")) {
histo(pid, option.substring("-histo:".length()));
} else if (option.startsWith("-dump:")) {
dump(pid, option.substring("-dump:".length()));
} else if (option.equals("-finalizerinfo")) {
executeCommandForPid(pid, "jcmd", "GC.finalizer_info");
} else if (option.equals("-clstats")) {
executeCommandForPid(pid, "jcmd", "GC.class_stats");
} else {
usage(1);
}
}
}
private static void executeCommandForPid(String pid, String command, Object ... args)
throws AttachNotSupportedException, IOException,
UnsupportedEncodingException {
VirtualMachine vm = VirtualMachine.attach(pid);
// Cast to HotSpotVirtualMachine as this is an
// implementation specific method.
HotSpotVirtualMachine hvm = (HotSpotVirtualMachine) vm;
try (InputStream in = hvm.executeCommand(command, args)) {
// read to EOF and just print output
byte b[] = new byte[256];
int n;
do {
n = in.read(b);
if (n > 0) {
String s = new String(b, 0, n, "UTF-8");
System.out.print(s);
}
} while (n > 0);
}
vm.detach();
}
private static void histo(String pid, String options)
throws AttachNotSupportedException, IOException,
UnsupportedEncodingException {
String liveopt = "-all";
if (options.equals("") || options.equals("all")) {
// pass
}
else if (options.equals("live")) {
liveopt = "-live";
}
else {
usage(1);
}
// inspectHeap is not the same as jcmd GC.class_histogram
executeCommandForPid(pid, "inspectheap", liveopt);
}
private static void dump(String pid, String options)
throws AttachNotSupportedException, IOException,
UnsupportedEncodingException {
String subopts[] = options.split(",");
String filename = null;
String liveopt = "-all";
for (int i = 0; i < subopts.length; i++) {
String subopt = subopts[i];
if (subopt.equals("live")) {
liveopt = "-live";
} else if (subopt.startsWith("file=")) {
// file=<file> - check that <file> is specified
if (subopt.length() > 5) {
filename = subopt.substring(5);
}
}
}
if (filename == null) {
usage(1); // invalid options or no filename
}
// get the canonical path - important to avoid just passing
// a "heap.bin" and having the dump created in the target VM
// working directory rather than the directory where jmap
// is executed.
filename = new File(filename).getCanonicalPath();
// dumpHeap is not the same as jcmd GC.heap_dump
executeCommandForPid(pid, "dumpheap", filename, liveopt);
}
private static void checkForUnsupportedOptions(String[] args) {
// Check arguments for -F, -m, and non-numeric value
// and warn the user that SA is not supported anymore
int paramCount = 0;
for (String s : args) {
if (s.equals("-F")) {
SAOptionError("-F option used");
}
if (s.equals("-heap")) {
SAOptionError("-heap option used");
}
/* Reimplemented using jcmd, output format is different
from original one
if (s.equals("-clstats")) {
warnSA("-clstats option used");
}
if (s.equals("-finalizerinfo")) {
warnSA("-finalizerinfo option used");
}
*/
if (! s.startsWith("-")) {
paramCount += 1;
}
}
if (paramCount > 1) {
SAOptionError("More than one non-option argument");
}
}
private static void SAOptionError(String msg) {
System.err.println("Error: " + msg);
System.err.println("Cannot connect to core dump or remote debug server. Use jhsdb jmap instead");
System.exit(1);
}
// print usage message
private static void usage(int exit) {
System.err.println("Usage:");
System.err.println(" jmap -clstats <pid>");
System.err.println(" to connect to running process and print class loader statistics");
System.err.println(" jmap -finalizerinfo <pid>");
System.err.println(" to connect to running process and print information on objects awaiting finalization");
System.err.println(" jmap -histo[:live] <pid>");
System.err.println(" to connect to running process and print histogram of java object heap");
System.err.println(" if the \"live\" suboption is specified, only count live objects");
System.err.println(" jmap -dump:<dump-options> <pid>");
System.err.println(" to connect to running process and dump java heap");
System.err.println("");
System.err.println(" dump-options:");
System.err.println(" live dump only live objects; if not specified,");
System.err.println(" all objects in the heap are dumped.");
System.err.println(" format=b binary format");
System.err.println(" file=<file> dump heap to <file>");
System.err.println("");
System.err.println(" Example: jmap -dump:live,format=b,file=heap.bin <pid>");
System.exit(exit);
}
}

View file

@ -0,0 +1,166 @@
/*
* 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.jps;
import java.io.*;
import java.net.*;
import sun.jvmstat.monitor.*;
/**
* Class for processing command line arguments and providing method
* level access to the command line arguments.
*
* @author Brian Doherty
* @since 1.5
*/
public class Arguments {
private static final boolean debug = Boolean.getBoolean("jps.debug");
private static final boolean printStackTrace = Boolean.getBoolean(
"jps.printStackTrace");
private boolean help;
private boolean quiet;
private boolean longPaths;
private boolean vmArgs;
private boolean vmFlags;
private boolean mainArgs;
private String hostname;
private HostIdentifier hostId;
public static void printUsage(PrintStream ps) {
ps.println("usage: jps [-help]");
ps.println(" jps [-q] [-mlvV] [<hostid>]");
ps.println();
ps.println("Definitions:");
ps.println(" <hostid>: <hostname>[:<port>]");
}
public Arguments(String[] args) throws IllegalArgumentException {
int argc = 0;
if (args.length == 1) {
if ((args[0].compareTo("-?") == 0)
|| (args[0].compareTo("-help")== 0)) {
help = true;
return;
}
}
for (argc = 0; (argc < args.length) && (args[argc].startsWith("-"));
argc++) {
String arg = args[argc];
if (arg.compareTo("-q") == 0) {
quiet = true;
} else if (arg.startsWith("-")) {
for (int j = 1; j < arg.length(); j++) {
switch (arg.charAt(j)) {
case 'm':
mainArgs = true;
break;
case 'l':
longPaths = true;
break;
case 'v':
vmArgs = true;
break;
case 'V':
vmFlags = true;
break;
default:
throw new IllegalArgumentException("illegal argument: "
+ args[argc]);
}
}
} else {
throw new IllegalArgumentException("illegal argument: "
+ args[argc]);
}
}
switch (args.length - argc) {
case 0:
hostname = null;
break;
case 1:
hostname = args[args.length - 1];
break;
default:
throw new IllegalArgumentException("invalid argument count");
}
try {
hostId = new HostIdentifier(hostname);
} catch (URISyntaxException e) {
IllegalArgumentException iae =
new IllegalArgumentException("Malformed Host Identifier: "
+ hostname);
iae.initCause(e);
throw iae;
}
}
public boolean isDebug() {
return debug;
}
public boolean printStackTrace() {
return printStackTrace;
}
public boolean isHelp() {
return help;
}
public boolean isQuiet() {
return quiet;
}
public boolean showLongPaths() {
return longPaths;
}
public boolean showVmArgs() {
return vmArgs;
}
public boolean showVmFlags() {
return vmFlags;
}
public boolean showMainArgs() {
return mainArgs;
}
public String hostname() {
return hostname;
}
public HostIdentifier hostId() {
return hostId;
}
}

View file

@ -0,0 +1,175 @@
/*
* 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.jps;
import java.util.*;
import java.net.*;
import sun.jvmstat.monitor.*;
/**
* Application to provide a listing of monitorable java processes.
*
* @author Brian Doherty
* @since 1.5
*/
public class Jps {
private static Arguments arguments;
public static void main(String[] args) {
try {
arguments = new Arguments(args);
} catch (IllegalArgumentException e) {
System.err.println(e.getMessage());
Arguments.printUsage(System.err);
System.exit(1);
}
if (arguments.isHelp()) {
Arguments.printUsage(System.err);
System.exit(0);
}
try {
HostIdentifier hostId = arguments.hostId();
MonitoredHost monitoredHost =
MonitoredHost.getMonitoredHost(hostId);
// get the set active JVMs on the specified host.
Set<Integer> jvms = monitoredHost.activeVms();
for (Integer jvm: jvms) {
StringBuilder output = new StringBuilder();
Throwable lastError = null;
int lvmid = jvm;
output.append(String.valueOf(lvmid));
if (arguments.isQuiet()) {
System.out.println(output);
continue;
}
MonitoredVm vm = null;
String vmidString = "//" + lvmid + "?mode=r";
String errorString = null;
try {
// Note: The VM associated with the current VM id may
// no longer be running so these queries may fail. We
// already added the VM id to the output stream above.
// If one of the queries fails, then we try to add a
// reasonable message to indicate that the requested
// info is not available.
errorString = " -- process information unavailable";
VmIdentifier id = new VmIdentifier(vmidString);
vm = monitoredHost.getMonitoredVm(id, 0);
errorString = " -- main class information unavailable";
output.append(' ').append(MonitoredVmUtil.mainClass(vm,
arguments.showLongPaths()));
if (arguments.showMainArgs()) {
errorString = " -- main args information unavailable";
String mainArgs = MonitoredVmUtil.mainArgs(vm);
if (mainArgs != null && mainArgs.length() > 0) {
output.append(' ').append(mainArgs);
}
}
if (arguments.showVmArgs()) {
errorString = " -- jvm args information unavailable";
String jvmArgs = MonitoredVmUtil.jvmArgs(vm);
if (jvmArgs != null && jvmArgs.length() > 0) {
output.append(' ')
.append(
// multi-line args are permitted
jvmArgs.replace("\n", "\\n").replace("\r", "\\r")
);
}
}
if (arguments.showVmFlags()) {
errorString = " -- jvm flags information unavailable";
String jvmFlags = MonitoredVmUtil.jvmFlags(vm);
if (jvmFlags != null && jvmFlags.length() > 0) {
output.append(' ').append(jvmFlags);
}
}
errorString = " -- detach failed";
monitoredHost.detach(vm);
System.out.println(output);
errorString = null;
} catch (URISyntaxException e) {
// unexpected as vmidString is based on a validated hostid
lastError = e;
assert false;
} catch (Exception e) {
lastError = e;
} finally {
if (errorString != null) {
/*
* we ignore most exceptions, as there are race
* conditions where a JVM in 'jvms' may terminate
* before we get a chance to list its information.
* Other errors, such as access and I/O exceptions
* should stop us from iterating over the complete set.
*/
output.append(errorString);
if (arguments.isDebug()) {
if ((lastError != null)
&& (lastError.getMessage() != null)) {
output.append("\n\t");
output.append(lastError.getMessage());
}
}
System.out.println(output);
if (arguments.printStackTrace()) {
lastError.printStackTrace();
}
continue;
}
}
}
} catch (MonitorException e) {
if (e.getMessage() != null) {
System.err.println(e.getMessage());
} else {
Throwable cause = e.getCause();
if ((cause != null) && (cause.getMessage() != null)) {
System.err.println(cause.getMessage());
} else {
e.printStackTrace();
}
}
System.exit(1);
}
}
}

View file

@ -0,0 +1,177 @@
/*
* Copyright (c) 2005, 2013, 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.jstack;
import java.io.InputStream;
import java.util.Collection;
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor;
import sun.tools.attach.HotSpotVirtualMachine;
import sun.tools.common.ProcessArgumentMatcher;
/*
* This class is the main class for the JStack utility. It parses its arguments
* and decides if the command should be executed by the SA JStack tool or by
* obtained the thread dump from a target process using the VM attach mechanism
*/
public class JStack {
public static void main(String[] args) throws Exception {
if (args.length == 0) {
usage(1); // no arguments
}
checkForUnsupportedOptions(args);
boolean locks = false;
// Parse the options (arguments starting with "-" )
int optionCount = 0;
while (optionCount < args.length) {
String arg = args[optionCount];
if (!arg.startsWith("-")) {
break;
}
if (arg.equals("-help") || arg.equals("-h")) {
usage(0);
}
else {
if (arg.equals("-l")) {
locks = true;
} else {
usage(1);
}
}
optionCount++;
}
// Next we check the parameter count.
int paramCount = args.length - optionCount;
if (paramCount != 1) {
usage(1);
}
// pass -l to thread dump operation to get extra lock info
String pidArg = args[optionCount];
String params[];
if (locks) {
params = new String[] { "-l" };
} else {
params = new String[0];
}
ProcessArgumentMatcher ap = new ProcessArgumentMatcher(pidArg);
Collection<String> pids = ap.getVirtualMachinePids(JStack.class);
if (pids.isEmpty()) {
System.err.println("Could not find any processes matching : '" + pidArg + "'");
System.exit(1);
}
for (String pid : pids) {
if (pids.size() > 1) {
System.out.println("Pid:" + pid);
}
runThreadDump(pid, params);
}
}
// Attach to pid and perform a thread dump
private static void runThreadDump(String pid, String args[]) throws Exception {
VirtualMachine vm = null;
try {
vm = VirtualMachine.attach(pid);
} catch (Exception x) {
String msg = x.getMessage();
if (msg != null) {
System.err.println(pid + ": " + msg);
} else {
x.printStackTrace();
}
System.exit(1);
}
// Cast to HotSpotVirtualMachine as this is implementation specific
// method.
InputStream in = ((HotSpotVirtualMachine)vm).remoteDataDump((Object[])args);
// read to EOF and just print output
byte b[] = new byte[256];
int n;
do {
n = in.read(b);
if (n > 0) {
String s = new String(b, 0, n, "UTF-8");
System.out.print(s);
}
} while (n > 0);
in.close();
vm.detach();
}
private static void checkForUnsupportedOptions(String[] args) {
// Check arguments for -F, -m, and non-numeric value
// and warn the user that SA is not supported anymore
int paramCount = 0;
for (String s : args) {
if (s.equals("-F")) {
SAOptionError("-F option used");
}
if (s.equals("-m")) {
SAOptionError("-m option used");
}
if (! s.startsWith("-")) {
paramCount += 1;
}
}
if (paramCount > 1) {
SAOptionError("More than one non-option argument");
}
}
private static void SAOptionError(String msg) {
System.err.println("Error: " + msg);
System.err.println("Cannot connect to core dump or remote debug server. Use jhsdb jstack instead");
System.exit(1);
}
// print usage message
private static void usage(int exit) {
System.err.println("Usage:");
System.err.println(" jstack [-l] <pid>");
System.err.println(" (to connect to running process)");
System.err.println("");
System.err.println("Options:");
System.err.println(" -l long listing. Prints additional information about locks");
System.err.println(" -h or -help to print this help message");
System.exit(exit);
}
}

View file

@ -0,0 +1,125 @@
/*
* 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.jstat;
import java.util.*;
/**
* A typesafe enumeration for describing data alignment semantics
*
* @author Brian Doherty
* @since 1.5
*/
public abstract class Alignment {
private static int nextOrdinal = 0;
private static HashMap<String, Alignment> map = new HashMap<String, Alignment>();
private static final String blanks = " ";
private final String name;
private final int value = nextOrdinal++;
protected abstract String align(String s, int width);
/**
* Alignment representing a Centered alignment
*/
public static final Alignment CENTER = new Alignment("center") {
protected String align(String s, int width) {
int length = s.length();
if (length >= width) {
return s;
}
int pad = width - length;
int pad2 = pad / 2;
int padr = pad % 2;
if (pad2 == 0) {
// only 0 or 1 character to pad
return s + blanks.substring(0, padr);
} else {
// pad on both sides
return blanks.substring(0, pad2) + s +
blanks.substring(0, pad2 + padr);
}
}
};
/**
* Alignment representing a Left alignment
*/
public static final Alignment LEFT = new Alignment("left") {
protected String align(String s, int width) {
int length = s.length();
if (length >= width) {
return s;
}
int pad = width - length;
return s+blanks.substring(0, pad);
}
};
/**
* Alignment representing a Right alignment
*/
public static final Alignment RIGHT = new Alignment("right") {
protected String align(String s, int width) {
int length = s.length();
if (length >= width) {
return s;
}
int pad = width - length;
return blanks.substring(0, pad) + s;
}
};
/**
* Maps a string value to its corresponding Alignment object.
*
* @param s an string to match against Alignment objects.
* @return The Alignment object matching the given string.
*/
public static Alignment toAlignment(String s) {
return map.get(s);
}
/**
* Returns an enumeration of the keys for this enumerated type
*
* @return Set of Key Words for this enumeration.
*/
public static Set<String> keySet() {
return map.keySet();
}
public String toString() {
return name;
}
private Alignment(String name) {
this.name = name;
map.put(name, this);
}
}

View file

@ -0,0 +1,446 @@
/*
* 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.tools.jstat;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.regex.*;
import sun.jvmstat.monitor.Monitor;
import sun.jvmstat.monitor.VmIdentifier;
/**
* Class for processing command line arguments and providing method
* level access to arguments.
*
* @author Brian Doherty
* @since 1.5
*/
public class Arguments {
private static final boolean debug = Boolean.getBoolean("jstat.debug");
private static final boolean showUnsupported =
Boolean.getBoolean("jstat.showUnsupported");
private static final String JVMSTAT_USERDIR = ".jvmstat";
private static final String OPTIONS_FILENAME = "jstat_options";
private static final String UNSUPPORTED_OPTIONS_FILENAME = "jstat_unsupported_options";
private static final String ALL_NAMES = "\\w*";
private Comparator<Monitor> comparator;
private int headerRate;
private boolean help;
private boolean list;
private boolean options;
private boolean constants;
private boolean constantsOnly;
private boolean strings;
private boolean timestamp;
private boolean snap;
private boolean verbose;
private String specialOption;
private String names;
private OptionFormat optionFormat;
private int count = -1;
private int interval = -1;
private String vmIdString;
private VmIdentifier vmId;
public static void printUsage(PrintStream ps) {
ps.println("Usage: jstat -help|-options");
ps.println(" jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]");
ps.println();
ps.println("Definitions:");
ps.println(" <option> An option reported by the -options option");
ps.println(" <vmid> Virtual Machine Identifier. A vmid takes the following form:");
ps.println(" <lvmid>[@<hostname>[:<port>]]");
ps.println(" Where <lvmid> is the local vm identifier for the target");
ps.println(" Java virtual machine, typically a process id; <hostname> is");
ps.println(" the name of the host running the target Java virtual machine;");
ps.println(" and <port> is the port number for the rmiregistry on the");
ps.println(" target host. See the jvmstat documentation for a more complete");
ps.println(" description of the Virtual Machine Identifier.");
ps.println(" <lines> Number of samples between header lines.");
ps.println(" <interval> Sampling interval. The following forms are allowed:");
ps.println(" <n>[\"ms\"|\"s\"]");
ps.println(" Where <n> is an integer and the suffix specifies the units as ");
ps.println(" milliseconds(\"ms\") or seconds(\"s\"). The default units are \"ms\".");
ps.println(" <count> Number of samples to take before terminating.");
ps.println(" -J<flag> Pass <flag> directly to the runtime system.");
// undocumented options:
// -list [<vmid>] - list counter names
// -snap <vmid> - snapshot counter values as name=value pairs
// -name <pattern> - output counters matching given pattern
// -a - sort in ascending order (default)
// -d - sort in descending order
// -v - verbose output (-snap)
// -constants - output constants with -name output
// -strings - output strings with -name output
}
private static int toMillis(String s) throws IllegalArgumentException {
String[] unitStrings = { "ms", "s" }; // ordered from most specific to
// least specific
String unitString = null;
String valueString = s;
for (int i = 0; i < unitStrings.length; i++) {
int index = s.indexOf(unitStrings[i]);
if (index > 0) {
unitString = s.substring(index);
valueString = s.substring(0, index);
break;
}
}
try {
int value = Integer.parseInt(valueString);
if (unitString == null || unitString.compareTo("ms") == 0) {
return value;
} else if (unitString.compareTo("s") == 0) {
return value * 1000;
} else {
throw new IllegalArgumentException(
"Unknow time unit: " + unitString);
}
} catch (NumberFormatException e) {
throw new IllegalArgumentException(
"Could not convert interval: " + s);
}
}
public Arguments(String[] args) throws IllegalArgumentException {
int argc = 0;
if (args.length == 0) {
help = true;
return;
}
if ((args[0].compareTo("-?") == 0)
|| (args[0].compareTo("-help") == 0)) {
help = true;
return;
} else if (args[0].compareTo("-options") == 0) {
options = true;
return;
} else if (args[0].compareTo("-list") == 0) {
list = true;
if (args.length > 2) {
throw new IllegalArgumentException("invalid argument count");
}
// list can take one arg - a vmid - fall through for arg processing
argc++;
}
for ( ; (argc < args.length) && (args[argc].startsWith("-")); argc++) {
String arg = args[argc];
if (arg.compareTo("-a") == 0) {
comparator = new AscendingMonitorComparator();
} else if (arg.compareTo("-d") == 0) {
comparator = new DescendingMonitorComparator();
} else if (arg.compareTo("-t") == 0) {
timestamp = true;
} else if (arg.compareTo("-v") == 0) {
verbose = true;
} else if ((arg.compareTo("-constants") == 0)
|| (arg.compareTo("-c") == 0)) {
constants = true;
} else if ((arg.compareTo("-strings") == 0)
|| (arg.compareTo("-s") == 0)) {
strings = true;
} else if (arg.startsWith("-h")) {
String value;
if (arg.compareTo("-h") != 0) {
value = arg.substring(2);
} else {
argc++;
if (argc >= args.length) {
throw new IllegalArgumentException(
"-h requires an integer argument");
}
value = args[argc];
}
try {
headerRate = Integer.parseInt(value);
} catch (NumberFormatException e) {
headerRate = -1;
}
if (headerRate < 0) {
throw new IllegalArgumentException(
"illegal -h argument: " + value);
}
} else if (arg.startsWith("-name")) {
if (arg.startsWith("-name=")) {
names = arg.substring(7);
} else {
argc++;
if (argc >= args.length) {
throw new IllegalArgumentException(
"option argument expected");
}
names = args[argc];
}
} else {
/*
* there are scenarios here: special jstat_options file option
* or the rare case of a negative lvmid. The negative lvmid
* can occur in some operating environments (such as Windows
* 95/98/ME), so we provide for this case here by checking if
* the argument has any numerical characters. This assumes that
* there are no special jstat_options that contain numerical
* characters in their name.
*/
// extract the lvmid part of possible lvmid@host.domain:port
String lvmidStr = null;
int at_index = args[argc].indexOf('@');
if (at_index < 0) {
lvmidStr = args[argc];
} else {
lvmidStr = args[argc].substring(0, at_index);
}
// try to parse the lvmid part as an integer
try {
int vmid = Integer.parseInt(lvmidStr);
// it parsed, assume a negative lvmid and continue
break;
} catch (NumberFormatException nfe) {
// it didn't parse. check for the -snap or jstat_options
// file options.
if ((argc == 0) && (args[argc].compareTo("-snap") == 0)) {
snap = true;
} else if (argc == 0) {
specialOption = args[argc].substring(1);
} else {
throw new IllegalArgumentException(
"illegal argument: " + args[argc]);
}
}
}
}
// prevent 'jstat <pid>' from being accepted as a valid argument
if (!(specialOption != null || list || snap || names != null)) {
throw new IllegalArgumentException("-<option> required");
}
switch (args.length - argc) {
case 3:
if (snap) {
throw new IllegalArgumentException("invalid argument count");
}
try {
count = Integer.parseInt(args[args.length-1]);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("illegal count value: "
+ args[args.length-1]);
}
interval = toMillis(args[args.length-2]);
vmIdString = args[args.length-3];
break;
case 2:
if (snap) {
throw new IllegalArgumentException("invalid argument count");
}
interval = toMillis(args[args.length-1]);
vmIdString = args[args.length-2];
break;
case 1:
vmIdString = args[args.length-1];
break;
case 0:
if (!list) {
throw new IllegalArgumentException("invalid argument count");
}
break;
default:
throw new IllegalArgumentException("invalid argument count");
}
// set count and interval to their default values if not set above.
if (count == -1 && interval == -1) {
// default is for a single sample
count = 1;
interval = 0;
}
// validate arguments
if (comparator == null) {
comparator = new AscendingMonitorComparator();
}
// allow ',' characters to separate names, convert to '|' chars
names = (names == null) ? ALL_NAMES : names.replace(',', '|');
// verify that the given pattern parses without errors
try {
Pattern pattern = Pattern.compile(names);
} catch (PatternSyntaxException e) {
throw new IllegalArgumentException("Bad name pattern: "
+ e.getMessage());
}
// verify that the special option is valid and get it's formatter
if (specialOption != null) {
OptionFinder finder = new OptionFinder(optionsSources());
optionFormat = finder.getOptionFormat(specialOption, timestamp);
if (optionFormat == null) {
throw new IllegalArgumentException("Unknown option: -"
+ specialOption);
}
}
// verify that the vm identifier is valied
try {
vmId = new VmIdentifier(vmIdString);
} catch (URISyntaxException e) {
IllegalArgumentException iae = new IllegalArgumentException(
"Malformed VM Identifier: " + vmIdString);
iae.initCause(e);
throw iae;
}
}
public Comparator<Monitor> comparator() {
return comparator;
}
public boolean isHelp() {
return help;
}
public boolean isList() {
return list;
}
public boolean isSnap() {
return snap;
}
public boolean isOptions() {
return options;
}
public boolean isVerbose() {
return verbose;
}
public boolean printConstants() {
return constants;
}
public boolean isConstantsOnly() {
return constantsOnly;
}
public boolean printStrings() {
return strings;
}
public boolean showUnsupported() {
return showUnsupported;
}
public int headerRate() {
return headerRate;
}
public String counterNames() {
return names;
}
public VmIdentifier vmId() {
return vmId;
}
public String vmIdString() {
return vmIdString;
}
public int sampleInterval() {
return interval;
}
public int sampleCount() {
return count;
}
public boolean isTimestamp() {
return timestamp;
}
public boolean isSpecialOption() {
return specialOption != null;
}
public String specialOption() {
return specialOption;
}
public OptionFormat optionFormat() {
return optionFormat;
}
public List<URL> optionsSources() {
List<URL> sources = new ArrayList<URL>();
int i = 0;
String filename = OPTIONS_FILENAME;
try {
String userHome = System.getProperty("user.home");
String userDir = userHome + "/" + JVMSTAT_USERDIR;
File home = new File(userDir + "/" + filename);
sources.add(home.toURI().toURL());
} catch (Exception e) {
if (debug) {
System.err.println(e.getMessage());
e.printStackTrace();
}
throw new IllegalArgumentException("Internal Error: Bad URL: "
+ e.getMessage());
}
URL u = this.getClass().getResource("resources/" + filename);
assert u != null;
sources.add(u);
if (showUnsupported) {
u = this.getClass().getResource("resources/" + UNSUPPORTED_OPTIONS_FILENAME);
assert u != null;
sources.add(u);
}
return sources;
}
}

View file

@ -0,0 +1,43 @@
/*
* 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.jstat;
import java.util.*;
import sun.jvmstat.monitor.*;
/**
* Class to compare two Monitor objects by name in ascending order.
*
* @author Brian Doherty
* @since 1.5
*/
class AscendingMonitorComparator implements Comparator<Monitor> {
public int compare(Monitor o1, Monitor o2) {
String name1 = o1.getName();
String name2 = o2.getName();
return name1.compareTo(name2);
}
}

View file

@ -0,0 +1,39 @@
/*
* 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.jstat;
import java.util.List;
import sun.jvmstat.monitor.MonitorException;
/**
* An interface for visitor object on a binary tree.
*
* @author Brian Doherty
* @since 1.5
*/
interface Closure {
void visit(Object o, boolean hasNext) throws MonitorException;
}

View file

@ -0,0 +1,157 @@
/*
* Copyright (c) 2004, 2013, 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.jstat;
import java.util.*;
/**
* A class to represent the format for a column of data.
*
* @author Brian Doherty
* @since 1.5
*/
public class ColumnFormat extends OptionFormat {
private int number;
private int width;
private Alignment align = Alignment.CENTER;
private Scale scale = Scale.RAW;
private String format;
private String header;
private Expression expression;
private Object previousValue;
public ColumnFormat(int number) {
super("Column" + number);
this.number = number;
}
/*
* method to apply various validation rules to the ColumnFormat object.
*/
public void validate() throws ParserException {
// if we allow column spanning, then this method must change. it
// should allow null data statments
if (expression == null) {
// current policy is that a data statement must be specified
throw new ParserException("Missing data statement in column " + number);
}
if (header == null) {
// current policy is that if a header is not specified, then we
// will use the last component of the name as the header and
// insert the default anchor characters for center alignment..
throw new ParserException("Missing header statement in column " + number);
}
if (format == null) {
// if no formating is specified, then the format is set to output
// the raw data.
format="0";
}
}
public void setWidth(int width) {
this.width = width;
}
public void setAlignment(Alignment align) {
this.align = align;
}
public void setScale(Scale scale) {
this.scale = scale;
}
public void setFormat(String format) {
this.format = format;
}
public void setHeader(String header) {
this.header = header;
}
public String getHeader() {
return header;
}
public String getFormat() {
return format;
}
public int getWidth() {
return width;
}
public Alignment getAlignment() {
return align;
}
public Scale getScale() {
return scale;
}
public Expression getExpression() {
return expression;
}
public void setExpression(Expression e) {
this.expression = e;
}
public void setPreviousValue(Object o) {
this.previousValue = o;
}
public Object getPreviousValue() {
return previousValue;
}
public void printFormat(int indentLevel) {
String indentAmount = " ";
StringBuilder indent = new StringBuilder("");
for (int j = 0; j < indentLevel; j++) {
indent.append(indentAmount);
}
System.out.println(indent + name + " {");
System.out.println(indent + indentAmount + "name=" + name
+ ";data=" + expression.toString() + ";header=" + header
+ ";format=" + format + ";width=" + width
+ ";scale=" + scale.toString() + ";align=" + align.toString());
for (Iterator<OptionFormat> i = children.iterator(); i.hasNext(); /* empty */) {
OptionFormat of = i.next();
of.printFormat(indentLevel+1);
}
System.out.println(indent + "}");
}
public String getValue() {
return null;
}
}

View file

@ -0,0 +1,43 @@
/*
* 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.jstat;
import java.util.*;
import sun.jvmstat.monitor.*;
/**
* Class to compare two Monitor objects by name in descending order.
*
* @author Brian Doherty
* @since 1.5
*/
class DescendingMonitorComparator implements Comparator<Monitor> {
public int compare(Monitor o1, Monitor o2) {
String name1 = o1.getName();
String name2 = o2.getName();
return name2.compareTo(name1);
}
}

View file

@ -0,0 +1,98 @@
/*
* 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.jstat;
/**
* A class that represents a mathematical expression as a tree structure
* containing operators as interior nodes and operands as leaves. The
* operands can be literals or lazily bound variables.
*
* @author Brian Doherty
* @since 1.5
*/
public class Expression {
private static int nextOrdinal;
private boolean debug = Boolean.getBoolean("Expression.debug");
private Expression left;
private Expression right;
private Operator operator;
private int ordinal = nextOrdinal++;
Expression() {
if (debug) {
System.out.println("Expression " + ordinal + " created");
}
}
void setLeft(Expression left) {
if (debug) {
System.out.println("Setting left on " + ordinal + " to " + left);
}
this.left = left;
}
Expression getLeft() {
return left;
}
void setRight(Expression right) {
if (debug) {
System.out.println("Setting right on " + ordinal + " to " + right);
}
this.right = right;
}
Expression getRight() {
return right;
}
void setOperator(Operator o) {
if (debug) {
System.out.println("Setting operator on " + ordinal + " to " + o);
}
this.operator = o;
}
Operator getOperator() {
return operator;
}
public String toString() {
StringBuilder b = new StringBuilder();
b.append('(');
if (left != null) {
b.append(left.toString());
}
if (operator != null) {
b.append(operator.toString());
if (right != null) {
b.append(right.toString());
}
}
b.append(')');
return b.toString();
}
}

View file

@ -0,0 +1,39 @@
/*
* 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.jstat;
import sun.jvmstat.monitor.MonitorException;
/**
* An interface to allow an object to visit an Expression object and
* evaluate based on some context.
*
* @author Brian Doherty
* @since 1.5
*/
interface ExpressionEvaluator {
Object evaluate(Expression e) throws MonitorException;
}

View file

@ -0,0 +1,96 @@
/*
* 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.jstat;
import java.util.*;
import sun.jvmstat.monitor.*;
/**
* A class implementing the ExpressionEvaluator to evaluate an expression
* in the context of the available monitoring data.
*
* @author Brian Doherty
* @since 1.5
*/
public class ExpressionExecuter implements ExpressionEvaluator {
private static final boolean debug =
Boolean.getBoolean("ExpressionEvaluator.debug");
private MonitoredVm vm;
private HashMap<String, Object> map = new HashMap<String, Object>();
ExpressionExecuter(MonitoredVm vm) {
this.vm = vm;
}
/*
* evaluate the given expression.
*/
public Object evaluate(Expression e) {
if (e == null) {
return null;
}
if (debug) {
System.out.println("Evaluating expression: " + e);
}
if (e instanceof Literal) {
return ((Literal)e).getValue();
}
if (e instanceof Identifier) {
Identifier id = (Identifier)e;
if (map.containsKey(id.getName())) {
return map.get(id.getName());
} else {
// cache the data values for coherency of the values over
// the life of this expression executer.
Monitor m = (Monitor)id.getValue();
Object v = m.getValue();
map.put(id.getName(), v);
return v;
}
}
Expression l = e.getLeft();
Expression r = e.getRight();
Operator op = e.getOperator();
if (op == null) {
return evaluate(l);
} else {
double lval = ((Number)evaluate(l)).doubleValue();
double rval = ((Number)evaluate(r)).doubleValue();
double result = op.eval(lval, rval);
if (debug) {
System.out.println("Performed Operation: " + lval + op + rval
+ " = " + result);
}
return Double.valueOf(result);
}
}
}

View file

@ -0,0 +1,145 @@
/*
* Copyright (c) 2004, 2010, 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.jstat;
import sun.jvmstat.monitor.*;
/**
* A class implementing the ExpressionEvaluator to resolve unresolved
* symbols in an Expression in the context of the available monitoring data.
* This class also performs some minimal optimizations of the expressions,
* such as simplification of constant subexpressions.
*
* @author Brian Doherty
* @since 1.5
*/
public class ExpressionResolver implements ExpressionEvaluator {
private static boolean debug = Boolean.getBoolean("ExpressionResolver.debug");
private MonitoredVm vm;
ExpressionResolver(MonitoredVm vm) {
this.vm = vm;
}
/*
* evaluate the given expression. evaluation in this case means
* to resolve the counter names in the expression
*/
public Object evaluate(Expression e) throws MonitorException {
if (e == null) {
return null;
}
if (debug) {
System.out.println("Resolving Expression:" + e);
}
if (e instanceof Identifier) {
Identifier id = (Identifier)e;
// check if it's already resolved
if (id.isResolved()) {
return id;
}
// look it up
Monitor m = vm.findByName(id.getName());
if (m == null) {
System.err.println("Warning: Unresolved Symbol: "
+ id.getName() + " substituted NaN");
return new Literal(Double.valueOf(Double.NaN));
}
if (m.getVariability() == Variability.CONSTANT) {
if (debug) {
System.out.println("Converting constant " + id.getName()
+ " to literal with value "
+ m.getValue());
}
return new Literal(m.getValue());
}
id.setValue(m);
return id;
}
if (e instanceof Literal) {
return e;
}
Expression l = null;
Expression r = null;
if (e.getLeft() != null) {
l = (Expression)evaluate(e.getLeft());
}
if (e.getRight() != null) {
r = (Expression)evaluate(e.getRight());
}
if (l != null && r != null) {
if ((l instanceof Literal) && (r instanceof Literal)) {
Literal ll = (Literal)l;
Literal rl = (Literal)r;
boolean warn = false;
Double nan = Double.valueOf(Double.NaN);
if (ll.getValue() instanceof String) {
warn = true; ll.setValue(nan);
}
if (rl.getValue() instanceof String) {
warn = true; rl.setValue(nan);
}
if (debug && warn) {
System.out.println("Warning: String literal in "
+ "numerical expression: "
+ "substitutied NaN");
}
// perform the operation
Number ln = (Number)ll.getValue();
Number rn = (Number)rl.getValue();
double result = e.getOperator().eval(ln.doubleValue(),
rn.doubleValue());
if (debug) {
System.out.println("Converting expression " + e
+ " (left = " + ln.doubleValue() + ")"
+ " (right = " + rn.doubleValue() + ")"
+ " to literal value " + result);
}
return new Literal(Double.valueOf(result));
}
}
if (l != null && r == null) {
return l;
}
e.setLeft(l);
e.setRight(r);
return e;
}
}

View file

@ -0,0 +1,98 @@
/*
* 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.jstat;
import sun.jvmstat.monitor.MonitorException;
/**
* A class implementing the Closure interface that visits the nodes of
* the nodes of a ColumFormat object and computes the header string for
* the columns of data.
*
* @author Brian Doherty
* @since 1.5
*/
public class HeaderClosure implements Closure {
private static final char ALIGN_CHAR = '^';
private StringBuilder header = new StringBuilder();
/*
* visit an object to perform some operation. In this case, the
* object is a ColumnFormat we are building the header string.
*/
public void visit(Object o, boolean hasNext) throws MonitorException {
if (! (o instanceof ColumnFormat)) {
return;
}
ColumnFormat c = (ColumnFormat)o;
String h = c.getHeader();
// check for special alignment character
if (h.indexOf(ALIGN_CHAR) >= 0) {
int len = h.length();
if ((h.charAt(0) == ALIGN_CHAR)
&& (h.charAt(len-1) == ALIGN_CHAR)) {
// ^<header>^ case - center alignment
c.setWidth(Math.max(c.getWidth(),
Math.max(c.getFormat().length(), len-2)));
h = h.substring(1, len-1);
h = Alignment.CENTER.align(h, c.getWidth());
} else if (h.charAt(0) == ALIGN_CHAR) {
// ^<header> case - left alignment
c.setWidth(Math.max(c.getWidth(),
Math.max(c.getFormat().length(), len-1)));
h = h.substring(1, len);
h = Alignment.LEFT.align(h, c.getWidth());
} else if (h.charAt(len-1) == ALIGN_CHAR) {
// <header>^ case - right alignment
c.setWidth(Math.max(c.getWidth(),
Math.max(c.getFormat().length(), len-1)));
h = h.substring(0, len-1);
h = Alignment.RIGHT.align(h, c.getWidth());
} else {
// an internal alignment character - ignore
}
} else {
// User has provided their own padding for alignment purposes
}
header.append(h);
if (hasNext) {
header.append(" ");
}
}
/*
* get the header string.
*/
public String getHeader() {
return header.toString();
}
}

View file

@ -0,0 +1,64 @@
/*
* 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.jstat;
/**
* An Expression subclass that describes the variable operands of an
* expression. Objects of this type are always leaves of an expression tree.
*
* @author Brian Doherty
* @since 1.5
*/
public class Identifier extends Expression {
private String name;
private Object value;
public Identifier(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setValue(Object value) {
this.value = value;
}
public Object getValue() {
return value;
}
public boolean isResolved() {
return value != null;
}
public String toString() {
return name;
}
}

View file

@ -0,0 +1,159 @@
/*
* Copyright (c) 2004, 2010, 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.jstat;
import java.util.*;
import java.io.*;
import sun.jvmstat.monitor.*;
import sun.jvmstat.monitor.event.*;
import java.util.regex.PatternSyntaxException;
/**
* Class to sample and output various jvmstat statistics for a target Java
* a target Java Virtual Machine.
*
* @author Brian Doherty
* @since 1.5
*/
public class JStatLogger {
private MonitoredVm monitoredVm;
private volatile boolean active = true;
public JStatLogger(MonitoredVm monitoredVm) {
this.monitoredVm = monitoredVm;
}
/**
* print the monitors that match the given monitor name pattern string.
*/
public void printNames(String names, Comparator<Monitor> comparator,
boolean showUnsupported, PrintStream out)
throws MonitorException, PatternSyntaxException {
// get the set of all monitors
List<Monitor> items = monitoredVm.findByPattern(names);
Collections.sort(items, comparator);
for (Monitor m: items) {
if (!(m.isSupported() || showUnsupported)) {
continue;
}
out.println(m.getName());
}
}
/**
* print name=value pairs for the given list of monitors.
*/
public void printSnapShot(String names, Comparator<Monitor> comparator,
boolean verbose, boolean showUnsupported,
PrintStream out)
throws MonitorException, PatternSyntaxException {
// get the set of all monitors
List<Monitor> items = monitoredVm.findByPattern(names);
Collections.sort(items, comparator);
printList(items, verbose, showUnsupported, out);
}
/**
* print name=value pairs for the given list of monitors.
*/
public void printList(List<Monitor> list, boolean verbose, boolean showUnsupported,
PrintStream out)
throws MonitorException {
// print out the name of each available counter
for (Monitor m: list ) {
if (!(m.isSupported() || showUnsupported)) {
continue;
}
StringBuilder buffer = new StringBuilder();
buffer.append(m.getName()).append("=");
if (m instanceof StringMonitor) {
buffer.append("\"").append(m.getValue()).append("\"");
} else {
buffer.append(m.getValue());
}
if (verbose) {
buffer.append(" ").append(m.getUnits());
buffer.append(" ").append(m.getVariability());
buffer.append(" ").append(m.isSupported() ? "Supported"
: "Unsupported");
}
out.println(buffer);
}
}
/**
* method to for asynchronous termination of sampling loops
*/
public void stopLogging() {
active = false;
}
/**
* print samples according to the given format.
*/
public void logSamples(OutputFormatter formatter, int headerRate,
int sampleInterval, int sampleCount, PrintStream out)
throws MonitorException {
long iterationCount = 0;
int printHeaderCount = 0;
// if printHeader == 0, then only an initial column header is desired.
int printHeader = headerRate;
if (printHeader == 0) {
// print the column header once, disable future printing
out.println(formatter.getHeader());
printHeader = -1;
}
while (active) {
// check if it's time to print another column header
if (printHeader > 0 && --printHeaderCount <= 0) {
printHeaderCount = printHeader;
out.println(formatter.getHeader());
}
out.println(formatter.getRow());
// check if we've hit the specified sample count
if (sampleCount > 0 && ++iterationCount >= sampleCount) {
break;
}
try { Thread.sleep(sampleInterval); } catch (Exception e) { };
}
}
}

View file

@ -0,0 +1,190 @@
/*
* Copyright (c) 2004, 2010, 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.jstat;
import java.util.*;
import sun.jvmstat.monitor.*;
import sun.jvmstat.monitor.event.*;
/**
* Application to output jvmstat statistics exported by a target Java
* Virtual Machine. The jstat tool gets its inspiration from the suite
* of 'stat' tools, such as vmstat, iostat, mpstat, etc., available in
* various UNIX platforms.
*
* @author Brian Doherty
* @since 1.5
*/
public class Jstat {
private static Arguments arguments;
public static void main(String[] args) {
try {
arguments = new Arguments(args);
} catch (IllegalArgumentException e) {
System.err.println(e.getMessage());
Arguments.printUsage(System.err);
System.exit(1);
}
if (arguments.isHelp()) {
Arguments.printUsage(System.out);
System.exit(0);
}
if (arguments.isOptions()) {
OptionLister ol = new OptionLister(arguments.optionsSources());
ol.print(System.out);
System.exit(0);
}
try {
if (arguments.isList()) {
logNames();
} else if (arguments.isSnap()) {
logSnapShot();
} else {
logSamples();
}
} catch (MonitorException e) {
e.printStackTrace();
System.exit(1);
}
System.exit(0);
}
static void logNames() throws MonitorException {
VmIdentifier vmId = arguments.vmId();
int interval = arguments.sampleInterval();
MonitoredHost monitoredHost = MonitoredHost.getMonitoredHost(vmId);
MonitoredVm monitoredVm = monitoredHost.getMonitoredVm(vmId, interval);
JStatLogger logger = new JStatLogger(monitoredVm);
logger.printNames(arguments.counterNames(), arguments.comparator(),
arguments.showUnsupported(), System.out);
monitoredHost.detach(monitoredVm);
}
static void logSnapShot() throws MonitorException {
VmIdentifier vmId = arguments.vmId();
int interval = arguments.sampleInterval();
MonitoredHost monitoredHost = MonitoredHost.getMonitoredHost(vmId);
MonitoredVm monitoredVm = monitoredHost.getMonitoredVm(vmId, interval);
JStatLogger logger = new JStatLogger(monitoredVm);
logger.printSnapShot(arguments.counterNames(), arguments.comparator(),
arguments.isVerbose(), arguments.showUnsupported(),
System.out);
monitoredHost.detach(monitoredVm);
}
static void logSamples() throws MonitorException {
final VmIdentifier vmId = arguments.vmId();
int interval = arguments.sampleInterval();
final MonitoredHost monitoredHost =
MonitoredHost.getMonitoredHost(vmId);
MonitoredVm monitoredVm = monitoredHost.getMonitoredVm(vmId, interval);
final JStatLogger logger = new JStatLogger(monitoredVm);
OutputFormatter formatter = null;
if (arguments.isSpecialOption()) {
OptionFormat format = arguments.optionFormat();
formatter = new OptionOutputFormatter(monitoredVm, format);
} else {
List<Monitor> logged = monitoredVm.findByPattern(arguments.counterNames());
Collections.sort(logged, arguments.comparator());
List<Monitor> constants = new ArrayList<Monitor>();
for (Iterator<Monitor> i = logged.iterator(); i.hasNext(); /* empty */) {
Monitor m = i.next();
if (!(m.isSupported() || arguments.showUnsupported())) {
i.remove();
continue;
}
if (m.getVariability() == Variability.CONSTANT) {
i.remove();
if (arguments.printConstants()) constants.add(m);
} else if ((m.getUnits() == Units.STRING)
&& !arguments.printStrings()) {
i.remove();
}
}
if (!constants.isEmpty()) {
logger.printList(constants, arguments.isVerbose(),
arguments.showUnsupported(), System.out);
if (!logged.isEmpty()) {
System.out.println();
}
}
if (logged.isEmpty()) {
monitoredHost.detach(monitoredVm);
return;
}
formatter = new RawOutputFormatter(logged,
arguments.printStrings());
}
// handle user termination requests by stopping sampling loops
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
logger.stopLogging();
}
});
// handle target termination events for targets other than ourself
HostListener terminator = new HostListener() {
public void vmStatusChanged(VmStatusChangeEvent ev) {
Integer lvmid = vmId.getLocalVmId();
if (ev.getTerminated().contains(lvmid)) {
logger.stopLogging();
} else if (!ev.getActive().contains(lvmid)) {
logger.stopLogging();
}
}
public void disconnected(HostEvent ev) {
if (monitoredHost == ev.getMonitoredHost()) {
logger.stopLogging();
}
}
};
if (vmId.getLocalVmId() != 0) {
monitoredHost.addHostListener(terminator);
}
logger.logSamples(formatter, arguments.headerRate(),
arguments.sampleInterval(), arguments.sampleCount(),
System.out);
// detach from host events and from the monitored target jvm
if (terminator != null) {
monitoredHost.removeHostListener(terminator);
}
monitoredHost.detach(monitoredVm);
}
}

View file

@ -0,0 +1,55 @@
/*
* 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.jstat;
/**
* An Expression subclass that describes the constant operands of an
* expression. Objects of this type are always leaves of an expression tree.
*
* @author Brian Doherty
* @since 1.5
*/
public class Literal extends Expression {
private Object value;
public Literal(Object value) {
super();
this.value = value;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
public String toString() {
return value.toString();
}
}

View file

@ -0,0 +1,111 @@
/*
* 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.jstat;
import java.util.*;
/**
* A typesafe enumeration for describing mathematical operators.
*
* @author Brian Doherty
* @since 1.5
*/
public abstract class Operator {
private static int nextOrdinal = 0;
private static HashMap<String, Operator> map = new HashMap<String, Operator>();
private final String name;
private final int ordinal = nextOrdinal++;
private Operator(String name) {
this.name = name;
map.put(name, this);
}
protected abstract double eval(double x, double y);
/* Operator '+' */
public static final Operator PLUS = new Operator("+") {
protected double eval(double x, double y) {
return x + y;
}
};
/* Operator '-' */
public static final Operator MINUS = new Operator("-") {
protected double eval(double x, double y) {
return x - y;
}
};
/* Operator '/' */
public static final Operator DIVIDE = new Operator("/") {
protected double eval(double x, double y) {
if (y == 0) {
return Double.NaN;
}
return x / y;
}
};
/* Operator '*' */
public static final Operator MULTIPLY = new Operator("*") {
protected double eval(double x, double y) {
return x * y;
}
};
/**
* Returns the string representation of this Operator object.
*
* @return the string representation of this Operator object
*/
public String toString() {
return name;
}
/**
* Maps a string to its corresponding Operator object.
*
* @param s an string to match against Operator objects.
* @return The Operator object matching the given string.
*/
public static Operator toOperator(String s) {
return map.get(s);
}
/**
* Returns an enumeration of the keys for this enumerated type
*
* @param s an string to match against Operator objects.
* @return The Operator object matching the given string.
*/
protected static Set<?> keySet() {
return map.keySet();
}
}

View file

@ -0,0 +1,85 @@
/*
* Copyright (c) 2004, 2010, 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.jstat;
import java.util.*;
import java.net.*;
import java.io.*;
/**
* A class for finding a specific special option in the jstat_options file.
*
* @author Brian Doherty
* @since 1.5
*/
public class OptionFinder {
private static final boolean debug = false;
List<URL> optionsSources;
public OptionFinder(List<URL> optionsSources) {
this.optionsSources = optionsSources;
}
public OptionFormat getOptionFormat(String option, boolean useTimestamp) {
OptionFormat of = getOptionFormat(option, optionsSources);
OptionFormat tof = null;
if ((of != null) && (useTimestamp)) {
// prepend the timestamp column as first column
tof = getOptionFormat("timestamp", optionsSources);
if (tof != null) {
ColumnFormat cf = (ColumnFormat)tof.getSubFormat(0);
of.insertSubFormat(0, cf);
}
}
return of;
}
protected OptionFormat getOptionFormat(String option, List<URL> sources) {
OptionFormat of = null;
for (URL u : sources) {
try {
Reader r = new BufferedReader(
new InputStreamReader(u.openStream()));
of = new Parser(r).parse(option);
if (of != null)
break;
} catch (IOException e) {
if (debug) {
System.err.println("Error processing " + u
+ " : " + e.getMessage());
e.printStackTrace();
}
} catch (ParserException e) {
// Exception in parsing the options file.
System.err.println(u + ": " + e.getMessage());
System.err.println("Parsing of " + u + " aborted");
}
}
return of;
}
}

View file

@ -0,0 +1,110 @@
/*
* 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.jstat;
import java.util.*;
import sun.jvmstat.monitor.MonitorException;
/**
* A class for describing the output format specified by a command
* line option that was parsed from an option description file.
*
* @author Brian Doherty
* @since 1.5
*/
public class OptionFormat {
protected String name;
protected List<OptionFormat> children;
public OptionFormat(String name) {
this.name = name;
this.children = new ArrayList<OptionFormat>();
}
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof OptionFormat)) {
return false;
}
OptionFormat of = (OptionFormat)o;
return (this.name.compareTo(of.name) == 0);
}
public int hashCode() {
return name.hashCode();
}
public void addSubFormat(OptionFormat f) {
children.add(f);
}
public OptionFormat getSubFormat(int index) {
return children.get(index);
}
public void insertSubFormat(int index, OptionFormat f) {
children.add(index, f);
}
public String getName() {
return name;
}
public void apply(Closure c) throws MonitorException {
for (Iterator<OptionFormat> i = children.iterator(); i.hasNext(); /* empty */) {
OptionFormat o = i.next();
c.visit(o, i.hasNext());
}
for (Iterator <OptionFormat>i = children.iterator(); i.hasNext(); /* empty */) {
OptionFormat o = i.next();
o.apply(c);
}
}
public void printFormat() {
printFormat(0);
}
public void printFormat(int indentLevel) {
String indentAmount = " ";
StringBuilder indent = new StringBuilder("");
for (int j = 0; j < indentLevel; j++) {
indent.append(indentAmount);
}
System.out.println(indent + name + " {");
// iterate over all children and call their printFormat() methods
for (OptionFormat of : children) {
of.printFormat(indentLevel+1);
}
System.out.println(indent + "}");
}
}

View file

@ -0,0 +1,83 @@
/*
* Copyright (c) 2004, 2010, 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.jstat;
import java.util.*;
import java.net.*;
import java.io.*;
/**
* A class for listing the available options in the jstat_options file.
*
* @author Brian Doherty
* @since 1.5
*/
public class OptionLister {
private static final boolean debug = false;
private List<URL> sources;
public OptionLister(List<URL> sources) {
this.sources = sources;
}
public void print(PrintStream ps) {
Comparator<OptionFormat> c = new Comparator<OptionFormat>() {
public int compare(OptionFormat o1, OptionFormat o2) {
OptionFormat of1 = o1;
OptionFormat of2 = o2;
return (of1.getName().compareTo(of2.getName()));
}
};
Set<OptionFormat> options = new TreeSet<OptionFormat>(c);
for (URL u : sources) {
try {
Reader r = new BufferedReader(
new InputStreamReader(u.openStream()));
Set<OptionFormat> s = new Parser(r).parseOptions();
options.addAll(s);
} catch (IOException e) {
if (debug) {
System.err.println(e.getMessage());
e.printStackTrace();
}
} catch (ParserException e) {
// Exception in parsing the options file.
System.err.println(u + ": " + e.getMessage());
System.err.println("Parsing of " + u + " aborted");
}
}
for ( OptionFormat of : options) {
if (of.getName().compareTo("timestamp") == 0) {
// ignore the special timestamp OptionFormat.
continue;
}
ps.println("-" + of.getName());
}
}
}

View file

@ -0,0 +1,69 @@
/*
* 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.jstat;
import sun.jvmstat.monitor.*;
/**
* A class for applying an OptionFormat to a particular context, the context
* of the available Instrumentation for a monitorable Java Virtual Machine.
*
* @author Brian Doherty
* @since 1.5
*/
public class OptionOutputFormatter implements OutputFormatter {
private OptionFormat format;
private String header;
private MonitoredVm vm;
public OptionOutputFormatter(MonitoredVm vm, OptionFormat format)
throws MonitorException {
this.vm = vm;
this.format = format;
resolve();
}
private void resolve() throws MonitorException {
ExpressionEvaluator ee = new ExpressionResolver(vm);
SymbolResolutionClosure ec = new SymbolResolutionClosure(ee);
format.apply(ec);
}
public String getHeader() throws MonitorException {
if (header == null) {
HeaderClosure hc = new HeaderClosure();
format.apply(hc);
header = hc.getHeader();
}
return header;
}
public String getRow() throws MonitorException {
RowClosure rc = new RowClosure(vm);
format.apply(rc);
return rc.getRow();
}
}

View file

@ -0,0 +1,47 @@
/*
* 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.jstat;
import sun.jvmstat.monitor.MonitorException;
/**
* An interface for the JStatLogger formatting.
*
* @author Brian Doherty
* @since 1.5
*/
public interface OutputFormatter {
/**
* get the header row that describes the data in the columns
*/
String getHeader() throws MonitorException;
/**
* get the data row.
*/
String getRow() throws MonitorException;
}

View file

@ -0,0 +1,585 @@
/*
* 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.jstat;
import java.io.*;
import java.util.*;
/**
* A class implementing a simple predictive parser for output format
* specification language for the jstat command.
*
* @author Brian Doherty
* @since 1.5
*/
public class Parser {
private static boolean pdebug = Boolean.getBoolean("jstat.parser.debug");
private static boolean ldebug = Boolean.getBoolean("jstat.lex.debug");
private static final char OPENBLOCK = '{';
private static final char CLOSEBLOCK = '}';
private static final char DOUBLEQUOTE = '"';
private static final char PERCENT_CHAR = '%';
private static final char OPENPAREN = '(';
private static final char CLOSEPAREN = ')';
private static final char OPERATOR_PLUS = '+';
private static final char OPERATOR_MINUS = '-';
private static final char OPERATOR_MULTIPLY = '*';
private static final char OPERATOR_DIVIDE = '/';
private static final String OPTION = "option";
private static final String COLUMN = "column";
private static final String DATA = "data";
private static final String HEADER = "header";
private static final String WIDTH = "width";
private static final String FORMAT = "format";
private static final String ALIGN = "align";
private static final String SCALE = "scale";
private static final String START = OPTION;
private static final Set<String> scaleKeyWords = Scale.keySet();
private static final Set<String> alignKeyWords = Alignment.keySet();
private static String[] otherKeyWords = {
OPTION, COLUMN, DATA, HEADER, WIDTH, FORMAT, ALIGN, SCALE
};
private static char[] infixOps = {
OPERATOR_PLUS, OPERATOR_MINUS, OPERATOR_MULTIPLY, OPERATOR_DIVIDE
};
private static char[] delimiters = {
OPENBLOCK, CLOSEBLOCK, PERCENT_CHAR, OPENPAREN, CLOSEPAREN
};
private static Set<String> reservedWords;
private StreamTokenizer st;
private String filename;
private Token lookahead;
private Token previous;
private int columnCount;
private OptionFormat optionFormat;
public Parser(String filename) throws FileNotFoundException {
this.filename = filename;
Reader r = new BufferedReader(new FileReader(filename));
}
public Parser(Reader r) {
st = new StreamTokenizer(r);
// allow both c++ style comments
st.ordinaryChar('/');
st.wordChars('_','_');
st.slashSlashComments(true);
st.slashStarComments(true);
reservedWords = new HashSet<String>();
for (int i = 0; i < otherKeyWords.length; i++) {
reservedWords.add(otherKeyWords[i]);
}
for (int i = 0; i < delimiters.length; i++ ) {
st.ordinaryChar(delimiters[i]);
}
for (int i = 0; i < infixOps.length; i++ ) {
st.ordinaryChar(infixOps[i]);
}
}
/**
* push back the lookahead token and restore the lookahead token
* to the previous token.
*/
private void pushBack() {
lookahead = previous;
st.pushBack();
}
/**
* retrieve the next token, placing the token value in the lookahead
* member variable, storing its previous value in the previous member
* variable.
*/
private void nextToken() throws ParserException, IOException {
int t = st.nextToken();
previous = lookahead;
lookahead = new Token(st.ttype, st.sval, st.nval);
log(ldebug, "lookahead = " + lookahead);
}
/**
* match one of the token values in the given set of key words
* token is assumed to be of type TT_WORD, and the set is assumed
* to contain String objects.
*/
private Token matchOne(Set<String> keyWords) throws ParserException, IOException {
if ((lookahead.ttype == StreamTokenizer.TT_WORD)
&& keyWords.contains(lookahead.sval)) {
Token t = lookahead;
nextToken();
return t;
}
throw new SyntaxException(st.lineno(), keyWords, lookahead);
}
/**
* match a token with TT_TYPE=type, and the token value is a given sequence
* of characters.
*/
private void match(int ttype, String token)
throws ParserException, IOException {
if (lookahead.ttype == ttype && lookahead.sval.compareTo(token) == 0) {
nextToken();
} else {
throw new SyntaxException(st.lineno(), new Token(ttype, token),
lookahead);
}
}
/**
* match a token with TT_TYPE=type
*/
private void match(int ttype) throws ParserException, IOException {
if (lookahead.ttype == ttype) {
nextToken();
} else {
throw new SyntaxException(st.lineno(), new Token(ttype), lookahead);
}
}
/**
* match a token with TT_TYPE=char, where the token value is the given char.
*/
private void match(char ttype) throws ParserException, IOException {
if (lookahead.ttype == (int)ttype) {
nextToken();
}
else {
throw new SyntaxException(st.lineno(), new Token((int)ttype),
lookahead);
}
}
/**
* match a token with TT_TYPE='"', where the token value is a sequence
* of characters between matching quote characters.
*/
private void matchQuotedString() throws ParserException, IOException {
match(DOUBLEQUOTE);
}
/**
* match a TT_NUMBER token that matches a parsed number value
*/
private void matchNumber() throws ParserException, IOException {
match(StreamTokenizer.TT_NUMBER);
}
/**
* match a TT_WORD token that matches an arbitrary, not quoted token.
*/
private void matchID() throws ParserException, IOException {
match(StreamTokenizer.TT_WORD);
}
/**
* match a TT_WORD token that matches the given string
*/
private void match(String token) throws ParserException, IOException {
match(StreamTokenizer.TT_WORD, token);
}
/**
* determine if the given word is a reserved key word
*/
private boolean isReservedWord(String word) {
return reservedWords.contains(word);
}
/**
* determine if the give work is a reserved key word
*/
private boolean isInfixOperator(char op) {
for (int i = 0; i < infixOps.length; i++) {
if (op == infixOps[i]) {
return true;
}
}
return false;
}
/**
* scalestmt -> 'scale' scalespec
* scalespec -> <see above scaleTerminals array>
*/
private void scaleStmt(ColumnFormat cf)
throws ParserException, IOException {
match(SCALE);
Token t = matchOne(scaleKeyWords);
cf.setScale(Scale.toScale(t.sval));
String scaleString = t.sval;
log(pdebug, "Parsed: scale -> " + scaleString);
}
/**
* alignstmt -> 'align' alignspec
* alignspec -> <see above alignTerminals array>
*/
private void alignStmt(ColumnFormat cf)
throws ParserException, IOException {
match(ALIGN);
Token t = matchOne(alignKeyWords);
cf.setAlignment(Alignment.toAlignment(t.sval));
String alignString = t.sval;
log(pdebug, "Parsed: align -> " + alignString);
}
/**
* headerstmt -> 'header' quotedstring
*/
private void headerStmt(ColumnFormat cf)
throws ParserException, IOException {
match(HEADER);
String headerString = lookahead.sval;
matchQuotedString();
cf.setHeader(headerString);
log(pdebug, "Parsed: header -> " + headerString);
}
/**
* widthstmt -> 'width' integer
*/
private void widthStmt(ColumnFormat cf)
throws ParserException, IOException {
match(WIDTH);
double width = lookahead.nval;
matchNumber();
cf.setWidth((int)width);
log(pdebug, "Parsed: width -> " + width );
}
/**
* formatstmt -> 'format' quotedstring
*/
private void formatStmt(ColumnFormat cf)
throws ParserException, IOException {
match(FORMAT);
String formatString = lookahead.sval;
matchQuotedString();
cf.setFormat(formatString);
log(pdebug, "Parsed: format -> " + formatString);
}
/**
* Primary -> Literal | Identifier | '(' Expression ')'
*/
private Expression primary() throws ParserException, IOException {
Expression e = null;
switch (lookahead.ttype) {
case OPENPAREN:
match(OPENPAREN);
e = expression();
match(CLOSEPAREN);
break;
case StreamTokenizer.TT_WORD:
String s = lookahead.sval;
if (isReservedWord(s)) {
throw new SyntaxException(st.lineno(), "IDENTIFIER",
"Reserved Word: " + lookahead.sval);
}
matchID();
e = new Identifier(s);
log(pdebug, "Parsed: ID -> " + s);
break;
case StreamTokenizer.TT_NUMBER:
double literal = lookahead.nval;
matchNumber();
e = new Literal(Double.valueOf(literal));
log(pdebug, "Parsed: number -> " + literal);
break;
default:
throw new SyntaxException(st.lineno(), "IDENTIFIER", lookahead);
}
log(pdebug, "Parsed: primary -> " + e);
return e;
}
/**
* Unary -> ('+'|'-') Unary | Primary
*/
private Expression unary() throws ParserException, IOException {
Expression e = null;
Operator op = null;
while (true) {
switch (lookahead.ttype) {
case OPERATOR_PLUS:
match(OPERATOR_PLUS);
op = Operator.PLUS;
break;
case OPERATOR_MINUS:
match(OPERATOR_MINUS);
op = Operator.MINUS;
break;
default:
e = primary();
log(pdebug, "Parsed: unary -> " + e);
return e;
}
Expression e1 = new Expression();
e1.setOperator(op);
e1.setRight(e);
log(pdebug, "Parsed: unary -> " + e1);
e1.setLeft(new Literal(Double.valueOf(0)));
e = e1;
}
}
/**
* MultExpression -> Unary (('*' | '/') Unary)*
*/
private Expression multExpression() throws ParserException, IOException {
Expression e = unary();
Operator op = null;
while (true) {
switch (lookahead.ttype) {
case OPERATOR_MULTIPLY:
match(OPERATOR_MULTIPLY);
op = Operator.MULTIPLY;
break;
case OPERATOR_DIVIDE:
match(OPERATOR_DIVIDE);
op = Operator.DIVIDE;
break;
default:
log(pdebug, "Parsed: multExpression -> " + e);
return e;
}
Expression e1 = new Expression();
e1.setOperator(op);
e1.setLeft(e);
e1.setRight(unary());
e = e1;
log(pdebug, "Parsed: multExpression -> " + e);
}
}
/**
* AddExpression -> MultExpression (('+' | '-') MultExpression)*
*/
private Expression addExpression() throws ParserException, IOException {
Expression e = multExpression();
Operator op = null;
while (true) {
switch (lookahead.ttype) {
case OPERATOR_PLUS:
match(OPERATOR_PLUS);
op = Operator.PLUS;
break;
case OPERATOR_MINUS:
match(OPERATOR_MINUS);
op = Operator.MINUS;
break;
default:
log(pdebug, "Parsed: addExpression -> " + e);
return e;
}
Expression e1 = new Expression();
e1.setOperator(op);
e1.setLeft(e);
e1.setRight(multExpression());
e = e1;
log(pdebug, "Parsed: addExpression -> " + e);
}
}
/**
* Expression -> AddExpression
*/
private Expression expression() throws ParserException, IOException {
Expression e = addExpression();
log(pdebug, "Parsed: expression -> " + e);
return e;
}
/**
* datastmt -> 'data' expression
*/
private void dataStmt(ColumnFormat cf) throws ParserException, IOException {
match(DATA);
Expression e = expression();
cf.setExpression(e);
log(pdebug, "Parsed: data -> " + e);
}
/**
* statementlist -> optionalstmt statementlist
* optionalstmt -> 'data' expression
* 'header' quotedstring
* 'width' integer
* 'format' formatstring
* 'align' alignspec
* 'scale' scalespec
*/
private void statementList(ColumnFormat cf)
throws ParserException, IOException {
while (true) {
if (lookahead.ttype != StreamTokenizer.TT_WORD) {
return;
}
if (lookahead.sval.compareTo(DATA) == 0) {
dataStmt(cf);
} else if (lookahead.sval.compareTo(HEADER) == 0) {
headerStmt(cf);
} else if (lookahead.sval.compareTo(WIDTH) == 0) {
widthStmt(cf);
} else if (lookahead.sval.compareTo(FORMAT) == 0) {
formatStmt(cf);
} else if (lookahead.sval.compareTo(ALIGN) == 0) {
alignStmt(cf);
} else if (lookahead.sval.compareTo(SCALE) == 0) {
scaleStmt(cf);
} else {
return;
}
}
}
/**
* optionlist -> columspec optionlist
* null
* columspec -> 'column' '{' statementlist '}'
*/
private void optionList(OptionFormat of)
throws ParserException, IOException {
while (true) {
if (lookahead.ttype != StreamTokenizer.TT_WORD) {
return;
}
match(COLUMN);
match(OPENBLOCK);
ColumnFormat cf = new ColumnFormat(columnCount++);
statementList(cf);
match(CLOSEBLOCK);
cf.validate();
of.addSubFormat(cf);
}
}
/**
* optionstmt -> 'option' ID '{' optionlist '}'
*/
private OptionFormat optionStmt() throws ParserException, IOException {
match(OPTION);
String optionName=lookahead.sval;
matchID();
match(OPENBLOCK);
OptionFormat of = new OptionFormat(optionName);
optionList(of);
match(CLOSEBLOCK);
return of;
}
/**
* parse the specification for the given option identifier
*/
public OptionFormat parse(String option)
throws ParserException, IOException {
nextToken();
/*
* this search stops on the first occurance of an option
* statement with a name matching the given option. Any
* duplicate options are ignored.
*/
while (lookahead.ttype != StreamTokenizer.TT_EOF) {
// look for the start symbol
if ((lookahead.ttype != StreamTokenizer.TT_WORD)
|| (lookahead.sval.compareTo(START) != 0)) {
// skip tokens until a start symbol is found
nextToken();
continue;
}
// check if the option name is the one we are interested in
match(START);
if ((lookahead.ttype == StreamTokenizer.TT_WORD)
&& (lookahead.sval.compareTo(option) == 0)) {
// this is the one we are looking for, parse it
pushBack();
return optionStmt();
} else {
// not what we are looking for, start skipping tokens
nextToken();
}
}
return null;
}
public Set<OptionFormat> parseOptions() throws ParserException, IOException {
Set<OptionFormat> options = new HashSet<OptionFormat>();
nextToken();
while (lookahead.ttype != StreamTokenizer.TT_EOF) {
// look for the start symbol
if ((lookahead.ttype != StreamTokenizer.TT_WORD)
|| (lookahead.sval.compareTo(START) != 0)) {
// skip tokens until a start symbol is found
nextToken();
continue;
}
// note: if a duplicate option statement exists, then
// first one encountered is the chosen definition.
OptionFormat of = optionStmt();
options.add(of);
}
return options;
}
OptionFormat getOptionFormat() {
return optionFormat;
}
private void log(boolean logging, String s) {
if (logging) {
System.out.println(s);
}
}
}

View file

@ -0,0 +1,44 @@
/*
* 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.tools.jstat;
/**
* A class for describing exceptions generated by the Parser class.
*
* @author Brian Doherty
* @since 1.5
*/
@SuppressWarnings("serial") // JDK implementation class
public class ParserException extends Exception {
public ParserException() {
super();
}
public ParserException(String msg) {
super(msg);
}
}

View file

@ -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.tools.jstat;
import java.util.*;
import sun.jvmstat.monitor.*;
/**
* A class for formatting raw counter output.
*
* @author Brian Doherty
* @since 1.5
*/
public class RawOutputFormatter implements OutputFormatter {
private List<Monitor> logged;
private String header;
private boolean printStrings;
public RawOutputFormatter(List<Monitor> logged, boolean printStrings) {
this.logged = logged;
this.printStrings = printStrings;
}
public String getHeader() throws MonitorException {
if (header == null) {
// build the header string and prune out any unwanted monitors
StringBuilder headerBuilder = new StringBuilder();
for (Iterator<Monitor> i = logged.iterator(); i.hasNext(); /* empty */ ) {
Monitor m = i.next();
headerBuilder.append(m.getName()).append(' ');
}
header = headerBuilder.toString();
}
return header;
}
public String getRow() throws MonitorException {
StringBuilder row = new StringBuilder();
int count = 0;
for (Iterator<Monitor> i = logged.iterator(); i.hasNext(); /* empty */ ) {
Monitor m = i.next();
if (count++ > 0) {
row.append(" ");
}
if (printStrings && m instanceof StringMonitor) {
row.append("\"").append(m.getValue()).append("\"");
} else {
row.append(m.getValue());
}
}
return row.toString();
}
}

View file

@ -0,0 +1,82 @@
/*
* Copyright (c) 2004, 2013, 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.jstat;
import java.text.*;
import sun.jvmstat.monitor.*;
/**
* A class implementing the Closure interface for iterating over the
* specified columns of data and generating the columnized string of
* data representing a row of output for the form.
*
* @author Brian Doherty
* @since 1.5
*/
public class RowClosure implements Closure {
private MonitoredVm vm;
private StringBuilder row = new StringBuilder();
public RowClosure(MonitoredVm vm) {
this.vm = vm;
}
public void visit(Object o, boolean hasNext) throws MonitorException {
if (! (o instanceof ColumnFormat)) {
return;
}
ColumnFormat c = (ColumnFormat)o;
String s = null;
Expression e = c.getExpression();
ExpressionEvaluator ee = new ExpressionExecuter(vm);
Object value = ee.evaluate(e);
if (value instanceof String) {
s = (String)value;
} else if (value instanceof Number) {
double d = ((Number)value).doubleValue();
double scaledValue = c.getScale().scale(d);
DecimalFormat df = new DecimalFormat(c.getFormat());
DecimalFormatSymbols syms = df.getDecimalFormatSymbols();
syms.setNaN("-");
df.setDecimalFormatSymbols(syms);
s = df.format(scaledValue);
}
c.setPreviousValue(value);
s = c.getAlignment().align(s, c.getWidth());
row.append(s);
if (hasNext) {
row.append(" ");
}
}
public String getRow() {
return row.toString();
}
}

View file

@ -0,0 +1,185 @@
/*
* 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.jstat;
import java.util.*;
/**
* A typesafe enumeration for describing data scaling semantics
*
* @author Brian Doherty
* @since 1.5
*/
public class Scale {
private static int nextOrdinal = 0;
private static HashMap<String, Scale> map = new HashMap<String, Scale>();
private final String name;
private final int ordinal = nextOrdinal++;
private final double factor;
private Scale(String name, double factor) {
this.name = name;
this.factor = factor;
assert !map.containsKey(name);
map.put(name, this);
}
/**
* Scale representing a no scaling
*/
public static final Scale RAW = new Scale("raw", 1);
/**
* Scale representing a percent scaling
*/
public static final Scale PERCENT = new Scale("percent", 1/100);
/**
* Scale representing a kilo scaling
*/
public static final Scale KILO = new Scale("K", 1024);
/**
* Scale representing a mega scaling
*/
public static final Scale MEGA = new Scale("M", 1024*1024);
/**
* Scale representing a giga scaling
*/
public static final Scale GIGA = new Scale("G", 1024*1024*1024);
/**
* Scale representing a tera scaling
*/
public static final Scale TERA = new Scale("T", 1024*1024*1024*1024);
/**
* Scale representing a tera scaling
*/
public static final Scale PETA = new Scale("P", 1024*1024*1024*1024*1024);
/**
* Scale representing a pico scaling
*/
public static final Scale PICO = new Scale("p", 10.0E-12);
/**
* Scale representing a nano scaling
*/
public static final Scale NANO = new Scale("n", 10.0E-9);
/**
* Scale representing a micro scaling
*/
public static final Scale MICRO = new Scale("u", 10.0E-6);
/**
* Scale representing a milli scaling
*/
public static final Scale MILLI = new Scale("m", 10.0E-3);
/**
* Scale representing a picosecond scaling
*/
public static final Scale PSEC = new Scale("ps", 10.0E-12);
/**
* Scale representing a nanosecond scaling
*/
public static final Scale NSEC = new Scale("ns", 10.0E-9);
/**
* Scale representing a microsecond scaling
*/
public static final Scale USEC = new Scale("us", 10.0E-6);
/**
* Scale representing a millisecond scaling
*/
public static final Scale MSEC = new Scale("ms", 10.0E-3);
/**
* Scale representing a second scaling
*/
public static final Scale SEC = new Scale("s", 1);
public static final Scale SEC2 = new Scale("sec", 1);
/**
* Scale representing a minutes scaling
*/
public static final Scale MINUTES = new Scale("min", 1/60.0);
/**
* Scale representing a hours scaling
*/
public static final Scale HOUR = new Scale("h", 1/(60.0*60.0));
public static final Scale HOUR2 = new Scale("hour", 1/(60.0*60.0));
/**
* Returns the scaling factor of this Scale object
*
* @return the scaling factor of this Scale object
*/
public double getFactor() {
return factor;
}
/**
* Returns the string representation of this Scale object.
* The string representation is the name of the Scale object.
*
* @return the string representation of this Scale object
*/
public String toString() {
return name;
}
/**
* Maps a string to its corresponding Scale object.
*
* @param s a string to match against Scale objects.
* @return The Scale object matching the given string.
*/
public static Scale toScale(String s) {
return map.get(s);
}
/**
* Returns an enumeration of the keys for this enumerated type
*
* @param s an string to match against Scale objects.
* @return The Scale object matching the given string.
*/
protected static Set<String> keySet() {
return map.keySet();
}
protected double scale(double value) {
return value/factor;
}
}

View file

@ -0,0 +1,63 @@
/*
* 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.jstat;
import java.text.*;
import sun.jvmstat.monitor.MonitorException;
/**
* A class implementing the Closure interface which is used to resolve
* all the symbols in the expressions contained in ColumnFormat objects.
*
* @author Brian Doherty
* @since 1.5
*/
public class SymbolResolutionClosure implements Closure {
private static final boolean debug =
Boolean.getBoolean("SymbolResolutionClosure.debug");
private ExpressionEvaluator ee;
public SymbolResolutionClosure(ExpressionEvaluator ee) {
this.ee = ee;
}
public void visit(Object o, boolean hasNext) throws MonitorException {
if (! (o instanceof ColumnFormat)) {
return;
}
ColumnFormat c = (ColumnFormat)o;
Expression e = c.getExpression();
String previous = e.toString();
e = (Expression)ee.evaluate(e);
if (debug) {
System.out.print("Expression: " + previous + " resolved to "
+ e.toString());
}
c.setExpression(e);
}
}

View file

@ -0,0 +1,85 @@
/*
* 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.tools.jstat;
import java.io.StreamTokenizer;
import java.util.Set;
import java.util.Iterator;
/**
* An exception class for syntax exceptions detected by the options file
* parser.
*
* @author Brian Doherty
* @since 1.5
*/
@SuppressWarnings("serial") // JDK implementation class
public class SyntaxException extends ParserException {
private String message;
public SyntaxException(String message) {
this.message = message;
}
public SyntaxException(int lineno, String expected, String found) {
message = "Syntax error at line " + lineno
+ ": Expected " + expected
+ ", Found " + found;
}
public SyntaxException(int lineno, String expected, Token found) {
message = "Syntax error at line " + lineno
+ ": Expected " + expected
+ ", Found " + found.toMessage();
}
public SyntaxException(int lineno, Token expected, Token found) {
message = "Syntax error at line " + lineno
+ ": Expected " + expected.toMessage()
+ ", Found " + found.toMessage();
}
public SyntaxException(int lineno, Set<String> expected, Token found) {
StringBuilder msg = new StringBuilder();
msg.append("Syntax error at line ").append(lineno)
.append(": Expected one of \'");
for (String keyWord : expected) {
msg.append(keyWord).append('|');
}
if (!expected.isEmpty()) {
msg.setLength(msg.length() - 1);
}
message = msg.append("\', Found ").append(found.toMessage()).toString();
}
public String getMessage() {
return message;
}
}

View file

@ -0,0 +1,111 @@
/*
* 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.jstat;
import java.io.StreamTokenizer;
/**
* A class for encapsulating tokens returned from StreamTokenizer primarily
* for output formatting purposes.
*
* @author Brian Doherty
* @since 1.5
*/
public class Token {
public String sval;
public double nval;
public int ttype;
public Token(int ttype, String sval, double nval) {
this.ttype = ttype;
this.sval = sval;
this.nval = nval;
}
public Token(int ttype, String sval) {
this(ttype, sval, 0);
}
public Token(int ttype) {
this(ttype, null, 0);
}
public String toMessage() {
switch(ttype) {
case StreamTokenizer.TT_EOL:
return "\"EOL\"";
case StreamTokenizer.TT_EOF:
return "\"EOF\"";
case StreamTokenizer.TT_NUMBER:
return "NUMBER";
case StreamTokenizer.TT_WORD:
if (sval == null) {
return "IDENTIFIER";
} else {
return "IDENTIFIER " + sval;
}
default:
if (ttype == (int)'"') {
String msg = "QUOTED STRING";
if (sval != null)
msg = msg + " \"" + sval + "\"";
return msg;
} else {
return "CHARACTER \'" + (char)ttype + "\'";
}
}
}
public String toString() {
StringBuilder sb = new StringBuilder();
switch(ttype) {
case StreamTokenizer.TT_EOL:
sb.append("ttype=TT_EOL");
break;
case StreamTokenizer.TT_EOF:
sb.append("ttype=TT_EOF");
break;
case StreamTokenizer.TT_NUMBER:
sb.append("ttype=TT_NUM,").append("nval="+nval);
break;
case StreamTokenizer.TT_WORD:
if (sval == null) {
sb.append("ttype=TT_WORD:IDENTIFIER");
} else {
sb.append("ttype=TT_WORD:").append("sval="+sval);
}
break;
default:
if (ttype == (int)'"') {
sb.append("ttype=TT_STRING:").append("sval="+sval);
} else {
sb.append("ttype=TT_CHAR:").append((char)ttype);
}
break;
}
return sb.toString();
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,228 @@
/*
* Copyright (c) 2010, 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.
*/
option classload {
column {
header "^Loaded^" /* Number of classes loaded */
data (java.cls.loadedClasses + java.cls.sharedLoadedClasses)
align right
scale raw
width 5
format "0"
}
column {
header "Time^" /* Accumulated time for class loading */
data sun.cls.time/sun.os.hrt.frequency
scale sec
align right
width 10
format "0.000"
}
column {
header "^Inited^" /* Number of initialized classes */
data sun.cls.initializedClasses
align right
scale raw
width 5
format "0"
}
column {
header "Time^" /* Accumulated time for class initialization */
data sun.cls.classInitTime.self/sun.os.hrt.frequency
scale raw
align right
width 10
format "0.000"
}
column {
header "Shared^" /* Number of system classes loaded from shared archive */
data java.cls.sharedLoadedClasses
align right
scale raw
width 5
format "0"
}
column {
header "Kbytes^" /* Accumulated Size of classes loaded */
data sun.cls.sharedLoadedBytes
align right
scale K
width 7
format "0.0"
}
column {
header "LoadTime^" /* Accumulated time for loading classes from shared archive */
data sun.cls.sharedClassLoadTime/sun.os.hrt.frequency
scale raw
align right
width 10
format "0.000"
}
column {
header "^SysClass^" /* Number of system classes loaded */
data java.cls.loadedClasses
align right
scale raw
width 5
format "0"
}
column {
header "Kbytes^" /* Bytes read from system class files */
data sun.cls.sysClassBytes
align right
scale K
width 7
format "0.0"
}
column {
header "LoadTime^" /* Accumulated time for loading non-shared system classes */
data sun.cls.sysClassLoadTime/sun.os.hrt.frequency
scale raw
align right
width 10
format "0.000"
}
column {
header "Lookup^" /* Time spent in looking up/reading of system classes */
data sun.cls.lookupSysClassTime/sun.os.hrt.frequency
scale raw
align right
width 10
format "0.000"
}
column {
header "Parse^" /* Time spent in parsing system classes */
data sun.cls.parseClassTime.self/sun.os.hrt.frequency
scale raw
align right
width 10
format "0.000"
}
column {
header "^Linked^" /* Number of linked classes */
data sun.cls.linkedClasses
align right
scale raw
width 5
format "0"
}
column {
header "Time^" /* Accumulated time for class linking */
data sun.cls.classInitTime.self/sun.os.hrt.frequency
scale raw
align right
width 10
format "0.000"
}
column {
header "^Verified^" /* Number of verified classes */
data sun.cls.verifiedClasses
align right
scale raw
width 5
format "0"
}
column {
header "Time^" /* Accumulated time for class verification */
data sun.cls.classVerifyTime.self/sun.os.hrt.frequency
scale raw
align right
width 10
format "0.000"
}
column {
header "AppClass^" /* Number of loaded application classes */
data sun.cls.appClassLoadCount
align right
scale raw
width 5
format "0"
}
column {
header "Kbytes^" /* Bytes read from app class files */
data sun.cls.appClassBytes
align right
scale K
width 7
format "0.0"
}
column {
header "AppCL^" /* Accumulated time for loading app classes */
data sun.cls.appClassLoadTime/sun.os.hrt.frequency
scale raw
align right
width 10
format "0.000"
}
column {
header "^DefineClass^" /* Number of defineClass calls */
data sun.cls.defineAppClasses
align right
scale raw
width 5
format "0"
}
column {
header "Time^" /* Accumulated time for defineClass */
data sun.cls.defineAppClassTime.self/sun.os.hrt.frequency
scale raw
align right
width 10
format "0.000"
}
column {
header "^FindClass^" /* Number of findClass calls */
data sun.classloader.findClasses
align right
scale raw
width 5
format "0"
}
column {
header "Time^" /* Accumulated time for findClass */
data sun.classloader.findClassTime/1000000000
scale raw
align right
width 10
format "0.000"
}
column {
header "Delegation^" /* Parent class loader delegation time */
data sun.classloader.parentDelegationTime/1000000000
scale raw
align right
width 10
format "0.000"
}
column {
header "URLCL Read^" /* Accumulated time for URLClassLoader reading bytes */
data sun.urlClassLoader.readClassBytesTime/1000000000
scale raw
align right
width 10
format "0.000"
}
}