package jmxclcl; import java.util.*; import java.io.*; import java.lang.management.*; import javax.management.ObjectName; import javax.management.MBeanInfo; import javax.management.MalformedObjectNameException; import javax.management.ReflectionException; import javax.management.MBeanServerConnection; import javax.management.InstanceNotFoundException; import javax.management.MBeanAttributeInfo; import javax.management.MBeanOperationInfo; import javax.management.MBeanParameterInfo; import javax.management.Attribute; import javax.management.AttributeNotFoundException; import java.text.*; import common.RMISSLClientSocketFactory; import common.RMISSLServerSocketFactory; /** * Command-line JMX Console. This class interacts with MBeanServer * using JMX protocol. */ public class CLJconsole { final static long SECOND = 1000; final static long MINUTE = 60 * SECOND; final static long HOUR = 60 * MINUTE; final static long DAY = 24 * HOUR; final static DateFormat timeDF = new SimpleDateFormat("HH:mm"); final static long MEM_POOL_MAX_SZ_KB = 4*1024*1024; // some pools are up to 4 GB. private final static DateFormat timeWithSecondsDF = new SimpleDateFormat("HH:mm:ss"); private final static DateFormat dateDF = new SimpleDateFormat("yyyy-MM-dd"); static String passKwd = ""; static String failKwd = ""; static boolean verbose = false; static Stack beanInfoList = new Stack(); static Stack beanGettersList = new Stack(); static Stack beanSettersList = new Stack(); static Stack beanOperationsList = new Stack(); static String needSSL; static String formatTime(long t) { String str; if (t < 1 * MINUTE) { String seconds = String.format("%.3f", t / (double)SECOND); str = Resources.getText("DurationSeconds", seconds); } else { long remaining = t; long days = remaining / DAY; remaining %= 1 * DAY; long hours = remaining / HOUR; remaining %= 1 * HOUR; long minutes = remaining / MINUTE; if (t >= 1 * DAY) { str = Resources.getText("DurationDaysHoursMinutes", days, hours, minutes); } else if (t >= 1 * HOUR) { str = Resources.getText("DurationHoursMinutes", hours, minutes); } else { str = Resources.getText("DurationMinutes", minutes); } } return str; } static String formatNanoTime(long t) { long ms = t / 1000000; return formatTime(ms); } static String formatClockTime(long time) { return timeDF.format(time); } static String formatDate(long time) { return dateDF.format(time); } static String formatDateTime(long time) { return dateDF.format(time) + " " + timeWithSecondsDF.format(time); } static String validateStr (String str, boolean res) { return str + (res ? " " + passKwd : " " + failKwd); } static String validateLong (String value, long from, long to) { long valueLong; try { valueLong = Long.parseLong(value); } catch (Exception e) { return validateStr(value, false); } return validateLong(valueLong, from, to); } static String validateShort (String value, short from, short to) { Short valueShort; try { valueShort = Short.parseShort(value); } catch (Exception e) { return validateStr(value, false); } return validateStr(value, valueShort >= from && valueShort <= to); } static String validateInt (String value, int from, int to) { int valueInt; try { valueInt = Integer.parseInt(value); } catch (Exception e) { return validateStr(value, false); } return validateStr(value, valueInt >= from && valueInt <= to); } static String validateLong (long value, long from, long to) { String str = String.format("%,d",value); return validateStr(str, value >= from && value <= to); } static String formatKB (long bytes, long from, long to) { if (bytes == -1) { return "-1" + Resources.getText(" kbytes"); } long kb = bytes / 1024; return validateStr(String.format("%,d",kb) + Resources.getText(" kbytes"), kb >= from && kb <= to); } static boolean USE_getAllThreadIds = false; static int indent = 0; static String[] indents_space = {"", " ", " ", " ", " ", " ", " "}; static String[] indents = {"", ". ", ". . ", ". . . ", ". . . . ", ". . . . . ", ". . . . . "}; static String FIELD_BEG = ""; // "["; static String FIELD_END = ""; // "]"; static String FIELD_GET = ""; // "Get "; static String FIELD_SET = ""; // "Set "; static String indent () { int ind = indent; if (ind < 0) ind = 0; return indents[ind % (indents.length - 1)]; } static void out (String msg) { System.out.print(msg); System.out.flush(); } static void outln (String msg) { System.out.println(msg); System.out.flush(); } static boolean DEBUG = false; public boolean isDebug () { return DEBUG; } static void addRow (String label) { String msg = indent() + label + "\n"; out(msg); } static void out (Throwable throwable) { if (DEBUG) throwable.printStackTrace(System.out); else addRow("[stacktrace: use -debug on command line]"); } static void addRow (String label, String value) { String msg = indent() + FIELD_BEG + label + FIELD_END + " : " + FIELD_BEG + value + FIELD_END + "\n"; out(msg); } static void addRow (String label1, String value1, String label2, String value2) { String msg = indent() + FIELD_BEG + label1 + FIELD_END + " : " + FIELD_BEG + value1 + FIELD_END + " " + FIELD_BEG + label2 + FIELD_END + " : " + FIELD_BEG + value2 + FIELD_END + "\n"; out(msg); } static void addRow (String label1, String value1, String label2, String value2, String label3, String value3) { String msg = indent() + FIELD_BEG + label1 + FIELD_END + " : " + FIELD_BEG + value1 + FIELD_END + " " + FIELD_BEG + label2 + FIELD_END + " : " + FIELD_BEG + value2 + FIELD_END + " " + FIELD_BEG + label3 + FIELD_END + " : " + FIELD_BEG + value3 + FIELD_END + "\n"; out(msg); } static void addRow (String label1, String value1, String label2, String value2, String label3, String value3, String label4, String value4) { String msg = indent() + FIELD_BEG + label1 + FIELD_END + " : " + FIELD_BEG + value1 + FIELD_END + " " + FIELD_BEG + label2 + FIELD_END + " : " + FIELD_BEG + value2 + FIELD_END + " " + FIELD_BEG + label3 + FIELD_END + " : " + FIELD_BEG + value3 + FIELD_END + " " + FIELD_BEG + label4 + FIELD_END + " : " + FIELD_BEG + value4 + FIELD_END + "\n"; out(msg); } static String[] argv; static String host = null; static int port = 9999; static int loopCount = 1; static int loopInterval = 0; static int handshakeTimeout = 10000; static String delayCondObjName; static String delayCondAttrName; static String delayCondOpName; static String delayCondValue; static boolean reportForKnownBeans = true; static boolean measureAverageRoundtripTime = true; /** * * */ public static void main (String args[]) { argv = args; parseOptionsFlags(); if (needSSL != null) { boolean needOrapki = needSSL.toLowerCase().indexOf("orapki") > -1; if (needOrapki) { // install and init Oracle PKI Provider before any of the factories is initilalized oracle.security.pki.OraclePKIProvider opkip = new oracle.security.pki.OraclePKIProvider(); if (DEBUG) outln(" Oracle PKI: " + opkip); java.security.Security.insertProviderAt(opkip, 3); if(DEBUG) { java.security.Provider[] pa = java.security.Security.getProviders(); for (int p = 0; p < pa.length; p++) outln("at " + p + " provider " + pa[p]); } } //TestParamsRMISSLClient.main(new String[]{"ssl_prog", "2000", "1"}); boolean isDefaultKM = needSSL.toLowerCase().indexOf("default") > -1; try { RMISSLClientSocketFactory csf = new RMISSLClientSocketFactory(isDefaultKM); csf.initFactory(); } catch (Exception e) { addRow(failKwd + " Got exception " + e); out(e); } } while (loopCount-- > 0) { try { if (verbose) outln(" *** about to obtain stats *** "); monitor(argv[0], port); if (verbose) outln(" *** stats obtained, " + loopCount + " times remaim ***"); if (loopCount > 0) // do not wait before exiting Thread.sleep(loopInterval); } catch (Exception e) {} } } static void parseOptionsFlags () { if (argv.length < 1) { usage(failKwd + " Command line has too few arguments"); System.exit(1); } for (int i = 0; i < argv.length; i++) { if (argv[i].startsWith("-")) { if (argv[i].equals("-port") || argv[i].equals("-p")) { try { port = Integer.parseInt(argv[++i]); } catch (Exception e) { usage(failKwd + " error: port flag value is not an integer"); System.exit(1); } } else if (argv[i].equals("-repeatTimes") || argv[i].equals("-r")) { try { loopCount = Integer.parseInt(argv[++i]); } catch (Exception e) { usage(failKwd + " error: repetition count flag value is not an integer"); System.exit(1); } } else if (argv[i].equals("-interval") || argv[i].equals("-i")) { try { loopInterval = Integer.parseInt(argv[++i]); } catch (Exception e) { usage(failKwd + " error: repetition interval flag value is not an integer"); System.exit(1); } } else if (argv[i].equals("-handshakeTimeout") || argv[i].equals("-ht")) { try { handshakeTimeout = 1000 * Integer.parseInt(argv[++i]); } catch (Exception e) { usage(failKwd + " error: connection wait flag value is not an integer"); System.exit(1); } } else if (argv[i].equals("-delayCond") || argv[i].equals("-dc")) { try { delayCondObjName = argv[++i]; delayCondAttrName = argv[++i]; delayCondOpName = argv[++i]; delayCondValue = argv[++i]; } catch (Exception e) { usage(failKwd + " error: delayCond arguments incorrect"); System.exit(1); } } else if (argv[i].equals("-successKeyword") || argv[i].equals("-s")) { passKwd = argv[++i]; } else if (argv[i].equals("-debug") || argv[i].equals("-d")) { DEBUG = true; RMISSLServerSocketFactory.TRACE = true; RMISSLClientSocketFactory.TRACE = true; } else if (argv[i].equals("-failKeyword") || argv[i].equals("-f")) { failKwd = argv[++i]; } else if (argv[i].equals("-begMarker") || argv[i].equals("-b")) { FIELD_BEG = argv[++i]; } else if (argv[i].equals("-endMarker") || argv[i].equals("-e")) { FIELD_END = argv[++i]; } else if (argv[i].equals("-getMarker")) { FIELD_GET = argv[++i]; } else if (argv[i].equals("-setMarker")) { FIELD_SET = argv[++i]; } else if (argv[i].equals("-ssl")) { needSSL = argv[++i]; } else if (argv[i].equals("-verbose") || argv[i].equals("-v")) { verbose = true; } else if (argv[i].equals("-beanInfo")) { beanInfoList.push(argv[++i]); } else if (argv[i].equals("-getAttribute")) { beanGettersList.push(argv[++i]); // bean beanGettersList.push(argv[++i]); // attribute } else if (argv[i].equals("-setAttribute")) { beanSettersList.push(argv[++i]); // bean beanSettersList.push(argv[++i]); // attribute beanSettersList.push(argv[++i]); // value } else if (argv[i].equals("-invoke")) { beanOperationsList.push(argv[++i]); // bean String op = argv[++i]; if (op.indexOf("(") > -1 && op.indexOf(")") > -1) { beanOperationsList.push(op.substring(0, op.indexOf("("))); // operation String sign = op.substring(op.indexOf("(")+1, op.indexOf(")")).toLowerCase(); int arity = sign.length(); String[] types = new String[arity]; Object[] args = new Object[arity]; for (int si = 0; si < arity; si++) { switch (sign.charAt(si)) { case 'i': types[si] = "int"; args[si] = Integer.parseInt(argv[++i]); break; case 'l': types[si] = "long"; args[si] = Long.parseLong(argv[++i]); break; case 's': types[si] = "short"; args[si] = Short.parseShort(argv[++i]); break; case 'f': types[si] = "float"; args[si] = Float.parseFloat(argv[++i]); break; case 'd': types[si] = "double"; args[si] = Double.parseDouble(argv[++i]); break; case 'b': types[si] = "boolean"; args[si] = Boolean.parseBoolean(argv[++i]); break; case 't': default: types[si] = "java.lang.String"; args[si] = argv[++i]; break; } } beanOperationsList.push(types); beanOperationsList.push(args); } else { beanOperationsList.push(op); beanOperationsList.push(new String[]{}); beanOperationsList.push(new Object[]{}); } } else if (argv[i].equals("-noReport")) { reportForKnownBeans = false; } else if (argv[i].equals("-noRoundtrip")) { measureAverageRoundtripTime = false; } else { host = argv[i]; } } } if (port <= 0) { usage(failKwd + " error: port must be positive integer"); System.exit(1); } if (loopCount < 0) { usage(failKwd + " error: repetition count must be non-negative integer"); System.exit(1); } if (loopInterval < 0) { usage(failKwd + " error: repetition interval must be non-negative integer"); System.exit(1); } } static void usageFlags (String err) { if (err != null) outln(err); outln("Usage: "); outln(" [options...] host [options...] "); outln(" where"); outln(" host is machine name or IP"); outln(" options are as follows:"); outln(" -port number"); outln(" -p number"); outln(" port number. Default is 9999"); outln(" -repeatTimes number"); outln(" -r number"); outln(" number of repetitions the client communicates"); outln(" with the server. Default is 1."); outln(" -interval number"); outln(" -i number"); outln(" delay between repetitions, ms. Default is 0."); outln(" -beanInfo "); outln(" show info of bean , thsi includes list of "); outln(" attributes and operations with detailed property values of each"); outln(" -getAttribute attr"); outln(" show attribute attr of bean "); outln(" Note: is either an identifier or a well-formed JMX name"); outln(" such as \"java.lang:type=MemoryPool,name=Old Generation\"."); outln(" when is an identifier N, it is converted to java.lang:type=N "); outln(" -setAttribute attr val"); outln(" set attribute attr of bean to value val"); outln(" -invoke "); outln(" invoke operation of bean "); outln(" is an identifier or an identifier followed by argument type"); outln(" descriptors followed by argument values."); outln(" -successKeyword string"); outln(" -s string"); outln(" marker signalling success of an mBean operation. Default is empty."); outln(" -failKeyword string"); outln(" -f string"); outln(" marker signalling failure of an mBean operation. Default is empty."); outln(" -begMarker string"); outln(" -b string"); outln(" marker starting attribute-value pair. Default is empty."); outln(" -endMarker string"); outln(" -e string"); outln(" marker ending attribute-value pair. Default is empty."); outln(" -getMarker string"); outln(" marker for bean get operation. Default is empty."); outln(" -setMarker string"); outln(" marker for bean attribute set operation. Default is empty."); outln(" -handshakeTimeout howLong"); outln(" -ht howLong"); outln(" at handshake, retrying connecting for howLong secs every 500ms"); outln(" default is -ht 10"); outln(" -delayCond beanName attribute operation value"); outln(" -dc beanName attribute operation value"); outln(" after connecting, delay monitoring until a test condition is met"); outln(" -handshakeTimeout integer"); outln(" -ht howLong"); outln(" at handshake, retrying connecting for howLong secs every 500ms"); outln(" -handshakeTimeout integer"); outln(" -ht howLong"); outln(" at handshake, retrying connecting for howLong secs every 500ms"); outln(" -noReport"); outln(" supress report of properties of all known system beans"); outln(" -noRoundtrip"); outln(" do not measure and report client-server roundtrip statistics"); outln("Examples:"); outln(" java jmxclcl.CLJconsole foo.bar.com"); outln(" java jmxclcl.CLJconsole foo.bar.com -p 7777 "); outln(" java jmxclcl.CLJconsole foo.bar.com -p 7777 -r 10 -i 30000 "); outln(" java jmxclcl.CLJconsole foo.bar.com -r 10 -i 30000 -s PASS -f FAIL "); outln(" java jmxclcl.CLJconsole foo.bar.com -beanInfo Runtime"); outln(" java jmxclcl.CLJconsole foo.bar.com -beanInfo \'java.lang:type=MemoryPool,name=Old Generation\'"); outln(" java jmxclcl.CLJconsole foo.bar.com -getAttribute Memory Verbose"); outln(" java jmxclcl.CLJconsole foo.bar.com -setAttribute Memory Verbose true"); outln(" java jmxclcl.CLJconsole foo.bar.com -invoke Memory gc"); outln(" java jmxclcl.CLJconsole foo.bar.com -invoke Threading 'getThreadInfo(l)' 4 "); } static void usage (String err) { usageFlags(err); } static void usage () { usage(null); } static ObjectName toObjectName (String beanName) { if (beanName.indexOf(":") < 0) { // assume simple name was given beanName = "java.lang:type=" + beanName; } ObjectName name = null; try { name = new ObjectName(beanName); addRow(FIELD_GET + " Bean name", beanName + " " + passKwd); } catch (MalformedObjectNameException e) { addRow(FIELD_GET + " Bean name", beanName + " " + failKwd); } return name; } static void showAttributeInfo (MBeanAttributeInfo attr) { String name = attr.getName(); addRow(name); indent++; addRow("type", attr.getType()); addRow("descr", attr.getDescription()); addRow("readable", ""+attr.isReadable()); addRow("writeable", ""+attr.isWritable()); addRow("isIs", ""+attr.isIs()); indent--; } static void showOperationInfo (MBeanOperationInfo op) { String name = op.getName(); addRow(name); indent++; { MBeanParameterInfo[] sigarr = op.getSignature(); String sig = ""; if (sigarr != null) { for (int i = 0; i < sigarr.length; i++) { if (i != 0) sig += ","; sig += sigarr[i].getType(); } addRow("signature", "(" + sig + ")"); } } addRow("type", op.getReturnType()); addRow("descr", op.getDescription()); addRow("impact", ""+op.getImpact()); indent--; } static Object coerceAttributeLiteralTo (String literal, Object currentVal) { if (currentVal == null) return literal; Class cl = currentVal.getClass(); try { if (cl == Long.class) return Long.parseLong(literal); if (cl == Integer.class) return Integer.parseInt(literal); if (cl == Boolean.class) return Boolean.parseBoolean(literal); if (cl == Byte.class) return Byte.parseByte(literal); if (cl == Short.class) return Short.parseShort(literal); if (cl == Float.class) return Float.parseFloat(literal); if (cl == Double.class) return Double.parseDouble(literal); } catch (Exception e) {} return literal; } static void monitor (String host, int port) { indent = 0; try { addRow("JMX RMI Connection..."); indent++; ProxyClient proxyClient = null; long timeStamp = System.currentTimeMillis(); while (true) { try { proxyClient = ProxyClient.getProxyClient(host, port, "", ""); if (proxyClient.isDead()) { //outln("-- proxyClient isDead "); addRow(FIELD_GET + "Connection Proxy", "" + proxyClient + " is dead. " + failKwd); return; } addRow(FIELD_GET + "Connection Proxy", proxyClient.toString() + " " + passKwd); if (delayCondObjName != null && delayCondAttrName != null && delayCondOpName != null && delayCondValue != null) { addRow("Check startup condition " + delayCondObjName + " " + delayCondAttrName + " " + delayCondOpName + " " + delayCondValue + " :"); while (true) { ObjectName name = toObjectName(delayCondObjName); Object val = null; Object[] params = {}; String[] paramSign = {}; try { MBeanServerConnection server = proxyClient.getMBeanServerConnection(); val = server.getAttribute(name, delayCondAttrName); if (delayCondOpName.equals("eq")) { if (delayCondValue.equals(""+val)) break; // while(true); else continue; // while(true); } else if (delayCondOpName.equals("ne")) { if (delayCondValue.equals(""+val)) continue; // while(true); else break; // while(true); } } catch (Throwable e) { if (System.currentTimeMillis() < timeStamp + handshakeTimeout) { System.out.println(" Condition is false (" + delayCondObjName + " " + delayCondAttrName + " = " + val + " ). Wait..." ); Thread.sleep(500); continue; // while(true) } else { addRow(FIELD_GET + "Startup condition ", delayCondObjName + " " + delayCondAttrName + " " + delayCondOpName + " " + delayCondValue + " " + failKwd); return; } } } } } catch (Throwable thr) { if (System.currentTimeMillis() < timeStamp + handshakeTimeout) { System.out.println("Wait for connection..."); Thread.sleep(500); continue; // while(true) } else { addRow(FIELD_GET + "Connection Proxy", "" + proxyClient + " " + failKwd); out(thr); return; } } break; // while(true) } indent--; if (reportForKnownBeans) { addRow("Beans"); indent++; RuntimeMXBean rmBean = null; try { rmBean = proxyClient.getRuntimeMXBean(); addRow(FIELD_GET + "RuntimeMXBean", "" + rmBean.getClass() + " " + passKwd); { indent++; String name = rmBean.getName(); addRow("Name", validateStr(name, name != null && name.length() > 3 && name.indexOf("@") > -1 && name.indexOf("PID=") > -1 && name.indexOf("SID=") > -1)); // name includes PID, and SID see sun.management.VMManagementImpl.getVmId String PID = name.substring(name.indexOf("PID=")+4, name.indexOf(";")); String SID = name.substring(name.indexOf("SID=")+4, name.indexOf(")")); // todo maybe check PID, SID are positive integers addRow("PID", validateInt(PID, 1, 0xffff)); addRow("SID", validateInt(SID, 1, 0xffff)); List arglist = rmBean.getInputArguments(); if (arglist != null && arglist.size() > 0) addRow("MODE", arglist.get(0)); indent--; } } catch (Throwable thr) { addRow(FIELD_GET + "RuntimeMXBean", "" + rmBean.getClass() + " " + failKwd); out(thr); } OperatingSystemMXBean osMBean = null; try { osMBean = proxyClient.getOperatingSystemMXBean(); addRow(FIELD_GET + "OperatingSystemMXBean", "" + osMBean.getClass() + " " + passKwd); } catch (Throwable thr) { addRow(FIELD_GET + "OperatingSystemMXBean", "" + osMBean.getClass() + " " + failKwd); out(thr); } // This code is currently disabled [bug 10145316] // because not all client java envs provide com.sun.management.* // // com.sun.management.OperatingSystemMXBean sunOSMBean = null; // OperatingSystemMXBean platfOSMBean = null; // // try { // platfOSMBean = proxyClient.getSunOperatingSystemMXBean(); // addRow(FIELD_GET + "com.sun.management.OperatingSystemMXBean", // "" + platfOSMBean.getClass() + " " + passKwd); // } catch (Throwable thr) { // addRow(FIELD_GET + "com.sun.management.OperatingSystemMXBean", // "" + platfOSMBean.getClass() + " " + failKwd); // out(thr); // } // // long uptime = rmBean.getUptime(); // // { indent++; // if (platfOSMBean != null) { // long uptimeNano = platfOSMBean.getProcessCpuTime(); // if (uptimeNano == 0) // addRow("Uptime, ms", // validateLong(rmBean.getUptime(), 100, 3600000), // "Process CPU time", // validateLong(uptimeNano, 0, 0)); // else // addRow("Uptime, ms", // validateLong(rmBean.getUptime(), 100, 3600000), // "Process CPU time", // validateLong(uptimeNano, uptime * 1000000, (10+ uptime) * 1000000)); // } else { // addRow("Uptime", validateLong(uptime, 100, HOUR*MINUTE*SECOND)); // } // // if (platfOSMBean != null) { // addRow(Resources.getText("Total physical memory"), // formatKB(platfOSMBean.getTotalPhysicalMemorySize(), 0, 0), // Resources.getText("Free physical memory"), // formatKB(platfOSMBean.getFreePhysicalMemorySize(), 0, 0)); // addRow(Resources.getText("Committed virtual memory"), // formatKB(platfOSMBean.getCommittedVirtualMemorySize(), 0, 0)); // } // indent--; // } CompilationMXBean cmpMBean = null; try { cmpMBean = proxyClient.getCompilationMXBean(); addRow(FIELD_GET + "CompilationMXBean", "" + cmpMBean.getClass() + " " + passKwd); } catch (Throwable thr) { addRow(FIELD_GET + "CompilationMXBean", "" + cmpMBean.getClass() + " " + failKwd); out(thr); } if (cmpMBean.isCompilationTimeMonitoringSupported()) { addRow("Total compile time", validateLong(cmpMBean.getTotalCompilationTime(), 0, HOUR*MINUTE*SECOND)); } // threads // addRow("Threads"); { // indent++; ThreadMXBean tmBean = null; try { tmBean = proxyClient.getThreadMXBean(); addRow(FIELD_GET + "ThreadMXBean", "" + tmBean.getClass() + " " + passKwd); } catch (Throwable thr) { if (DEBUG) out(thr); addRow(FIELD_GET + "ThreadMXBean", "" + tmBean.getClass() + " " + failKwd); } { indent++; int tlCount = tmBean.getThreadCount(); int tdCount = tmBean.getDaemonThreadCount(); int tpCount = tmBean.getPeakThreadCount(); long ttCount = tmBean.getTotalStartedThreadCount(); addRow(Resources.getText("Live Threads"), validateLong(tlCount, 5, 1000), Resources.getText("Peak"), validateLong(tpCount, 5, 1000)); addRow(Resources.getText("Daemon threads"), validateLong(tdCount, 2, 100)); addRow(Resources.getText("Total started"), validateLong(ttCount, 6, 2000)); if (USE_getAllThreadIds) { indent++; ThreadInfo[] ttia = tmBean.getThreadInfo(tmBean.getAllThreadIds()); for (int i = 0; i < ttia.length; i++) { ThreadInfo tti = ttia[i]; String ttiString = tti.toString(); StackTraceElement[] ttiStack = tti.getStackTrace(); addRow("ThreadInfo", validateStr(ttiString, ttiString.length() > 30), "stack size", validateLong(ttiStack.length, 2, 50)); for (StackTraceElement e : tti.getStackTrace()) { addRow(" . . . ", e.toString()); } } indent--; } else { indent++; // addRow("another method"); for (long threadID : tmBean.getAllThreadIds()) { ThreadMXBean threadMBean = proxyClient.getThreadMXBean(); ThreadInfo ti = threadMBean.getThreadInfo(threadID, Integer.MAX_VALUE); if (ti != null) { String ttiString = ti.toString(); StackTraceElement[] ttiStack = ti.getStackTrace(); addRow("ThreadInfo", validateStr(ttiString, ttiString.length() > 30)); { indent++; if (ti.getLockName() == null) { addRow("Name", ti.getThreadName(), "State", ti.getThreadState().toString()); } else if (ti.getLockOwnerName() == null) { addRow("Name", ti.getThreadName(), "State", ti.getThreadState().toString(), "LockName", ti.getLockName()); } else { addRow("Name", ti.getThreadName(), "State", ti.getThreadState().toString(), "LockName", ti.getLockName(), "LockOwner", ti.getLockOwnerName()); } addRow("BlockedCount", ""+ti.getBlockedCount(), "WaitedCount", ""+ti.getWaitedCount()); StackTraceElement[] elts = ti.getStackTrace(); addRow("Stack trace size", validateLong(elts.length, 1, 50)); indent++; int frameIdx = 1; for (StackTraceElement e : elts) { String elt = "" + e; addRow("" + (frameIdx++), validateStr(elt, elt.lastIndexOf(".") > 2 && elt.indexOf("(") > 5)); } indent--; } indent--; } } indent--; } indent--; } // indent--; } MemoryMXBean memoryBean = null; { try { memoryBean = proxyClient.getMemoryMXBean(); addRow(FIELD_GET + "MemoryMXBean", "" + memoryBean.getClass() + " " + passKwd); } catch (Throwable thr) { out(thr); addRow(FIELD_GET + "MemoryMXBean", "" + memoryBean.getClass() + " " + failKwd); } { indent++; MemoryUsage u = memoryBean.getHeapMemoryUsage(); long finalizerQueueLength = memoryBean.getObjectPendingFinalizationCount(); addRow(Resources.getText("Current heap size"), formatKB(u.getUsed(), 32,u.getCommitted())); addRow(Resources.getText("Committed memory"), formatKB(u.getCommitted(), 64, u.getMax())); addRow(Resources.getText("Maximum heap size"), formatKB(u.getMax(), -1, 8*MEM_POOL_MAX_SZ_KB)); addRow(Resources.getText("Objects pending for finalization"), validateLong(finalizerQueueLength, 0, 10000)); boolean verbose_val = memoryBean.isVerbose(); memoryBean.setVerbose(!verbose_val); boolean verbose_val_inverse = memoryBean.isVerbose(); memoryBean.setVerbose(verbose_val); addRow("flip verbose flag", validateStr("", (memoryBean.isVerbose() == verbose_val && verbose_val != verbose_val_inverse))); indent--; } // addRow("Collectors"); Collection garbageCollectors = proxyClient.getGarbageCollectorMXBeans(); long totalGcCount = 0; for (GarbageCollectorMXBean garbageCollectorMBean : garbageCollectors) { String gcName = garbageCollectorMBean.getName(); long gcCount = garbageCollectorMBean.getCollectionCount(); totalGcCount += gcCount; long gcTime = garbageCollectorMBean.getCollectionTime(); addRow("GarbageCollectorMXBean", ""+garbageCollectorMBean.getClass()); addRow(Resources.getText("GcInfo", gcName, gcCount, (gcTime < 0 ? Resources.getText("Unavailable") : formatTime(gcTime)))); } addRow("Perform gc..."); memoryBean.gc(); MemoryUsage u_afterGC = memoryBean.getHeapMemoryUsage(); long totalGcCount_afterGC = 0; for (GarbageCollectorMXBean garbageCollectorMBean : garbageCollectors) { String gcName = garbageCollectorMBean.getName(); long gcCount = garbageCollectorMBean.getCollectionCount(); totalGcCount_afterGC += gcCount; } addRow("Total collection count", // it seems 300 extra collections since the button pressed is enough... // it is typically 15..35 depending on client/server connection speed // and the intensity of GC workload validateLong(totalGcCount_afterGC, totalGcCount, totalGcCount+300)); } addRow("Memory Pools"); Collection poolProxies = proxyClient.getMemoryPoolProxies(); if (poolProxies != null) addRow(FIELD_GET + "Pool Proxy Collection", "" + passKwd); else addRow(FIELD_GET + "Pool Proxy Collection", "" + failKwd); { indent++; addRow("Number of Proxies", validateLong(poolProxies.size(), 6, 10)); for (MemoryPoolProxy poolProxy : poolProxies) { try { MemoryPoolStat stat = poolProxy.getStat(); { indent++; String name = stat.getPoolName(); addRow("Name", validateStr(name, name != null && name.length() > 3)); MemoryUsage u = stat.getUsage(); addRow("Current size", formatKB(u.getUsed(), 0, Math.max(0, u.getMax())), Resources.getText("Committed memory"), formatKB(u.getCommitted(), 0, Math.max(0, u.getMax()))); addRow(Resources.getText("Maximum heap size"), formatKB(u.getMax(), -1, MEM_POOL_MAX_SZ_KB)); indent--; } } catch (Exception e) { addRow("Got Exception while accessing Mem Pool Proxy " + poolProxy); out(e); } } indent--; } // addRow("Classes"); ClassLoadingMXBean clMBean = null; try { clMBean = proxyClient.getClassLoadingMXBean(); addRow(FIELD_GET + "ClassLoadingMXBean", "" + clMBean.getClass() + " " + passKwd); } catch (Throwable thr) { out(thr); addRow(FIELD_GET + "ClassLoadingMXBean", "" + clMBean.getClass() + " " + failKwd); } if (clMBean != null) { indent++; long clCount = clMBean.getLoadedClassCount(); long cuCount = clMBean.getUnloadedClassCount(); long ctCount = clMBean.getTotalLoadedClassCount(); addRow(Resources.getText("Current classes loaded"), validateLong(clCount, 1000, 3000), Resources.getText("Total classes unloaded"), validateLong(cuCount, 0,0)); addRow(Resources.getText("Total classes loaded"), validateLong(ctCount, clCount, clCount)); indent--; {// OracleRuntimeMXBean. MBeanInfo info = null; String beanName = "oracle.jvm:type=OracleRuntime"; ObjectName name = toObjectName(beanName); Object val = null; MBeanServerConnection server = proxyClient.getMBeanServerConnection(); try { info = server.getMBeanInfo(name); addRow(FIELD_GET + "OracleRuntimeMXBean", "" + info + " " + passKwd); } catch (Throwable thr) { out(thr); addRow(FIELD_GET + "OracleRuntimeMXBean", "" + info + " " + failKwd); } // get a few attributes indent++; { String[] attributeNames = { "Platform", "WholeJVM_ExecutionElapsedTime", "WholeJVM_CallHeapCollectedCount" }; for (int i = 0; i < attributeNames.length; i++) { try { val = server.getAttribute(name, attributeNames[i]); addRow(FIELD_GET + "OracleRuntimeMXBean", attributeNames[i] + " = " + val + " " + passKwd); } catch (Throwable thr) { out(thr); addRow(FIELD_GET + "OracleRuntimeMXBean", attributeNames[i] + " attribute " + failKwd); } } } indent--; } if (measureAverageRoundtripTime) { long rt_start = System.currentTimeMillis(); for (int rti = 0; rti < 1000; rti++) clCount = clMBean.getLoadedClassCount(); addRow("Roundtrip time, average, ms: " + (System.currentTimeMillis() - ((double)rt_start))); rt_start = System.currentTimeMillis(); // [bug 10145316] // if (platfOSMBean != null) platfOSMBean.getProcessCpuTime(); if (clMBean != null ) clMBean.getLoadedClassCount(); if (memoryBean != null) memoryBean.isVerbose(); // [bug 10145316] // if (platfOSMBean != null) platfOSMBean.getProcessCpuTime(); if (clMBean != null ) clMBean.getLoadedClassCount(); if (memoryBean != null) memoryBean.isVerbose(); addRow("Roundtrip time, single, diff beans ms: " + (((System.currentTimeMillis() - ((double)rt_start)))/6)); } } } if (beanInfoList.size() > 0) { if (verbose) outln(" *** Individual MBean Info *** "); Iterator it = beanInfoList.iterator(); while (it.hasNext()) { String beanName = (String)it.next(); ObjectName name = toObjectName(beanName); if (name != null) { // get bean info MBeanInfo info = null; try { MBeanServerConnection server = proxyClient.getMBeanServerConnection(); info = server.getMBeanInfo(name); addRow(FIELD_GET + " Bean info " + beanName, "" + passKwd); if (info != null) { indent++; MBeanAttributeInfo[] attrs = info.getAttributes(); addRow("Attributes"); indent++; for (MBeanAttributeInfo attr : attrs) { if (attr != null) { showAttributeInfo(attr); indent++; try { Object val = server.getAttribute(name, attr.getName()); addRow("Value", ""+val); } catch (Exception e) { if (DEBUG) out(e); addRow("Value", "unavailable"); } indent--; } } indent--; MBeanOperationInfo[] ops = info.getOperations(); addRow("Operations"); indent++; for (MBeanOperationInfo op : ops) { if (op != null) { showOperationInfo(op); } } indent--; indent--; } } catch (InstanceNotFoundException e) { addRow(FIELD_GET + " Bean does not exit", beanName + " " + failKwd); out(e); } catch (ReflectionException e1) { addRow(FIELD_GET + " Bean inacessible", beanName + " " + failKwd); out(e1); } } } } if (beanGettersList.size() > 0) { if (verbose) outln(" *** Get Specific MBean Attributes *** "); Iterator it = beanGettersList.iterator(); while (it.hasNext()) { String beanName = (String) it.next(); ObjectName name = toObjectName(beanName); String attrName = (String) it.next(); if (name != null) { // get bean info Object val = null; try { MBeanServerConnection server = proxyClient.getMBeanServerConnection(); val = server.getAttribute(name, attrName); if (val != null && val.getClass().isArray()) { Object[] arr = (Object[])val; String val_print = "{"; for (int i = 0; i < arr.length; i++) { val_print += " " + arr[i]; } val_print += " }"; val = val_print; } addRow(FIELD_GET + " Bean attribute", attrName + " " + passKwd); } catch (InstanceNotFoundException e) { addRow(FIELD_GET + " Bean does not exist", beanName + " " + failKwd); out(e); } catch (AttributeNotFoundException e) { addRow(FIELD_GET + " Bean attribute does not exist", attrName + " " + failKwd); out(e); } catch (ReflectionException e) { addRow(FIELD_GET + " Problem retrieving attribute ", attrName + " " + failKwd); out(e); } addRow(FIELD_GET + " Attribute '" + attrName + "' value", "" + val); } } } if (beanSettersList.size() > 0) { if (verbose) outln(" *** Set Specific MBean Attributes *** "); Iterator it = beanSettersList.iterator(); while (it.hasNext()) { String beanName = (String) it.next(); String attrName = (String) it.next(); String literal = (String) it.next(); ObjectName name = toObjectName(beanName); Object val = literal; if (name != null) { // set attribute try { MBeanServerConnection server = proxyClient.getMBeanServerConnection(); // first, get the attribute to determine the type of it val = server.getAttribute(name, attrName); if (val != null) val = coerceAttributeLiteralTo(literal, val); // second, set the new value Attribute attr = new Attribute(attrName, val); server.setAttribute(name, attr); // last, retrieve the new value and print out val = server.getAttribute(name, attrName); addRow(FIELD_SET + beanName + "." + attrName, ""+ val + " " + passKwd); } catch (InstanceNotFoundException e) { addRow(FIELD_SET + beanName + "." + attrName, ""+ val + " " + failKwd); out(e); } catch (AttributeNotFoundException e) { addRow(FIELD_SET + beanName + "." + attrName, ""+ val + " " + failKwd); out(e); } catch (ReflectionException e) { addRow(FIELD_SET + beanName + "." + attrName, ""+ val + " " + failKwd); out(e); } } } } if (beanOperationsList.size() > 0) { if (verbose) outln(" *** Invoke Specific MBean Operations *** "); Iterator it = beanOperationsList.iterator(); while (it.hasNext()) { String beanName = (String) it.next(); String opName = (String) it.next(); String[] paramSign = (String[]) it.next(); Object[] params = (Object[]) it.next(); ObjectName name = toObjectName(beanName); if (name != null) { // get bean info Object val = null; try { MBeanServerConnection server = proxyClient.getMBeanServerConnection(); val = server.invoke(name, opName, params, paramSign); addRow(FIELD_GET + " Bean operation " + beanName + ":" + opName, "" + passKwd); } catch (InstanceNotFoundException e) { addRow(FIELD_GET + " Bean does not exist", beanName + " " + failKwd); out(e); } catch (ReflectionException e) { addRow(FIELD_GET + " Bean operation " + beanName + "." + opName, "" + failKwd); out(e); } String params_str = ""; for (int pi = 0; pi < params.length; pi++) params_str += (pi == 0 ? "" : ",") + params[pi]; addRow("Result of " + beanName + ":" + opName + "(" + params_str + ") :", ""+val); } } } } catch (IOException e) { addRow(failKwd + "Got IO exception " + e); out(e); } catch (Exception e) { addRow(failKwd + " Got exception " + e); out(e); } } }