8046778: Better error messages when starting JMX agent via attach or jcmd
authorsla
Wed, 18 Jun 2014 09:04:20 +0200
changeset 24980 dbf4ae2cafa4
parent 24979 b7bbc918ad4b
child 24981 09fa2afd361a
8046778: Better error messages when starting JMX agent via attach or jcmd Reviewed-by: dholmes
jdk/src/share/classes/sun/management/Agent.java
jdk/src/share/classes/sun/management/resources/agent.properties
jdk/test/com/sun/tools/attach/StartManagementAgent.java
--- a/jdk/src/share/classes/sun/management/Agent.java	Tue Jun 17 10:47:07 2014 +0100
+++ b/jdk/src/share/classes/sun/management/Agent.java	Wed Jun 18 09:04:20 2014 +0200
@@ -34,7 +34,6 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.net.InetAddress;
-import java.net.Socket;
 import java.net.UnknownHostException;
 import java.text.MessageFormat;
 import java.util.MissingResourceException;
@@ -88,7 +87,7 @@
     // return empty property set
     private static Properties parseString(String args) {
         Properties argProps = new Properties();
-        if (args != null) {
+        if (args != null && !args.trim().equals("")) {
             for (String option : args.split(",")) {
                 String s[] = option.split("=", 2);
                 String name = s[0].trim();
@@ -160,53 +159,59 @@
             throw new RuntimeException(getText(INVALID_STATE, "Agent already started"));
         }
 
-        Properties argProps = parseString(args);
-        Properties configProps = new Properties();
+        try {
+            Properties argProps = parseString(args);
+            Properties configProps = new Properties();
 
-        // Load the management properties from the config file
-        // if config file is not specified readConfiguration implicitly
-        // reads <java.home>/lib/management/management.properties
+            // Load the management properties from the config file
+            // if config file is not specified readConfiguration implicitly
+            // reads <java.home>/lib/management/management.properties
+
+            String fname = System.getProperty(CONFIG_FILE);
+            readConfiguration(fname, configProps);
 
-        String fname = System.getProperty(CONFIG_FILE);
-        readConfiguration(fname, configProps);
+            // management properties can be overridden by system properties
+            // which take precedence
+            Properties sysProps = System.getProperties();
+            synchronized (sysProps) {
+                configProps.putAll(sysProps);
+            }
 
-        // management properties can be overridden by system properties
-        // which take precedence
-        Properties sysProps = System.getProperties();
-        synchronized (sysProps) {
-            configProps.putAll(sysProps);
-        }
+            // if user specifies config file into command line for either
+            // jcmd utilities or attach command it overrides properties set in
+            // command line at the time of VM start
+            String fnameUser = argProps.getProperty(CONFIG_FILE);
+            if (fnameUser != null) {
+                readConfiguration(fnameUser, configProps);
+            }
 
-        // if user specifies config file into command line for either
-        // jcmd utilities or attach command it overrides properties set in
-        // command line at the time of VM start
-        String fnameUser = argProps.getProperty(CONFIG_FILE);
-        if (fnameUser != null) {
-            readConfiguration(fnameUser, configProps);
-        }
+            // arguments specified in command line of jcmd utilities
+            // override both system properties and one set by config file
+            // specified in jcmd command line
+            configProps.putAll(argProps);
 
-        // arguments specified in command line of jcmd utilities
-        // override both system properties and one set by config file
-        // specified in jcmd command line
-        configProps.putAll(argProps);
+            // jcmd doesn't allow to change ThreadContentionMonitoring, but user
+            // can specify this property inside config file, so enable optional
+            // monitoring functionality if this property is set
+            final String enableThreadContentionMonitoring =
+                    configProps.getProperty(ENABLE_THREAD_CONTENTION_MONITORING);
 
-        // jcmd doesn't allow to change ThreadContentionMonitoring, but user
-        // can specify this property inside config file, so enable optional
-        // monitoring functionality if this property is set
-        final String enableThreadContentionMonitoring =
-                configProps.getProperty(ENABLE_THREAD_CONTENTION_MONITORING);
+            if (enableThreadContentionMonitoring != null) {
+                ManagementFactory.getThreadMXBean().
+                        setThreadContentionMonitoringEnabled(true);
+            }
 
-        if (enableThreadContentionMonitoring != null) {
-            ManagementFactory.getThreadMXBean().
-                    setThreadContentionMonitoringEnabled(true);
-        }
+            String jmxremotePort = configProps.getProperty(JMXREMOTE_PORT);
+            if (jmxremotePort != null) {
+                jmxServer = ConnectorBootstrap.
+                        startRemoteConnectorServer(jmxremotePort, configProps);
 
-        String jmxremotePort = configProps.getProperty(JMXREMOTE_PORT);
-        if (jmxremotePort != null) {
-            jmxServer = ConnectorBootstrap.
-                    startRemoteConnectorServer(jmxremotePort, configProps);
-
-            startDiscoveryService(configProps);
+                startDiscoveryService(configProps);
+            } else {
+                throw new AgentConfigurationError(INVALID_JMXREMOTE_PORT, "No port specified");
+            }
+        } catch (AgentConfigurationError err) {
+            error(err.getError(), err.getParams());
         }
     }
 
@@ -507,7 +512,7 @@
         String keyText = getText(key);
         System.err.print(getText("agent.err.error") + ": " + keyText);
         System.err.println(": " + message);
-        throw new RuntimeException(keyText);
+        throw new RuntimeException(keyText + ": " + message);
     }
 
     public static void error(Exception e) {
--- a/jdk/src/share/classes/sun/management/resources/agent.properties	Tue Jun 17 10:47:07 2014 +0100
+++ b/jdk/src/share/classes/sun/management/resources/agent.properties	Wed Jun 18 09:04:20 2014 +0200
@@ -43,7 +43,7 @@
 agent.err.premain.notfound         = premain(String) does not exist in agent class
 agent.err.agentclass.access.denied = Access to premain(String) is denied
 agent.err.invalid.agentclass       = Invalid com.sun.management.agent.class property value
-agent.err.invalid.state            = Invalid agent state
+agent.err.invalid.state            = Invalid agent state: {0}
 agent.err.invalid.jmxremote.port   = Invalid com.sun.management.jmxremote.port number
 agent.err.invalid.jmxremote.rmi.port = Invalid com.sun.management.jmxremote.rmi.port number
 
--- a/jdk/test/com/sun/tools/attach/StartManagementAgent.java	Tue Jun 17 10:47:07 2014 +0100
+++ b/jdk/test/com/sun/tools/attach/StartManagementAgent.java	Wed Jun 18 09:04:20 2014 +0200
@@ -93,7 +93,7 @@
         } catch(AttachOperationFailedException ex) {
             // We expect parsing of "apa" above to fail, but if the file path
             // can't be read we get a different exception message
-            if (!ex.getMessage().contains("java.lang.NumberFormatException")) {
+            if (!ex.getMessage().contains("Invalid com.sun.management.jmxremote.port number")) {
                 throw ex;
             }
         }