Command Line Parser: GNUCommandLine
import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.GnuParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.MissingOptionException; import org.apache.commons.cli.Option; import org.apache.commons.cli.OptionBuilder; import org.apache.commons.cli.OptionGroup; import org.apache.commons.cli.Options; public class GNUCommandLine { private Options options = new Options(); private String[] cmdlineArgs = null; private CommandLine cmdLine = null; private boolean isParsed = false; public GNUCommandLine(String cmdLineArgs[]) { this.cmdlineArgs = cmdLineArgs; this.addOption("help", "print this help message", false, false); } /** * Adds an option into the command line parser * @param optionName - the option name * @param description - option description * @param hasArg - if set to true, the option will accept argument: --optionName=value, otherwise, --optionName is a boolean * @param isMandatory - if set to true, the option must be provided. */ public Option addOption(String optionName, String description, boolean hasArg, boolean isMandatory) { return addOption(optionName, null, description, hasArg, isMandatory); } /** * Adds an option into the command line parser * @param optionName - the option name * @param argName - the name for the argument * @param description - option description * @param hasArg - if set to true, the option will accept argument: --optionName=value, otherwise, --optionName is a boolean * @param isMandatory - if set to true, the option must be provided. */ @SuppressWarnings("static-access") public Option addOption(String optionName, String argName, String description, boolean hasArg, boolean isMandatory) { OptionBuilder opt = OptionBuilder.withLongOpt(optionName); opt = opt.withDescription(description); if (hasArg) { opt = opt.hasArg(); } if (isMandatory) { opt = opt.isRequired(); } if (argName != null) { opt = opt.withArgName(argName); } Option option = opt.create(); options.addOption(option); return option; } /** * Two options form a mutually exclusive option group * @param option1 * @param option2 * @return */ public OptionGroup addOptionGroup(Option option1, Option option2) { OptionGroup optionGroup = new OptionGroup(); optionGroup.addOption(option1); optionGroup.addOption(option2); options.addOptionGroup(optionGroup); return optionGroup; } /** * Several options form a mutually exclusive option group * @param optionList * @return */ public OptionGroup addOptionGroup(List<Option> optionList) { OptionGroup optionGroup = new OptionGroup(); for (Option option : optionList) { optionGroup.addOption(option); } options.addOptionGroup(optionGroup); return optionGroup; } /** * Return all options * @return */ public Options getOptions() { return this.options; } private void parse() throws Exception { CommandLineParser parser = new GnuParser(); try { this.cmdLine = parser.parse(this.options, this.cmdlineArgs); } catch (MissingOptionException e) { printUsage(); } this.isParsed = true; if (this.cmdLine.hasOption("help")) { printUsage(); } } public void printUsage() { HelpFormatter formatter = new HelpFormatter(); formatter.printHelp("options ", options); System.exit(1); } public String getString(String optionName) throws Exception { if (!this.isParsed) { this.parse(); } return this.cmdLine.getOptionValue(optionName); } public Integer getInteger(String optionName) throws Exception { return Integer.parseInt(this.getString(optionName)); } public Double getDouble(String optionName) throws Exception { return Double.parseDouble(this.getString(optionName)); } public List<String> getList(String optionName, String delimiter) throws Exception { List<String> arrayList = new ArrayList<String>(); StringTokenizer tkn = new StringTokenizer(this.getString(optionName), delimiter); while (tkn.hasMoreTokens()) { arrayList.add(tkn.nextToken()); } return arrayList; } public boolean hasOption(String optionName) throws Exception { if (!this.isParsed) { this.parse(); } return this.cmdLine.hasOption(optionName); } }
JMXClient:
public class JmxClient { private static final String OPTION_HOSTNAME = "host-name"; private static final String OPTION_PORT = "port"; private static final String OPTION_USER_NAME = "user-name"; private static final String OPTION_PASSWORD = "password"; private static final String OPTION_MBEAN_DOMAIN = "mbean-domain"; private static final String OPTION_MBEAN_NAME = "mbean-name"; private static final String OPTION_MBEAN_OPERATION = "mbean-operation"; public static void main(String[] args) { GNUCommandLine cli = new GNUCommandLine(args); cli.addOption(OPTION_HOSTNAME, "host name of remote mbean server", true, true); cli.addOption(OPTION_PORT, "port number of remote mbean server", true, true); cli.addOption(OPTION_USER_NAME, "user name for remote jmx connection", true, true); cli.addOption(OPTION_PASSWORD, "password for remote jmx connection", true, true); cli.addOption(OPTION_MBEAN_DOMAIN, "mbean domain to lookup from remote mbean server", true, true); cli.addOption(OPTION_MBEAN_NAME, "mbean name to lookup from remote mbean server", true, true); cli.addOption(OPTION_MBEAN_OPERATION, "mbean operation to lookup from remote mbean server", true, true); String hostName = null; Integer port = null; String userName = null; String password = null; String mBeanDomain = null; String mBeanName = null; String mBeanOperation = null; try { hostName = cli.getString(OPTION_HOSTNAME); port = cli.getInteger(OPTION_PORT); userName = cli.getString(OPTION_USER_NAME); password = cli.getString(OPTION_PASSWORD); mBeanDomain = cli.getString(OPTION_MBEAN_DOMAIN); mBeanName = cli.getString(OPTION_MBEAN_NAME); mBeanOperation = cli.getString(OPTION_MBEAN_OPERATION); } catch (NumberFormatException e) { System.err.println("Number format error. " + e.getMessage()); System.exit(1); } catch (Exception e) { System.err.println(e.getMessage()); System.exit(1); } JmxClientWorker worker = new JmxClientWorker(); worker.execute(hostName, port, userName, password, mBeanDomain, mBeanName, mBeanOperation); } }
JMXClientWorker:
import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.Hashtable; import java.util.Iterator; import java.util.Set; import javax.management.InstanceNotFoundException; import javax.management.IntrospectionException; import javax.management.MBeanException; import javax.management.MBeanFeatureInfo; import javax.management.MBeanOperationInfo; import javax.management.MBeanParameterInfo; import javax.management.MBeanServerConnection; import javax.management.MalformedObjectNameException; import javax.management.ObjectInstance; import javax.management.ObjectName; import javax.management.ReflectionException; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; public class JmxClientWorker { public void execute(String hostName, Integer port, String userName, String password, String mBeanDomain, String mBeanName, String mBeanOperation) { JMXConnector jmxc = null; try { JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + hostName + ":" + port + "/jmxrmi"); Hashtable<String, Object[]> env = new Hashtable<String, Object[]>(); String[] credentials = new String[]{userName, password}; env.put(JMXConnector.CREDENTIALS, credentials); System.out.println("Connecting to server: [" + url + "]"); jmxc = JMXConnectorFactory.connect(url, env); MBeanServerConnection mbs = jmxc.getMBeanServerConnection(); System.out.println("Invoking operation: [" + mBeanDomain + ":" + mBeanName + " -> " + mBeanOperation + "]"); ObjectName objectName = new ObjectName(mBeanDomain + ":name=" + mBeanName); Set<?> beans = mbs.queryMBeans(objectName, null); if (beans.size() == 0) { exit("Not a registered bean -> " + "[" + objectName.getCanonicalName() + "]"); } else if (beans.size() > 1) { listOptions(beans); exit("More than one beans are found. Please be more specific"); } else { ObjectInstance instance = (ObjectInstance) beans.iterator().next(); MBeanOperationInfo[] operationInfos = mbs.getMBeanInfo(instance.getObjectName()).getOperations(); MBeanOperationInfo operationInfo = (MBeanOperationInfo) getFeatureInfo(operationInfos, mBeanOperation); if (operationInfo != null) { MBeanParameterInfo[] paramInfos = operationInfo.getSignature(); String[] params = getParameters(mBeanOperation); int paramInfosLength = paramInfos != null ? paramInfos.length : 0; int paramsLength = params != null ? params.length : 0; if (paramInfosLength != paramsLength) { exit("Parameters count passed doesn't match signature count"); } else { Object[] paramObjects = paramInfosLength != 0 ? new Object[paramInfosLength] : null; String[] signatures = paramInfosLength != 0 ? new String[paramInfosLength] : null; for (int i = 0; i < paramInfos.length; i++) { MBeanParameterInfo paramInfo = paramInfos[i]; Constructor<?> c = Class.forName(paramInfo.getType()).getConstructor(new Class[] { java.lang.String.class }); paramObjects[i] = c.newInstance(new Object[]{params[i] }); signatures[i] = paramInfos[i].getType(); } Object result = mbs.invoke(instance.getObjectName(), operationInfo.getName(), paramObjects, signatures); System.out.println("Result: [" + result + "]"); } } else { exit("Operation not found: [" + mBeanOperation + "]"); } } } catch (InstanceNotFoundException e) { exit("Failed to find mbean", e); } catch (MalformedObjectNameException e) { exit("Invalid object name", e); } catch (ReflectionException e) { exit("No operation found", e); } catch (IOException e) { exit("Failed to connect to mbean server", e); } catch (SecurityException e) { exit("Authentication failed", e); } catch (IntrospectionException e) { exit("Failed to get mbean info", e); } catch (NoSuchMethodException e) { exit("Method is not found", e); } catch (ClassNotFoundException e) { exit("Parameter type is not found", e); } catch (IllegalArgumentException e) { exit("Invalid argument", e); } catch (InstantiationException e) { exit("Failed to initialize type", e); } catch (IllegalAccessException e) { exit("Invalid access", e); } catch (InvocationTargetException e) { exit("Failed to invoke target", e); } catch (MBeanException e) { exit("MBean exception", e); } finally { if (jmxc != null) { try { jmxc.close(); } catch (IOException e) { exit("Failed to close JMXConnectorFactory" + e.getMessage()); } } } System.out.println("Executed: [" + mBeanOperation + "]"); } private void exit (String message) { System.err.println(message); System.exit(1); } private void exit (String message, Throwable e) { while (e.getCause() != null) { e = e.getCause(); } System.err.println("Failed to execute operation, reason: [" + message + " -> " + e.getMessage() + "]"); System.exit(1); } private MBeanFeatureInfo getFeatureInfo(MBeanFeatureInfo infos[], String mBeanOperation) { int index = mBeanOperation.indexOf('='); String name = index <= 0 ? mBeanOperation : mBeanOperation.substring(0, index); for(int i = 0; i < infos.length; i++) { if(infos[i].getName().equals(name)) { return infos[i]; } } return null; } private String[] getParameters (String mBeanOperation) { int index = mBeanOperation.indexOf('='); if (index <=0) { return null; } else { return mBeanOperation.substring(index).split(","); } } private void listOptions(Set<?> beans) { for (Iterator<?> iter = beans.iterator(); iter.hasNext();) { Object obj = iter.next(); if (obj instanceof ObjectName) { System.out.println(((ObjectName) obj).getCanonicalName()); } else if (obj instanceof ObjectInstance) { System.out.println(((ObjectInstance) obj).getObjectName().getCanonicalName()); } else { System.err.println("Unexpected object type: " + obj.toString()); } } } }