7110104: It should be possible to stop and start JMX Agent at runtime
Summary: Added a capability to start and stop JMX Agent by jcmd
Reviewed-by: acorn, mchung
--- a/jdk/src/share/classes/sun/management/Agent.java Sun Feb 26 17:25:42 2012 +0000
+++ b/jdk/src/share/classes/sun/management/Agent.java Mon Feb 27 15:21:18 2012 +0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,30 +25,34 @@
package sun.management;
+import java.io.BufferedInputStream;
import java.io.File;
-import java.io.InputStream;
import java.io.FileInputStream;
-import java.io.BufferedInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.io.InputStream;
+
import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.management.ManagementFactory;
+
import java.text.MessageFormat;
+
+import java.util.MissingResourceException;
import java.util.Properties;
import java.util.ResourceBundle;
-import java.util.MissingResourceException;
-import java.lang.management.ManagementFactory;
-import java.lang.reflect.Method;
import javax.management.remote.JMXConnectorServer;
+import static sun.management.AgentConfigurationError.*;
import sun.management.jmxremote.ConnectorBootstrap;
-import static sun.management.AgentConfigurationError.*;
import sun.misc.VMSupport;
/**
* This Agent is started by the VM when -Dcom.sun.management.snmp
* or -Dcom.sun.management.jmxremote is set. This class will be
- * loaded by the system class loader.
+ * loaded by the system class loader. Also jmx framework could
+ * be started by jcmd
*/
public class Agent {
// management properties
@@ -69,7 +73,33 @@
"com.sun.management.jmxremote.localConnectorAddress";
private static final String SNMP_ADAPTOR_BOOTSTRAP_CLASS_NAME =
- "sun.management.snmp.AdaptorBootstrap";
+ "sun.management.snmp.AdaptorBootstrap";
+
+ // The only active agent allowed
+ private static JMXConnectorServer jmxServer = null;
+
+ // Parse string com.sun.management.prop=xxx,com.sun.management.prop=yyyy
+ // and return property set if args is null or empty
+ // return empty property set
+ private static Properties parseString(String args){
+ Properties argProps = new Properties();
+ if (args != null) {
+ for (String option : args.split(",")) {
+ String s[] = option.split("=", 2);
+ String name = s[0].trim();
+ String value = (s.length > 1) ? s[1].trim() : "";
+
+ if (!name.startsWith("com.sun.management.")) {
+ error(INVALID_OPTION, name);
+ }
+
+ argProps.setProperty(name, value);
+ }
+ }
+
+ return argProps;
+ }
+
// invoked by -javaagent or -Dcom.sun.management.agent.class
public static void premain(String args) throws Exception {
@@ -82,37 +112,104 @@
args = JMXREMOTE; // default to local management
}
- // Parse agent options into properties
+ Properties arg_props = parseString(args);
+
+ // Read properties from the config file
+ Properties config_props = new Properties();
+ String fname = arg_props.getProperty(CONFIG_FILE);
+ readConfiguration(fname, config_props);
+
+ // Arguments override config file
+ config_props.putAll(arg_props);
+ startAgent(config_props);
+ }
- Properties arg_props = new Properties();
- if (args != null) {
- String[] options = args.split(",");
- for (int i=0; i<options.length; i++) {
- String[] option = options[i].split("=");
- if (option.length >= 1 && option.length <= 2) {
- String name = option[0];
- String value = (option.length == 1) ? "" : option[1];
- if (name != null && name.length() > 0) {
+ // jcmd ManagementAgent.start_local entry point
+ // Also called due to command-line via startAgent()
+ private static synchronized void startLocalManagementAgent(){
+ Properties agentProps = VMSupport.getAgentProperties();
- // Assume that any com.sun.management.* options are okay
- if (name.startsWith("com.sun.management.")) {
- arg_props.setProperty(name, value);
- } else {
- error(INVALID_OPTION, name);
- }
- }
- }
+ // start local connector if not started
+ if (agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP) == null) {
+ JMXConnectorServer cs = ConnectorBootstrap.startLocalConnectorServer();
+ String address = cs.getAddress().toString();
+ // Add the local connector address to the agent properties
+ agentProps.put(LOCAL_CONNECTOR_ADDRESS_PROP, address);
+
+ try {
+ // export the address to the instrumentation buffer
+ ConnectorAddressLink.export(address);
+ } catch (Exception x) {
+ // Connector server started but unable to export address
+ // to instrumentation buffer - non-fatal error.
+ warning(EXPORT_ADDRESS_FAILED, x.getMessage());
}
}
+ }
- // Read properties from the config file
- Properties config_props = new Properties();
- String fname = arg_props.getProperty(CONFIG_FILE);
- readConfiguration(fname, config_props);
+ // jcmd ManagementAgent.start entry point
+ // This method starts the remote JMX agent and starts neither
+ // the local JMX agent nor the SNMP agent
+ // @see #startLocalManagementAgent and also @see #startAgent.
+ private static synchronized void startRemoteManagementAgent(String args) throws Exception {
+ if (jmxServer != null) {
+ throw new RuntimeException(getText(INVALID_STATE, "Agent already started"));
+ }
+
+ 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
+
+ String fname = System.getProperty(CONFIG_FILE);
+ readConfiguration(fname, configProps);
+
+ // management properties can be overridden by system properties
+ // which take precedence
+ configProps.putAll(System.getProperties());
+
+ // 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 override config file
- config_props.putAll(arg_props);
- startAgent(config_props);
+ // 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);
+
+ if (enableThreadContentionMonitoring != null) {
+ ManagementFactory.getThreadMXBean().
+ setThreadContentionMonitoringEnabled(true);
+ }
+
+ String jmxremotePort = configProps.getProperty(JMXREMOTE_PORT);
+ if (jmxremotePort != null) {
+ jmxServer = ConnectorBootstrap.
+ startRemoteConnectorServer(jmxremotePort, configProps);
+ }
+ }
+
+ private static synchronized void stopRemoteManagementAgent() throws Exception {
+ if (jmxServer != null) {
+ ConnectorBootstrap.unexportRegistry();
+
+ // Attempt to stop already stopped agent
+ // Don't cause any errors.
+ jmxServer.stop();
+ jmxServer = null;
+ }
}
private static void startAgent(Properties props) throws Exception {
@@ -130,7 +227,7 @@
try {
if (snmpPort != null) {
- loadSnmpAgent(snmpPort, props);
+ loadSnmpAgent(snmpPort, props);
}
/*
@@ -142,31 +239,14 @@
* of this "local" server is exported as a counter to the jstat
* instrumentation buffer.
*/
- if (jmxremote != null || jmxremotePort != null) {
+ if (jmxremote != null || jmxremotePort != null) {
if (jmxremotePort != null) {
- ConnectorBootstrap.initialize(jmxremotePort, props);
+ jmxServer = ConnectorBootstrap.
+ startRemoteConnectorServer(jmxremotePort, props);
}
+ startLocalManagementAgent();
+ }
- Properties agentProps = VMSupport.getAgentProperties();
- // start local connector if not started
- // System.out.println("local address : " +
- // agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP));
- if (agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP) == null) {
- JMXConnectorServer cs = ConnectorBootstrap.startLocalConnectorServer();
- String address = cs.getAddress().toString();
- // Add the local connector address to the agent properties
- agentProps.put(LOCAL_CONNECTOR_ADDRESS_PROP, address);
-
- try {
- // export the address to the instrumentation buffer
- ConnectorAddressLink.export(address);
- } catch (Exception x) {
- // Connector server started but unable to export address
- // to instrumentation buffer - non-fatal error.
- warning(EXPORT_ADDRESS_FAILED, x.getMessage());
- }
- }
- }
} catch (AgentConfigurationError e) {
error(e.getError(), e.getParams());
} catch (Exception e) {
@@ -187,9 +267,9 @@
props.putAll(System.getProperties());
return props;
- }
+ }
- public static synchronized Properties getManagementProperties() {
+ public static synchronized Properties getManagementProperties() {
if (mgmtProps == null) {
String configFile = System.getProperty(CONFIG_FILE);
String snmpPort = System.getProperty(SNMP_PORT);
--- a/jdk/src/share/classes/sun/management/AgentConfigurationError.java Sun Feb 26 17:25:42 2012 +0000
+++ b/jdk/src/share/classes/sun/management/AgentConfigurationError.java Mon Feb 27 15:21:18 2012 +0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -53,6 +53,8 @@
"agent.err.invalid.agentclass";
public static final String INVALID_JMXREMOTE_PORT =
"agent.err.invalid.jmxremote.port";
+ public static final String INVALID_JMXREMOTE_RMI_PORT =
+ "agent.err.invalid.jmxremote.rmi.port";
public static final String PASSWORD_FILE_NOT_SET =
"agent.err.password.file.notset";
public static final String PASSWORD_FILE_NOT_READABLE =
@@ -105,6 +107,8 @@
"agent.err.snmp.adaptor.start.failed";
public static final String SNMP_MIB_INIT_FAILED =
"agent.err.snmp.mib.init.failed";
+ public static final String INVALID_STATE =
+ "agent.err.invalid.state";
private final String error;
private final String[] params;
--- a/jdk/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java Sun Feb 26 17:25:42 2012 +0000
+++ b/jdk/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java Mon Feb 27 15:21:18 2012 +0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,25 +28,22 @@
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
+import java.io.IOException;
import java.io.InputStream;
-import java.io.IOException;
-
+import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.UnknownHostException;
-
import java.rmi.NoSuchObjectException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.Registry;
-import java.rmi.server.RemoteObject;
import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory;
+import java.rmi.server.RemoteObject;
import java.rmi.server.UnicastRemoteObject;
-
import java.security.KeyStore;
import java.security.Principal;
-
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -55,35 +52,31 @@
import java.util.Set;
import java.util.StringTokenizer;
-import java.lang.management.ManagementFactory;
-
-import javax.net.ssl.*;
-
import javax.management.MBeanServer;
import javax.management.remote.JMXAuthenticator;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import javax.management.remote.rmi.RMIConnectorServer;
-
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManagerFactory;
import javax.rmi.ssl.SslRMIClientSocketFactory;
import javax.rmi.ssl.SslRMIServerSocketFactory;
-
import javax.security.auth.Subject;
-import sun.rmi.server.UnicastRef;
-import sun.rmi.server.UnicastServerRef;
-import sun.rmi.server.UnicastServerRef2;
+import com.sun.jmx.remote.internal.RMIExporter;
+import com.sun.jmx.remote.security.JMXPluggableAuthenticator;
+import com.sun.jmx.remote.util.ClassLogger;
import sun.management.Agent;
import sun.management.AgentConfigurationError;
import static sun.management.AgentConfigurationError.*;
import sun.management.ConnectorAddressLink;
import sun.management.FileSystem;
-import com.sun.jmx.remote.util.ClassLogger;
-
-import com.sun.jmx.remote.internal.RMIExporter;
-import com.sun.jmx.remote.security.JMXPluggableAuthenticator;
+import sun.rmi.server.UnicastRef;
+import sun.rmi.server.UnicastServerRef;
+import sun.rmi.server.UnicastServerRef2;
/**
* This class initializes and starts the RMIConnectorServer for JSR 163
@@ -114,6 +107,8 @@
public static final String PORT =
"com.sun.management.jmxremote.port";
+ public static final String RMI_PORT =
+ "com.sun.management.jmxremote.rmi.port";
public static final String CONFIG_FILE_NAME =
"com.sun.management.config.file";
public static final String USE_LOCAL_ONLY =
@@ -266,34 +261,61 @@
private final String accessFile;
}
- /**
- * Initializes and starts the JMX Connector Server.
- * If the com.sun.management.jmxremote.port property is not defined,
- * simply return. Otherwise, attempts to load the config file, and
- * then calls {@link #initialize(java.lang.String, java.util.Properties)}.
- *
- **/
- public static synchronized JMXConnectorServer initialize() {
+ // The variable below is here to support stop functionality
+ // It would be overriten if you call startRemoteCommectionServer second
+ // time. It's OK for now as logic in Agent.java forbids mutiple agents
+ private static Registry registry = null;
+
+ public static void unexportRegistry() {
+ // Remove the entry from registry
+ try {
+ if (registry != null) {
+ UnicastRemoteObject.unexportObject(registry, true);
+ registry = null;
+ }
+ } catch(NoSuchObjectException ex) {
+ // This exception can appears only if we attempt
+ // to unexportRegistry second time. So it's safe
+ // to ignore it without additional messages.
+ }
+ }
- // Load a new management properties
- final Properties props = Agent.loadManagementProperties();
- if (props == null) {
- return null;
- }
+ /**
+ * Initializes and starts the JMX Connector Server.
+ * If the com.sun.management.jmxremote.port property is not defined,
+ * simply return. Otherwise, attempts to load the config file, and
+ * then calls {@link #startRemoteConnectorServer
+ * (java.lang.String, java.util.Properties)}.
+ *
+ * This method is used by some jtreg tests.
+ **/
+ public static synchronized JMXConnectorServer initialize() {
- final String portStr = props.getProperty(PropertyNames.PORT);
-
+ // Load a new management properties
+ final Properties props = Agent.loadManagementProperties();
+ if (props == null) {
+ return null;
+ }
- // System.out.println("initializing: {port=" + portStr + ",
- // properties="+props+"}");
- return initialize(portStr, props);
+ final String portStr = props.getProperty(PropertyNames.PORT);
+ return startRemoteConnectorServer(portStr, props);
+ }
+
+ /**
+ * This method is used by some jtreg tests.
+ *
+ * @see #startRemoteConnectorServer
+ * (String portStr, Properties props)
+ */
+ public static synchronized JMXConnectorServer initialize(String portStr, Properties props) {
+ return startRemoteConnectorServer(portStr, props);
}
/**
* Initializes and starts a JMX Connector Server for remote
* monitoring and management.
**/
- public static synchronized JMXConnectorServer initialize(String portStr, Properties props) {
+ public static synchronized JMXConnectorServer startRemoteConnectorServer(String portStr, Properties props) {
// Get port number
final int port;
@@ -306,6 +328,22 @@
throw new AgentConfigurationError(INVALID_JMXREMOTE_PORT, portStr);
}
+ // User can specify a port to be used to export rmi object,
+ // in order to simplify firewall rules
+ // if port is not specified random one will be allocated.
+ int rmiPort = 0;
+ String rmiPortStr = props.getProperty(PropertyNames.RMI_PORT);
+ try {
+ if (rmiPortStr != null) {
+ rmiPort = Integer.parseInt(rmiPortStr);
+ }
+ } catch (NumberFormatException x) {
+ throw new AgentConfigurationError(INVALID_JMXREMOTE_RMI_PORT, x, rmiPortStr);
+ }
+ if (rmiPort < 0) {
+ throw new AgentConfigurationError(INVALID_JMXREMOTE_RMI_PORT, rmiPortStr);
+ }
+
// Do we use authentication?
final String useAuthenticationStr =
props.getProperty(PropertyNames.USE_AUTHENTICATION,
@@ -387,9 +425,10 @@
}
if (log.debugOn()) {
- log.debug("initialize",
- Agent.getText("jmxremote.ConnectorBootstrap.initialize") +
+ log.debug("startRemoteConnectorServer",
+ Agent.getText("jmxremote.ConnectorBootstrap.starting") +
"\n\t" + PropertyNames.PORT + "=" + port +
+ "\n\t" + PropertyNames.RMI_PORT + "=" + rmiPort +
"\n\t" + PropertyNames.USE_SSL + "=" + useSsl +
"\n\t" + PropertyNames.USE_REGISTRY_SSL + "=" + useRegistrySsl +
"\n\t" + PropertyNames.SSL_CONFIG_FILE_NAME + "=" + sslConfigFileName +
@@ -404,7 +443,7 @@
(useAuthentication ? (loginConfigName == null ? ("\n\t" + PropertyNames.PASSWORD_FILE_NAME + "=" +
passwordFileName) : ("\n\t" + PropertyNames.LOGIN_CONFIG_NAME + "=" +
loginConfigName)) : "\n\t" +
- Agent.getText("jmxremote.ConnectorBootstrap.initialize.noAuthentication")) +
+ Agent.getText("jmxremote.ConnectorBootstrap.noAuthentication")) +
(useAuthentication ? ("\n\t" + PropertyNames.ACCESS_FILE_NAME + "=" +
accessFileName) : "") +
"");
@@ -415,15 +454,15 @@
JMXServiceURL url = null;
try {
final JMXConnectorServerData data = exportMBeanServer(
- mbs, port, useSsl, useRegistrySsl,
+ mbs, port, rmiPort, useSsl, useRegistrySsl,
sslConfigFileName, enabledCipherSuitesList,
enabledProtocolsList, sslNeedClientAuth,
useAuthentication, loginConfigName,
passwordFileName, accessFileName);
cs = data.jmxConnectorServer;
url = data.jmxRemoteURL;
- log.config("initialize",
- Agent.getText("jmxremote.ConnectorBootstrap.initialize.ready",
+ log.config("startRemoteConnectorServer",
+ Agent.getText("jmxremote.ConnectorBootstrap.ready",
url.toString()));
} catch (Exception e) {
throw new AgentConfigurationError(AGENT_EXCEPTION, e, e.toString());
@@ -442,7 +481,7 @@
// Remote connector server started but unable to export remote
// connector address and associated configuration properties to
// the instrumentation buffer - non-fatal error.
- log.debug("initialize", e);
+ log.debug("startRemoteConnectorServer", e);
}
return cs;
}
@@ -517,9 +556,9 @@
try {
if (fs.supportsFileSecurity(file)) {
if (!fs.isAccessUserOnly(file)) {
- final String msg = Agent.getText("jmxremote.ConnectorBootstrap.initialize.password.readonly",
+ final String msg = Agent.getText("jmxremote.ConnectorBootstrap.password.readonly",
passwordFileName);
- log.config("initialize", msg);
+ log.config("startRemoteConnectorServer", msg);
throw new AgentConfigurationError(PASSWORD_FILE_ACCESS_NOT_RESTRICTED,
passwordFileName);
}
@@ -560,9 +599,9 @@
if (fs.supportsFileSecurity(file)) {
if (!fs.isAccessUserOnly(file)) {
final String msg = Agent.getText(
- "jmxremote.ConnectorBootstrap.initialize.file.readonly",
+ "jmxremote.ConnectorBootstrap.file.readonly",
restrictedFileName);
- log.config("initialize", msg);
+ log.config("startRemoteConnectorServer", msg);
throw new AgentConfigurationError(
FILE_ACCESS_NOT_RESTRICTED, restrictedFileName);
}
@@ -662,6 +701,7 @@
private static JMXConnectorServerData exportMBeanServer(
MBeanServer mbs,
int port,
+ int rmiPort,
boolean useSsl,
boolean useRegistrySsl,
String sslConfigFileName,
@@ -679,7 +719,7 @@
* IDs. */
System.setProperty("java.rmi.server.randomIDs", "true");
- JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+ JMXServiceURL url = new JMXServiceURL("rmi", null, rmiPort);
Map<String, Object> env = new HashMap<>();
@@ -736,7 +776,6 @@
}
}
- final Registry registry;
if (useRegistrySsl) {
registry =
new SingleEntryRegistry(port, csf, ssf,
@@ -747,10 +786,12 @@
"jmxrmi", exporter.firstExported);
}
- JMXServiceURL remoteURL = new JMXServiceURL(
- "service:jmx:rmi:///jndi/rmi://" + url.getHost() + ":" +
- ((UnicastRef) ((RemoteObject) registry).getRef()).getLiveRef().getPort() +
- "/jmxrmi");
+
+ int registryPort =
+ ((UnicastRef) ((RemoteObject) registry).getRef()).getLiveRef().getPort();
+ String jmxUrlStr = String.format("service:jmx:rmi:///jndi/rmi://%s:%d/jmxrmi",
+ url.getHost(), registryPort);
+ JMXServiceURL remoteURL = new JMXServiceURL(jmxUrlStr);
/* Our exporter remembers the first object it was asked to
export, which will be an RMIServerImpl appropriate for
--- a/jdk/src/share/classes/sun/management/resources/agent.properties Sun Feb 26 17:25:42 2012 +0000
+++ b/jdk/src/share/classes/sun/management/resources/agent.properties Mon Feb 27 15:21:18 2012 +0400
@@ -1,6 +1,6 @@
#
#
-# Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -43,8 +43,9 @@
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.jmxremote.port = Invalid com.sun.management.jmxremote.port number
+agent.err.invalid.jmxremote.rmi.port = Invalid com.sun.management.jmxremote.rmi.port number
agent.err.file.not.set = File not specified
agent.err.file.not.readable = File not readable
@@ -78,11 +79,11 @@
agent.err.snmp.adaptor.start.failed = Failed to start SNMP adaptor with address
agent.err.snmp.mib.init.failed = Failed to initialize SNMP MIB with error
-jmxremote.ConnectorBootstrap.initialize = Starting JMX Connector Server:
-jmxremote.ConnectorBootstrap.initialize.noAuthentication = No Authentication
-jmxremote.ConnectorBootstrap.initialize.ready = JMX Connector ready at: {0}
-jmxremote.ConnectorBootstrap.initialize.password.readonly = Password file read access must be restricted: {0}
-jmxremote.ConnectorBootstrap.initialize.file.readonly = File read access must be restricted: {0}
+jmxremote.ConnectorBootstrap.starting = Starting JMX Connector Server:
+jmxremote.ConnectorBootstrap.noAuthentication = No Authentication
+jmxremote.ConnectorBootstrap.ready = JMX Connector ready at: {0}
+jmxremote.ConnectorBootstrap.password.readonly = Password file read access must be restricted: {0}
+jmxremote.ConnectorBootstrap.file.readonly = File read access must be restricted: {0}
jmxremote.AdaptorBootstrap.getTargetList.processing = Processing ACL
jmxremote.AdaptorBootstrap.getTargetList.adding = Adding target: {0}
--- a/jdk/test/sun/management/AgentCheckTest.java Sun Feb 26 17:25:42 2012 +0000
+++ b/jdk/test/sun/management/AgentCheckTest.java Mon Feb 27 15:21:18 2012 +0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -35,10 +35,10 @@
public static void main(String[] args){
String [][] testStrings = {
{"agent.err.error", "", ""},
- {"jmxremote.ConnectorBootstrap.initialize", "", ""},
- {"jmxremote.ConnectorBootstrap.initialize.noAuthentication", "", ""},
- {"jmxremote.ConnectorBootstrap.initialize.ready", "Phony JMXServiceURL", ""},
- {"jmxremote.ConnectorBootstrap.initialize.password.readonly", "Phony passwordFileName", ""},
+ {"jmxremote.ConnectorBootstrap.starting", "", ""},
+ {"jmxremote.ConnectorBootstrap.noAuthentication", "", ""},
+ {"jmxremote.ConnectorBootstrap.ready", "Phony JMXServiceURL", ""},
+ {"jmxremote.ConnectorBootstrap.password.readonly", "Phony passwordFileName", ""},
{"jmxremote.AdaptorBootstrap.getTargetList.processing", "", ""},
{"jmxremote.AdaptorBootstrap.getTargetList.adding", "Phony target", ""},
{"jmxremote.AdaptorBootstrap.getTargetList.starting", "", ""},
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/management/jmxremote/startstop/JMXStartStopDoSomething.java Mon Feb 27 15:21:18 2012 +0400
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.RandomAccessFile;
+
+public class JMXStartStopDoSomething {
+
+
+ public void doSomething(){
+ try {
+ for (int i=0; i < 10; ++i) {
+ RandomAccessFile f = new RandomAccessFile("/dev/null","r");
+ int n = f.read();
+ f.close();
+ }
+
+ } catch (Throwable e) {
+ System.err.println("Something bad happens:" +e);
+ }
+ }
+
+ public static void main(String args[]) throws Exception {
+ System.err.println("main enter");
+ int count = 1;
+ while(count > 0) {
+ JMXStartStopDoSomething p = new JMXStartStopDoSomething();
+ p.doSomething();
+ Thread.sleep(1);
+ }
+ // System.err.println("main exit");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.java Mon Feb 27 15:21:18 2012 +0400
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.rmi.registry.LocateRegistry;
+import java.rmi.registry.Registry;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.management.*;
+import javax.management.remote.*;
+
+import sun.management.AgentConfigurationError;
+import sun.management.jmxremote.ConnectorBootstrap;
+
+public class JMXStartStopTest {
+
+ static boolean verbose = false;
+
+ static void dbg_print(String msg){
+ if (verbose) {
+ System.err.println("DBG: " +msg);
+ }
+ }
+
+ static void dbg_print(String msg, Throwable ex){
+ if (verbose) {
+ System.err.println("DBG: " + msg + " " + ex.getMessage() );
+ ex.printStackTrace(System.err);
+ }
+ }
+
+ public static int listMBeans(MBeanServerConnection server, ObjectName pattern, QueryExp query)
+ throws Exception {
+
+ Set names = server.queryNames(pattern,query);
+ for (Iterator i=names.iterator(); i.hasNext(); ) {
+ ObjectName name = (ObjectName)i.next();
+ MBeanInfo info = server.getMBeanInfo(name);
+ dbg_print("Got MBean: " + name);
+
+ MBeanAttributeInfo[] attrs = info.getAttributes();
+ if (attrs == null)
+ continue;
+
+ for (int j=0; j<attrs.length; j++) {
+ if (attrs[j].isReadable()) {
+ Object o = server.getAttribute(name,attrs[j].getName());
+ }
+ }
+ }
+ return names.size();
+ }
+
+
+ public void run_local(String strPid)
+ throws Exception {
+
+ String jmxUrlStr = null;
+ int pid = Integer.parseInt(strPid);
+
+ try {
+ jmxUrlStr = sun.management.ConnectorAddressLink.importFrom(pid);
+ dbg_print("Local Service URL: " +jmxUrlStr);
+ if ( jmxUrlStr == null ) {
+ throw new Exception("No Service URL. Local agent not started?");
+ }
+
+ JMXServiceURL url = new JMXServiceURL(jmxUrlStr);
+ Map m = new HashMap();
+
+ JMXConnector c = JMXConnectorFactory.connect(url,m);
+
+ MBeanServerConnection conn = c.getMBeanServerConnection();
+ ObjectName pattern = new ObjectName("java.lang:type=Memory,*");
+
+ int count = listMBeans(conn,pattern,null);
+ if (count == 0)
+ throw new Exception("Expected at least one matching "+ "MBean for "+pattern);
+
+
+ } catch (IOException e) {
+ dbg_print("Cannot find process : " + pid);
+ throw e;
+ }
+ }
+
+ public void run(String args[]) throws Exception {
+
+ dbg_print("RmiRegistry lookup...");
+
+ int port = 4567;
+ if (args != null && args.length > 0) {
+ port = Integer.parseInt(args[0]);
+ }
+ dbg_print("Using port: " + port);
+
+ int rmiPort = 0;
+ if (args != null && args.length > 1) {
+ rmiPort = Integer.parseInt(args[1]);
+ }
+ dbg_print("Using rmi port: " + rmiPort);
+
+ Registry registry = LocateRegistry.getRegistry(port);
+
+ // "jmxrmi"
+ String[] relist = registry.list();
+ for (int i = 0; i < relist.length; ++i) {
+ dbg_print("Got registry: " + relist[i]);
+ }
+
+ String jmxUrlStr = (rmiPort != 0) ?
+ String.format("service:jmx:rmi://localhost:%d/jndi/rmi://localhost:%d/jmxrmi", rmiPort, port) :
+ String.format("service:jmx:rmi:///jndi/rmi://localhost:%d/jmxrmi",port);
+
+ JMXServiceURL url = new JMXServiceURL(jmxUrlStr);
+ Map m = new HashMap();
+
+ JMXConnector c = JMXConnectorFactory.connect(url,m);
+
+ MBeanServerConnection conn = c.getMBeanServerConnection();
+ ObjectName pattern = new ObjectName("java.lang:type=Memory,*");
+
+ int count = listMBeans(conn,pattern,null);
+ if (count == 0)
+ throw new Exception("Expected at least one matching "+ "MBean for "+pattern);
+ }
+
+
+ public static void main(String args[]) {
+ JMXStartStopTest manager = new JMXStartStopTest();
+ try {
+ if (args!=null && args[0].equals("local")) {
+ manager.run_local(args[1]);
+ } else {
+ manager.run(args);
+ }
+ } catch (RuntimeException r) {
+ dbg_print("No connection: ", r);
+ System.out.println("NO_CONN");
+ System.exit(1);
+ } catch (Throwable t) {
+ dbg_print("No connection: ", t);
+ System.out.println("NO_CONN");
+ System.exit(2);
+ }
+ System.out.println("OK_CONN");
+ System.exit(0);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.sh Mon Feb 27 15:21:18 2012 +0400
@@ -0,0 +1,603 @@
+#!/bin/sh
+
+# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+
+# @test
+# @bug 7110104
+# @build JMXStartStopTest JMXStartStopDoSomething
+# @run shell JMXStartStopTest.sh --jtreg --no-compile
+# @summary No word Failed expected in the test output
+
+_verbose=no
+_server=no
+_jtreg=no
+_compile=yes
+_testsuite="01,02,03,04,05,06,07,08,09,10,11,12,13"
+_port_one=50234
+_port_two=50235
+
+
+_testclasses=".classes"
+_testsrc=`pwd`
+
+_logname=".classes/JMXStartStopTest_output.txt"
+
+
+_compile(){
+
+ if [ ! -e ${_testclasses} ]
+ then
+ mkdir -p ${_testclasses}
+ fi
+
+ rm -f ${_testclasses}/JMXStartStopTest.class
+
+ # Compile testcase
+ ${TESTJAVA}/bin/javac -d ${_testclasses} JMXStartStopDoSomething.java JMXStartStopTest.java
+
+ if [ ! -e ${_testclasses}/JMXStartStopTest.class ]
+ then
+ echo "ERROR: Can't compile"
+ exit -1
+ fi
+}
+
+_app_start(){
+
+ if [ "${_verbose}" = "yes" ]
+ then
+ echo "RUN: ${TESTJAVA}/bin/java -server $* -cp ${_testclasses} JMXStartStopDoSomething "
+ fi
+ ${TESTJAVA}/bin/java -server $* -cp ${_testclasses} JMXStartStopDoSomething >> ${_logname} 2>&1 &
+ sleep 1
+
+ pid=`_get_pid`
+ if [ "x${pid}" = "x" ]
+ then
+ echo "ERROR: Test app not started"
+ exit -1
+ fi
+
+}
+
+_get_pid(){
+ ${TESTJAVA}/bin/jps | sed -n "/JMXStartStopDoSomething/s/ .*//p"
+}
+
+_app_stop(){
+ pid=`_get_pid`
+ if [ "x${pid}" != "x" ]
+ then
+ kill $pid
+ fi
+
+ # Stop on first failed test under jtreg
+ if [ "x$1" = "xFailed" -a "${_jtreg}" = "yes" ]
+ then
+ exit -1
+ fi
+}
+
+testme(){
+ ${TESTJAVA}/bin/java -cp ${_testclasses} JMXStartStopTest $*
+}
+
+
+_jcmd(){
+ if [ "${_verbose}" = "yes" ]
+ then
+ echo "RUN: ${TESTJAVA}/bin/jcmd JMXStartStopDoSomething $*"
+ ${TESTJAVA}/bin/jcmd JMXStartStopDoSomething $*
+ else
+ ${TESTJAVA}/bin/jcmd JMXStartStopDoSomething $* > /dev/null 2>/dev/null
+ fi
+}
+
+_echo(){
+ echo "$*"
+ echo "$*" >> ${_logname}
+}
+
+# ============= TESTS ======================================
+
+test_01(){
+# Run an app with JMX enabled stop it and
+# restart on other port
+
+ _echo "**** Test one ****"
+
+ _app_start -Dcom.sun.management.jmxremote.port=$1 \
+ -Dcom.sun.management.jmxremote.authenticate=false \
+ -Dcom.sun.management.jmxremote.ssl=false
+
+ res1=`testme $1`
+
+ _jcmd ManagementAgent.stop
+
+ res2=`testme $1`
+
+ _jcmd ManagementAgent.start jmxremote.port=$2
+
+ res3=`testme $2`
+
+
+ if [ "${res1}" = "OK_CONN" -a "${res2}" = "NO_CONN" -a "${res3}" = "OK_CONN" ]
+ then
+ _echo "Passed"
+ else
+ _echo "Failed r1(OK):${res1} r2(NO):${res2} r3(OK):${res3}"
+ _app_stop "Failed"
+ fi
+
+ _app_stop
+
+}
+
+test_02(){
+# Run an app without JMX enabled
+# start JMX by jcmd
+
+_echo "**** Test two ****"
+_app_start
+
+_jcmd ManagementAgent.start jmxremote.port=$1 jmxremote.authenticate=false jmxremote.ssl=false
+
+res1=`testme $1`
+
+if [ "${res1}" = "OK_CONN" ]
+then
+ _echo "Passed"
+else
+ _echo "Failed r1(OK):${res1}"
+ _app_stop "Failed"
+fi
+
+_app_stop
+
+}
+
+test_03(){
+# Run an app without JMX enabled
+# start JMX by jcmd on one port than on other one
+
+_echo "**** Test three ****"
+_app_start
+
+_jcmd ManagementAgent.start jmxremote.port=$1 jmxremote.authenticate=false jmxremote.ssl=false
+
+# Second agent shouldn't start
+_jcmd ManagementAgent.start jmxremote.port=$2 jmxremote.authenticate=false jmxremote.ssl=false
+
+# First agent should connect
+res1=`testme $1`
+
+if [ "${res1}" = "OK_CONN" ]
+then
+ _echo "Passed $1"
+else
+ _echo "Failed r1(NO):${res1}"
+ _app_stop "Failed"
+fi
+
+#Second agent shouldn't connect
+res1=`testme $2`
+
+if [ "${res1}" = "NO_CONN" ]
+then
+ _echo "Passed $2"
+else
+ _echo "Failed r1(OK):${res1}"
+fi
+
+_app_stop
+}
+
+test_04(){
+# Run an app without JMX enabled
+# start JMX by jcmd on one port, specify rmi port explicitly
+
+_echo "**** Test four ****"
+_app_start
+
+_jcmd ManagementAgent.start jmxremote.port=$1 jmxremote.rmi.port=$2 jmxremote.authenticate=false jmxremote.ssl=false
+
+# First agent should connect
+res1=`testme $1 $2`
+
+if [ "${res1}" = "OK_CONN" ]
+then
+ _echo "Passed $1 $2"
+else
+ _echo "Failed r1(NO):${res1}"
+ _app_stop "Failed"
+fi
+
+_app_stop
+}
+
+test_05(){
+# Run an app without JMX enabled, it will enable local server
+# but should leave remote server disabled
+
+_echo "**** Test five ****"
+_app_start
+
+_jcmd ManagementAgent.start jmxremote=1
+
+# First agent should connect
+res1=`testme $1`
+
+if [ "${res1}" = "NO_CONN" ]
+then
+ _echo "Passed $1 $2"
+else
+ _echo "Failed r1(OK):${res1}"
+ _app_stop "Failed"
+fi
+
+_app_stop
+}
+
+test_06(){
+# Run an app without JMX enabled
+# start JMX by jcmd on one port, specify rmi port explicitly
+# attempt to start it again
+# 1) with the same port
+# 2) with other port
+# 3) attempt to stop it twice
+# Check for valid messages in the output
+
+_echo "**** Test six ****"
+_app_start
+
+_jcmd ManagementAgent.start jmxremote.port=$1 jmxremote.authenticate=false jmxremote.ssl=false
+
+# First agent should connect
+res1=`testme $1 $2`
+
+if [ "${res1}" = "OK_CONN" ]
+then
+ _echo "Passed $1 $2"
+else
+ _echo "Failed r1(NO):${res1}"
+ _app_stop "Failed"
+fi
+
+_jcmd ManagementAgent.start jmxremote.port=$1 jmxremote.authenticate=false jmxremote.ssl=false
+
+_jcmd ManagementAgent.start jmxremote.port=$2 jmxremote.authenticate=false jmxremote.ssl=false
+
+_jcmd ManagementAgent.stop
+
+_jcmd ManagementAgent.stop
+
+_jcmd ManagementAgent.start jmxremote.port=22 jmxremote.rmi.port=$2 jmxremote.authenticate=false jmxremote.ssl=false
+
+_app_stop
+}
+
+test_07(){
+# Run an app without JMX enabled, but with some properties set
+# in command line.
+# make sure these properties overriden corectly
+
+_echo "**** Test seven ****"
+
+_app_start -Dcom.sun.management.jmxremote.authenticate=false \
+ -Dcom.sun.management.jmxremote.ssl=true
+
+res1=`testme $1`
+
+_jcmd ManagementAgent.start jmxremote.port=$2 jmxremote.authenticate=false jmxremote.ssl=false
+
+res2=`testme $2`
+
+
+if [ "${res1}" = "NO_CONN" -a "${res2}" = "OK_CONN" ]
+then
+ echo "Passed"
+else
+ _echo "Failed r1(NO):${res1} r2(OK):${res2}"
+ _app_stop "Failed"
+fi
+
+_app_stop
+}
+
+test_08(){
+# Run an app with JMX enabled and with some properties set
+# in command line.
+# stop JMX agent and then start it again with different property values
+# make sure these properties overriden corectly
+
+_echo "**** Test eight ****"
+
+_app_start -Dcom.sun.management.jmxremote.port=$1 \
+ -Dcom.sun.management.jmxremote.authenticate=false \
+ -Dcom.sun.management.jmxremote.ssl=true
+
+res1=`testme $1`
+
+_jcmd ManagementAgent.stop
+
+res2=`testme $1`
+
+_jcmd ManagementAgent.start jmxremote.port=$2 jmxremote.authenticate=false jmxremote.ssl=false
+
+res3=`testme $2`
+
+
+if [ "${res1}" = "NO_CONN" -a "${res2}" = "NO_CONN" -a "${res3}" = "OK_CONN" ]
+then
+ _echo "Passed"
+else
+ _echo "Failed r1(NO):${res1} r2(NO):${res2} r3(OK):${res3}"
+ _app_stop "Failed"
+fi
+
+_app_stop
+}
+
+test_09(){
+# Run an app with JMX enabled and with some properties set
+# in command line.
+# stop JMX agent and then start it again with different property values
+# specifing some property in management config file and some of them
+# in command line
+# make sure these properties overriden corectly
+
+_echo "**** Test nine ****"
+
+_app_start -Dcom.sun.management.config.file=${_testsrc}/management_cl.properties \
+ -Dcom.sun.management.jmxremote.authenticate=false
+
+res1=`testme $1`
+
+_jcmd ManagementAgent.stop
+
+res2=`testme $1`
+
+_jcmd ManagementAgent.start config.file=${_testsrc}/management_jcmd.properties \
+ jmxremote.authenticate=false jmxremote.port=$2
+
+res3=`testme $2`
+
+if [ "${res1}" = "NO_CONN" -a "${res2}" = "NO_CONN" -a "${res3}" = "OK_CONN" ]
+then
+ _echo "Passed"
+else
+ _echo "Failed r1(NO):${res1} r2(NO):${res2} r3(OK):${res3}"
+ _app_stop "Failed"
+fi
+
+_app_stop
+}
+
+test_10(){
+# Run an app with JMX enabled and with some properties set
+# in command line.
+# stop JMX agent and then start it again with different property values
+# stop JMX agent again and then start it without property value
+# make sure these properties overriden corectly
+
+_echo "**** Test ten ****"
+
+_app_start -Dcom.sun.management.jmxremote.port=$1 \
+ -Dcom.sun.management.jmxremote.authenticate=false \
+ -Dcom.sun.management.jmxremote.ssl=true
+
+res1=`testme $1`
+
+_jcmd ManagementAgent.stop
+_jcmd ManagementAgent.start jmxremote.ssl=false jmxremote.port=$1
+
+
+res2=`testme $1`
+
+_jcmd ManagementAgent.stop
+_jcmd ManagementAgent.start jmxremote.port=$1
+
+res3=`testme $1`
+
+if [ "${res1}" = "NO_CONN" -a "${res2}" = "OK_CONN" -a "${res3}" = "NO_CONN" ]
+then
+ _echo "Passed"
+else
+ _echo "Failed r1(NO):${res1} r2(OK):${res2} r3(NO):${res3}"
+ _app_stop "Failed"
+fi
+
+_app_stop
+}
+
+test_11(){
+# Run an app with JMX enabled
+# stop remote agent
+# make sure local agent is not affected
+
+_echo "**** Test eleven ****"
+
+_app_start -Dcom.sun.management.jmxremote.port=$2 \
+ -Dcom.sun.management.jmxremote.authenticate=false \
+ -Dcom.sun.management.jmxremote.ssl=false
+
+res1=`testme $2`
+
+_jcmd ManagementAgent.stop
+
+pid=`${TESTJAVA}/bin/jps | sed -n "/JMXStartStopDoSomething/s/ .*//p"`
+res2=`testme local ${pid}`
+
+if [ "${res1}" = "OK_CONN" -a "${res2}" = "OK_CONN" ]
+then
+ _echo "Passed"
+else
+ _echo "Failed r1(OK):${res1} r2(OK):${res2}"
+ _app_stop "Failed"
+fi
+
+_app_stop
+}
+
+test_12(){
+# Run an app with JMX disabled
+# start local agent only
+
+_echo "**** Test twelve ****"
+
+_app_start
+
+res1=`testme $1`
+
+_jcmd ManagementAgent.start_local
+
+pid=`_get_pid`
+if [ "x${pid}" = "x" ]
+then
+ res2="NO_CONN"
+else
+ res2=`testme local ${pid}`
+fi
+
+if [ "${res1}" = "NO_CONN" -a "${res2}" = "OK_CONN" ]
+then
+ _echo "Passed"
+else
+ _echo "Failed r1(NO):${res1} r2(OK):${res2}"
+ _app_stop "Failed"
+fi
+
+_app_stop
+}
+
+test_13(){
+# Run an app with -javaagent make sure it works as expected - system properties are ignored
+
+_echo "**** Test 13 ****"
+
+AGENT="${TESTJAVA}/jre/lib/management-agent.jar"
+if [ ! -f ${AGENT} ]
+ then
+ AGENT="${TESTJAVA}/lib/management-agent.jar"
+fi
+
+_app_start -javaagent:${AGENT}=com.sun.management.jmxremote.port=$1,com.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false
+
+res1=`testme $1`
+
+if [ "${res1}" = "NO_CONN" ]
+then
+ _echo "Passed"
+else
+ _echo "Failed r1(NO):${res1}"
+ _app_stop "Failed"
+fi
+
+_app_stop
+}
+
+
+#============== Server tests =======================
+
+server_test_01(){
+
+ _echo "**** Server test one ****"
+
+ _app_start -Dcom.sun.management.jmxremote.port=$1 \
+ -Dcom.sun.management.jmxremote.rmi.port=$2 \
+ -Dcom.sun.management.jmxremote.authenticate=false \
+ -Dcom.sun.management.jmxremote.ssl=false
+
+}
+
+
+# ============= MAIN =======================================
+
+if [ "x${TESTJAVA}" = "x" ]
+then
+ echo "TESTJAVA env have to be set"
+ exit
+fi
+
+if [ ! -x "${TESTJAVA}/bin/jcmd" ]
+then
+ echo "${TESTJAVA}/bin/jcmd"
+ echo "Doesn't exist or not an executable"
+
+ if [ "${_verbose}" != "yes" ]
+ then
+ exit
+ fi
+fi
+
+
+#------------------------------------------------------------------------------
+# reading parameters
+
+for parm in "$@"
+do
+ case $parm in
+ --verbose) _verbose=yes ;;
+ --server) _server=yes ;;
+ --jtreg) _jtreg=yes ;;
+ --no-compile) _compile=no ;;
+ --testsuite=*) _testsuite=`_echo $parm | sed "s,^--.*=\(.*\),\1,"` ;;
+ --port-one=*) _port_one=`_echo $parm | sed "s,^--.*=\(.*\),\1,"` ;;
+ --port-two=*) _port_two=`_echo $parm | sed "s,^--.*=\(.*\),\1,"` ;;
+ *)
+ echo "Undefined parameter $parm. Try --help for help"
+ exit
+ ;;
+ esac
+done
+
+if [ ${_compile} = "yes" ]
+then
+ _compile
+fi
+
+if [ ${_jtreg} = "yes" ]
+then
+ _testclasses=${TESTCLASSES}
+ _testsrc=${TESTSRC}
+ _logname="JMXStartStopTest_output.txt"
+fi
+
+rm -f ${_logname}
+
+# Start server mode tests
+# All of them require manual cleanup
+if [ "x${_server}" = "xyes" ]
+then
+
+ server_test_01 ${_port_one} ${_port_two}
+
+else
+
+ # Local mode tests
+ for i in `echo ${_testsuite} | sed -e "s/,/ /g"`
+ do
+ test_${i} ${_port_one} ${_port_two}
+ done
+
+fi
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/management/jmxremote/startstop/REMOTE_TESTING.txt Mon Feb 27 15:21:18 2012 +0400
@@ -0,0 +1,11 @@
+1. Setup two hosts
+2. Make sure tcp connection between them works
+3. run tcpdump -i <interface> host <host2_name> and 'tcp[13] & 2!=0'
+ on host 1
+4. run JMXStartStopTest.sh --server on host2
+5. run jconsole on host1
+6. connect jconsole to host2:50234
+ Make sure jconsole works
+ Make sure only host2.50234 and host2.50235 appears in tcpdump output.
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/management/jmxremote/startstop/management_cl.properties Mon Feb 27 15:21:18 2012 +0400
@@ -0,0 +1,2 @@
+com.sun.management.jmxremote.ssl=true
+com.sun.management.internal.read_from_config_file_cl=true
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/management/jmxremote/startstop/management_jcmd.properties Mon Feb 27 15:21:18 2012 +0400
@@ -0,0 +1,3 @@
+com.sun.management.jmxremote.ssl=false
+jmxremote.authenticate=true
+com.sun.management.internal.read_from_config_file_jcmd=true