mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8187443: Forest Consolidation: Move files to unified layout
Reviewed-by: darcy, ihse
This commit is contained in:
parent
270fe13182
commit
3789983e89
56923 changed files with 3 additions and 15727 deletions
48
src/jdk.jcmd/share/classes/module-info.java
Normal file
48
src/jdk.jcmd/share/classes/module-info.java
Normal 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;
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
121
src/jdk.jcmd/share/classes/sun/tools/jcmd/Arguments.java
Normal file
121
src/jdk.jcmd/share/classes/sun/tools/jcmd/Arguments.java
Normal 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 ");
|
||||
}
|
||||
}
|
181
src/jdk.jcmd/share/classes/sun/tools/jcmd/JCmd.java
Normal file
181
src/jdk.jcmd/share/classes/sun/tools/jcmd/JCmd.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
261
src/jdk.jcmd/share/classes/sun/tools/jinfo/JInfo.java
Normal file
261
src/jdk.jcmd/share/classes/sun/tools/jinfo/JInfo.java
Normal 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);
|
||||
}
|
||||
}
|
260
src/jdk.jcmd/share/classes/sun/tools/jmap/JMap.java
Normal file
260
src/jdk.jcmd/share/classes/sun/tools/jmap/JMap.java
Normal 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);
|
||||
}
|
||||
}
|
166
src/jdk.jcmd/share/classes/sun/tools/jps/Arguments.java
Normal file
166
src/jdk.jcmd/share/classes/sun/tools/jps/Arguments.java
Normal 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;
|
||||
}
|
||||
}
|
175
src/jdk.jcmd/share/classes/sun/tools/jps/Jps.java
Normal file
175
src/jdk.jcmd/share/classes/sun/tools/jps/Jps.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
177
src/jdk.jcmd/share/classes/sun/tools/jstack/JStack.java
Normal file
177
src/jdk.jcmd/share/classes/sun/tools/jstack/JStack.java
Normal 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);
|
||||
}
|
||||
}
|
125
src/jdk.jcmd/share/classes/sun/tools/jstat/Alignment.java
Normal file
125
src/jdk.jcmd/share/classes/sun/tools/jstat/Alignment.java
Normal 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);
|
||||
}
|
||||
}
|
446
src/jdk.jcmd/share/classes/sun/tools/jstat/Arguments.java
Normal file
446
src/jdk.jcmd/share/classes/sun/tools/jstat/Arguments.java
Normal 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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
39
src/jdk.jcmd/share/classes/sun/tools/jstat/Closure.java
Normal file
39
src/jdk.jcmd/share/classes/sun/tools/jstat/Closure.java
Normal 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;
|
||||
}
|
157
src/jdk.jcmd/share/classes/sun/tools/jstat/ColumnFormat.java
Normal file
157
src/jdk.jcmd/share/classes/sun/tools/jstat/ColumnFormat.java
Normal 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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
98
src/jdk.jcmd/share/classes/sun/tools/jstat/Expression.java
Normal file
98
src/jdk.jcmd/share/classes/sun/tools/jstat/Expression.java
Normal 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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
64
src/jdk.jcmd/share/classes/sun/tools/jstat/Identifier.java
Normal file
64
src/jdk.jcmd/share/classes/sun/tools/jstat/Identifier.java
Normal 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;
|
||||
}
|
||||
}
|
159
src/jdk.jcmd/share/classes/sun/tools/jstat/JStatLogger.java
Normal file
159
src/jdk.jcmd/share/classes/sun/tools/jstat/JStatLogger.java
Normal 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) { };
|
||||
}
|
||||
}
|
||||
}
|
190
src/jdk.jcmd/share/classes/sun/tools/jstat/Jstat.java
Normal file
190
src/jdk.jcmd/share/classes/sun/tools/jstat/Jstat.java
Normal 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);
|
||||
}
|
||||
}
|
55
src/jdk.jcmd/share/classes/sun/tools/jstat/Literal.java
Normal file
55
src/jdk.jcmd/share/classes/sun/tools/jstat/Literal.java
Normal 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();
|
||||
}
|
||||
}
|
111
src/jdk.jcmd/share/classes/sun/tools/jstat/Operator.java
Normal file
111
src/jdk.jcmd/share/classes/sun/tools/jstat/Operator.java
Normal 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();
|
||||
}
|
||||
}
|
85
src/jdk.jcmd/share/classes/sun/tools/jstat/OptionFinder.java
Normal file
85
src/jdk.jcmd/share/classes/sun/tools/jstat/OptionFinder.java
Normal 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;
|
||||
}
|
||||
}
|
110
src/jdk.jcmd/share/classes/sun/tools/jstat/OptionFormat.java
Normal file
110
src/jdk.jcmd/share/classes/sun/tools/jstat/OptionFormat.java
Normal 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 + "}");
|
||||
}
|
||||
}
|
83
src/jdk.jcmd/share/classes/sun/tools/jstat/OptionLister.java
Normal file
83
src/jdk.jcmd/share/classes/sun/tools/jstat/OptionLister.java
Normal 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());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
585
src/jdk.jcmd/share/classes/sun/tools/jstat/Parser.java
Normal file
585
src/jdk.jcmd/share/classes/sun/tools/jstat/Parser.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
82
src/jdk.jcmd/share/classes/sun/tools/jstat/RowClosure.java
Normal file
82
src/jdk.jcmd/share/classes/sun/tools/jstat/RowClosure.java
Normal 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();
|
||||
}
|
||||
}
|
185
src/jdk.jcmd/share/classes/sun/tools/jstat/Scale.java
Normal file
185
src/jdk.jcmd/share/classes/sun/tools/jstat/Scale.java
Normal 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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
111
src/jdk.jcmd/share/classes/sun/tools/jstat/Token.java
Normal file
111
src/jdk.jcmd/share/classes/sun/tools/jstat/Token.java
Normal 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();
|
||||
}
|
||||
}
|
1045
src/jdk.jcmd/share/classes/sun/tools/jstat/resources/jstat_options
Normal file
1045
src/jdk.jcmd/share/classes/sun/tools/jstat/resources/jstat_options
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue