/*************************************************************** #Author: Kannan Balasubramanian #Last Updated on: 11/22/2007 #Tool for querying jhat and redirect o/p to stdout or a file... ****************************************************************/ import java.net.*; import java.io.*; import java.util.*; public class JQuery { public static BufferedReader input = null; public static PrintWriter output = null; public static Socket socket = null; public static PrintStream stdout = System.out; public static void usage() { System.err.println("Usage: java JQuery [logfile]"); System.err.println("E.g: java JQuery localhost 7001 log.txt"); } public static void displayCommands() { System.err.println(".....................Commands......................"); System.err.println(" / ( all classes excluding plaform)"); System.err.println(" showRoots"); System.err.println(" allClassesWithPlatform"); System.err.println(" showInstanceCounts"); System.err.println(" showInstanceCounts/includePlatform"); System.err.println(" histo"); System.err.println(" finalizerSummary"); System.err.println(" finalizerObjects"); System.err.println(" oql/?query=<>"); System.err.println(" oqlhelp"); System.err.println(" <-help> <-h> "); System.err.println(" redirect "); System.err.println(" redirect none (msgs goes to stdout)"); System.err.println(" quit (exit JQuery)"); System.err.println("..................................................."); System.err.println("\n"); } public static String validateOQLCommand(String str) { String inputString = str; if (inputString.indexOf('\n') != -1 || inputString.indexOf('\r') != -1) { inputString = inputString.substring(0, inputString.length()-2); } if (inputString.equals("/")) { return inputString + " ."; } if (inputString.indexOf("?query") != -1) { //This is a query. Leave it as it is. return "/" + inputString + " ."; } inputString = "/" + inputString + "/" + " ."; //hack. remove . later and fix it return inputString; } public static boolean validateCommand(String str) { String inputString = str.toLowerCase().trim(); if (inputString.length() == 0) { System.err.println("No command specified ...."); return false; } if (inputString.startsWith("-help") || inputString.startsWith("help") || inputString.equals("-h")) { displayCommands(); return false; } if(inputString.equals("quit")) { if (socket != null) { try { socket.close(); } catch (Exception e) { System.err.println(e); } } System.err.println("Exiting JQuery..."); System.exit(0); } if (!inputString.startsWith("redirect")) { //it's a OQL command... return true; } StringTokenizer st = new StringTokenizer(inputString); String buf = null; if (st.hasMoreTokens()) { buf = st.nextToken(); if (buf.equals("redirect")) { if (!st.hasMoreTokens()) { System.err.println("invalid command... See -help"); return false; } buf = st.nextToken(); try { if (buf.equals("none")) { System.setOut(stdout); return false; } else { System.setOut(new PrintStream(new FileOutputStream(buf))); return false; } } catch (Exception e) { System.err.println(e); return false; } } } return true; //It's a OQL command } public static boolean updateSocketStreams(InetAddress addr, int port) { try { if (socket != null) { socket.close(); } while (true) { try { socket = new Socket(addr, port); break; } catch (Exception ex) { System.err.println("Socket not connected. Waiting..."); Thread.sleep(2000); } } if (input != null) { input.close(); } input = new BufferedReader( new InputStreamReader(socket.getInputStream())); if (output != null) { output.close(); } output = new PrintWriter(socket.getOutputStream(), true); } catch (Exception e) { e.printStackTrace(); return false; } return true; } public static void main(String [] args) { if (args != null && args.length < 2) { usage(); return; } if (args[0].equals("-h") || args[0].equals("-help")) { usage(); return; } int port = -1; try { port = Integer.parseInt(args[1]); } catch (NumberFormatException ne) { System.err.println("Invalid port: " + args[1]); return; } if (args.length >= 3) { try { System.setOut(new PrintStream(new FileOutputStream(args[2]))); } catch(Exception e) { System.err.println("Cannot write to log file: " + args[2] + " ..."); return; } } try { InetAddress address = null; //Take the default hostaddress, if no hostname is provided at the command line. if ( args != null && args.length > 0 ) { address = InetAddress.getByName(args[0]); } else { address = InetAddress.getLocalHost(); } boolean bFlag = updateSocketStreams(address, port); if (bFlag) { System.err.println("Congrats... you are connected...\nStart sending messages now..."); System.err.println("Type -help for list of commands supported...\n"); } final BufferedReader stdinput = new BufferedReader(new InputStreamReader(System.in)); //create a separate thread for listening to the socket. Thread thread = new Thread() { public void run() { String inString = null; while (true) { try { inString = input.readLine(); if (inString != null) { System.out.println(inString); } else { Thread.sleep(1000); } } catch(Exception e) { //System.out.println("Thread: " + e.toString()); } finally { //System.out.println("Input socket done..."); } } } }; thread.setDaemon(true); thread.start(); String inputString; //keep reading from the stdinput console and pass it on to the socket. while ((inputString = stdinput.readLine()) != null) { if (!validateCommand(inputString)) { //it's a non OQL command. Hence no need to communicate to jhat continue; } updateSocketStreams(address, port); inputString = validateOQLCommand(inputString); output.println("GET " + inputString); } System.err.println("Output socket done..."); } catch(Exception e) { System.err.println("exception: " + e.toString()); } } }