001: /*
002: * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.tools.jinfo;
027:
028: import java.lang.reflect.Method;
029: import java.io.File;
030: import java.io.IOException;
031: import java.io.InputStream;
032:
033: import com.sun.tools.attach.VirtualMachine;
034: import sun.tools.attach.HotSpotVirtualMachine;
035:
036: /*
037: * This class is the main class for the JInfo utility. It parses its arguments
038: * and decides if the command should be satisifed using the VM attach mechanism
039: * or an SA tool. At this time the only option that uses the VM attach
040: * mechanism is the -flag option to set or print a command line option of a
041: * running application. All other options are mapped to SA tools.
042: */
043: public class JInfo {
044:
045: public static void main(String[] args) throws Exception {
046: if (args.length == 0) {
047: usage(); // no arguments
048: }
049:
050: boolean useSA = true;
051: String arg1 = args[0];
052: if (arg1.startsWith("-")) {
053: if (arg1.equals("-flags") || arg1.equals("-sysprops")) {
054: // SA JInfo needs <pid> or <server> or
055: // (<executable> and <code file>). So, total
056: // argument count including option has to 2 or 3.
057: if (args.length != 2 && args.length != 3) {
058: usage();
059: }
060: } else if (arg1.equals("-flag")) {
061: // do not use SA, use attach-on-demand
062: useSA = false;
063: } else {
064: // unknown option or -h or -help, print help
065: usage();
066: }
067: }
068:
069: if (useSA) {
070: runTool(args);
071: } else {
072: if (args.length == 3) {
073: String pid = args[2];
074: String option = args[1];
075: flag(pid, option);
076: } else {
077: usage();
078: }
079: }
080: }
081:
082: // Invoke SA tool with the given arguments
083: private static void runTool(String args[]) throws Exception {
084: String tool = "sun.jvm.hotspot.tools.JInfo";
085: // Tool not available on this platform.
086: Class<?> c = loadClass(tool);
087: if (c == null) {
088: usage();
089: }
090:
091: // invoke the main method with the arguments
092: Class[] argTypes = { String[].class };
093: Method m = c.getDeclaredMethod("main", argTypes);
094:
095: Object[] invokeArgs = { args };
096: m.invoke(null, invokeArgs);
097: }
098:
099: // loads the given class using the system class loader
100: private static Class loadClass(String name) {
101: //
102: // We specify the system clas loader so as to cater for development
103: // environments where this class is on the boot class path but sa-jdi.jar
104: // is on the system class path. Once the JDK is deployed then both
105: // tools.jar and sa-jdi.jar are on the system class path.
106: //
107: try {
108: return Class.forName(name, true, ClassLoader
109: .getSystemClassLoader());
110: } catch (Exception x) {
111: }
112: return null;
113: }
114:
115: private static void flag(String pid, String option)
116: throws IOException {
117: VirtualMachine vm = attach(pid);
118: String flag;
119: InputStream in;
120: int index = option.indexOf('=');
121: if (index != -1) {
122: flag = option.substring(0, index);
123: String value = option.substring(index + 1);
124: in = ((HotSpotVirtualMachine) vm).setFlag(flag, value);
125: } else {
126: char c = option.charAt(0);
127: switch (c) {
128: case '+':
129: flag = option.substring(1);
130: in = ((HotSpotVirtualMachine) vm).setFlag(flag, "1");
131: break;
132: case '-':
133: flag = option.substring(1);
134: in = ((HotSpotVirtualMachine) vm).setFlag(flag, "0");
135: break;
136: default:
137: flag = option;
138: in = ((HotSpotVirtualMachine) vm).printFlag(flag);
139: break;
140: }
141: }
142:
143: drain(vm, in);
144: }
145:
146: // Attach to <pid>, exiting if we fail to attach
147: private static VirtualMachine attach(String pid) {
148: try {
149: return VirtualMachine.attach(pid);
150: } catch (Exception x) {
151: String msg = x.getMessage();
152: if (msg != null) {
153: System.err.println(pid + ": " + msg);
154: } else {
155: x.printStackTrace();
156: }
157: System.exit(1);
158: return null; // keep compiler happy
159: }
160: }
161:
162: // Read the stream from the target VM until EOF, then detach
163: private static void drain(VirtualMachine vm, InputStream in)
164: throws IOException {
165: // read to EOF and just print output
166: byte b[] = new byte[256];
167: int n;
168: do {
169: n = in.read(b);
170: if (n > 0) {
171: String s = new String(b, 0, n, "UTF-8");
172: System.out.print(s);
173: }
174: } while (n > 0);
175: in.close();
176: vm.detach();
177: }
178:
179: // print usage message
180: private static void usage() {
181:
182: Class c = loadClass("sun.jvm.hotspot.tools.JInfo");
183: boolean usageSA = (c != null);
184:
185: System.out.println("Usage:");
186: if (usageSA) {
187: System.out.println(" jinfo [option] <pid>");
188: System.out
189: .println(" (to connect to running process)");
190: System.out.println(" jinfo [option] <executable <core>");
191: System.out.println(" (to connect to a core file)");
192: System.out
193: .println(" jinfo [option] [server_id@]<remote server IP or hostname>");
194: System.out
195: .println(" (to connect to remote debug server)");
196: System.out.println("");
197: System.out.println("where <option> is one of:");
198: System.out
199: .println(" -flag <name> to print the value of the named VM flag");
200: System.out
201: .println(" -flag [+|-]<name> to enable or disable the named VM flag");
202: System.out
203: .println(" -flag <name>=<value> to set the named VM flag to the given value");
204: System.out
205: .println(" -flags to print VM flags");
206: System.out
207: .println(" -sysprops to print Java system properties");
208: System.out
209: .println(" <no option> to print both of the above");
210: System.out
211: .println(" -h | -help to print this help message");
212: } else {
213: System.out.println(" jinfo <option> <pid>");
214: System.out
215: .println(" (to connect to a running process)");
216: System.out.println("");
217: System.out.println("where <option> is one of:");
218: System.out
219: .println(" -flag <name> to print the value of the named VM flag");
220: System.out
221: .println(" -flag [+|-]<name> to enable or disable the named VM flag");
222: System.out
223: .println(" -flag <name>=<value> to set the named VM flag to the given value");
224: System.out
225: .println(" -h | -help to print this help message");
226: }
227:
228: System.exit(1);
229: }
230: }
|