使用相同的连接环境连接启用 SSL 和禁用 SSL 的 JMX 远程代理
Connecting to both SSL enabled and SSL disabled JMX remote agents with the same connection environment
我有一个程序可以监视来自 JMX 远程代理的进程性能数据。
其中一些远程代理配置为使用 SSL,将 JVM 参数 com.sun.management.jmxremote.ssl
和 com.sun.management.jmxremote.registry.ssl
设置为 true。其他不受 SSL 保护,将这些 JVM 参数设置为 false。
我通过以下方法使用 JMXConnector 连接到这些远程代理:
private JMXConnector setUpConnection(String server, int jmxPort) {
try {
Registry r = LocateRegistry.getRegistry(server, jmxPort);
HashMap<String, Object> env = new HashMap<String, Object>();
String[] credentials = {"username", "password"};
env.put(JMXConnector.CREDENTIALS, credentials);
env.put("com.sun.jndi.rmi.factory.socket", new SslRMIClientSocketFactory()); // uncomment if needed
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + server + ":" + jmxPort + "/jmxrmi");
return JMXConnectorFactory.newJMXConnector(url, env);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
这种方法能够连接到我的 SSL 安全远程代理,但不能连接到我不使用 SSL 的远程代理。对于后一种情况,我得到的错误消息是:
java.io.IOException: Failed to retrieve RMIServer stub: javax.naming.CommunicationException [Root exception is java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is:
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake]
如果我删除以下行:
env.put("com.sun.jndi.rmi.factory.socket", new SslRMIClientSocketFactory());
然后情况正好相反,我现在可以连接到未配置为使用 SSL 但无法连接到 SSL 远程代理的远程代理。在这种情况下,我为 SSL 配置的远程代理收到的错误消息是:
java.io.IOException: Failed to retrieve RMIServer stub: javax.naming.CommunicationException [Root exception is java.rmi.ConnectIOException: non-JRMP server at remote endpoint]
如果我没有将 JVM 参数 com.sun.management.jmxremote.registry.ssl
设置为 true 那么我可以在我省略时连接到我的所有远程代理:
env.put("com.sun.jndi.rmi.factory.socket", new SslRMIClientSocketFactory());
然而,将此 属性 设置为 false 不是一个选项。
我想不惜一切代价避免使用两种不同的连接环境,一种用于 SSL 远程代理,另一种用于非 SSL 远程代理。我也无法将所有远程代理迁移到配置 SSL。
我们的一个项目使用了下面的代码片段来获取 JMXConnection。
private String provider = "";
private String jvmPort = "";
private JMXServiceURL jmxService = null;
private JMXConnector jmxConnector = null;
private RMIConnector rmiConnector = null;
private MBeanServerConnection beanServerConn = null;
.........
public boolean connectToJVM(String jvmURL, String user, String pass)
{
boolean flag = false;
beanServerConn = null ;
try
{
jmxService = new JMXServiceURL(jvmURL);
Map environment = new HashMap();
int jmxconnect_timeout = 30000;
environment.put("jmx.remote.protocol.provider.pkgs",provider);
if (jmxconnect_timeout > 0) {
environment.put("jmx.remote.x.request.waiting.timeout", Long.toString(jmxconnect_timeout));
}
boolean registrySSL = false;
if(user.equalsIgnoreCase("none")|| (pass.equalsIgnoreCase("none")))
{
try
{
jmxConnector = JMXConnectorFactory.connect(jmxService,environment);
}
catch(IOException ioe)
{
registrySSL = true;
}
}
else
{
String [] credentials={user,pass};
environment.put(JMXConnector.CREDENTIALS, credentials);
try
{
jmxConnector = JMXConnectorFactory.connect(jmxService,environment);
}
catch(IOException ioe)
{
registrySSL = true;
}
}
if(registrySSL)
{
/*
This if block runs when the "management.properties" file contains
com.sun.management.jmxremote.registry.ssl=true
This block of code is applicable both JDK5.0 & 6.0
Only for JDK6.0
===============
environment.put("com.sun.jndi.rmi.factory.socket", new SslRMIClientSocketFactory());
beanServerConn = jmxConnector.getMBeanServerConnection();
*/
try {
MySslRMIClientSocketFactory csf = new MySslRMIClientSocketFactory(targetHost, Integer.parseInt(jvmPort), (int)jmxconnect_timeout);
Registry registry = LocateRegistry.getRegistry(targetHost, Integer.parseInt(jvmPort), csf);
RMIServer stub = (RMIServer) registry.lookup(jndiName);
rmiConnector = new RMIConnector(stub, environment);
rmiConnector.connect(environment);
beanServerConn = rmiConnector.getMBeanServerConnection();
} catch (Exception e) {
e.printStackTrace();
}
}
else{
beanServerConn = jmxConnector.getMBeanServerConnection();
}
if(beanServerConn == null)
{
System.out.println("Connection to JVM is not established for url : " + url);
return false;
}
else
{
flag = true;
}
}
catch(Exception ex)
{
System.out.println("Connection to JVM is not established for url : " + url);
//ex.printStackTrace();
return false;
}
return flag;
}
我有一个程序可以监视来自 JMX 远程代理的进程性能数据。
其中一些远程代理配置为使用 SSL,将 JVM 参数 com.sun.management.jmxremote.ssl
和 com.sun.management.jmxremote.registry.ssl
设置为 true。其他不受 SSL 保护,将这些 JVM 参数设置为 false。
我通过以下方法使用 JMXConnector 连接到这些远程代理:
private JMXConnector setUpConnection(String server, int jmxPort) {
try {
Registry r = LocateRegistry.getRegistry(server, jmxPort);
HashMap<String, Object> env = new HashMap<String, Object>();
String[] credentials = {"username", "password"};
env.put(JMXConnector.CREDENTIALS, credentials);
env.put("com.sun.jndi.rmi.factory.socket", new SslRMIClientSocketFactory()); // uncomment if needed
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + server + ":" + jmxPort + "/jmxrmi");
return JMXConnectorFactory.newJMXConnector(url, env);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
这种方法能够连接到我的 SSL 安全远程代理,但不能连接到我不使用 SSL 的远程代理。对于后一种情况,我得到的错误消息是:
java.io.IOException: Failed to retrieve RMIServer stub: javax.naming.CommunicationException [Root exception is java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is:
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake]
如果我删除以下行:
env.put("com.sun.jndi.rmi.factory.socket", new SslRMIClientSocketFactory());
然后情况正好相反,我现在可以连接到未配置为使用 SSL 但无法连接到 SSL 远程代理的远程代理。在这种情况下,我为 SSL 配置的远程代理收到的错误消息是:
java.io.IOException: Failed to retrieve RMIServer stub: javax.naming.CommunicationException [Root exception is java.rmi.ConnectIOException: non-JRMP server at remote endpoint]
如果我没有将 JVM 参数 com.sun.management.jmxremote.registry.ssl
设置为 true 那么我可以在我省略时连接到我的所有远程代理:
env.put("com.sun.jndi.rmi.factory.socket", new SslRMIClientSocketFactory());
然而,将此 属性 设置为 false 不是一个选项。
我想不惜一切代价避免使用两种不同的连接环境,一种用于 SSL 远程代理,另一种用于非 SSL 远程代理。我也无法将所有远程代理迁移到配置 SSL。
我们的一个项目使用了下面的代码片段来获取 JMXConnection。
private String provider = "";
private String jvmPort = "";
private JMXServiceURL jmxService = null;
private JMXConnector jmxConnector = null;
private RMIConnector rmiConnector = null;
private MBeanServerConnection beanServerConn = null;
.........
public boolean connectToJVM(String jvmURL, String user, String pass)
{
boolean flag = false;
beanServerConn = null ;
try
{
jmxService = new JMXServiceURL(jvmURL);
Map environment = new HashMap();
int jmxconnect_timeout = 30000;
environment.put("jmx.remote.protocol.provider.pkgs",provider);
if (jmxconnect_timeout > 0) {
environment.put("jmx.remote.x.request.waiting.timeout", Long.toString(jmxconnect_timeout));
}
boolean registrySSL = false;
if(user.equalsIgnoreCase("none")|| (pass.equalsIgnoreCase("none")))
{
try
{
jmxConnector = JMXConnectorFactory.connect(jmxService,environment);
}
catch(IOException ioe)
{
registrySSL = true;
}
}
else
{
String [] credentials={user,pass};
environment.put(JMXConnector.CREDENTIALS, credentials);
try
{
jmxConnector = JMXConnectorFactory.connect(jmxService,environment);
}
catch(IOException ioe)
{
registrySSL = true;
}
}
if(registrySSL)
{
/*
This if block runs when the "management.properties" file contains
com.sun.management.jmxremote.registry.ssl=true
This block of code is applicable both JDK5.0 & 6.0
Only for JDK6.0
===============
environment.put("com.sun.jndi.rmi.factory.socket", new SslRMIClientSocketFactory());
beanServerConn = jmxConnector.getMBeanServerConnection();
*/
try {
MySslRMIClientSocketFactory csf = new MySslRMIClientSocketFactory(targetHost, Integer.parseInt(jvmPort), (int)jmxconnect_timeout);
Registry registry = LocateRegistry.getRegistry(targetHost, Integer.parseInt(jvmPort), csf);
RMIServer stub = (RMIServer) registry.lookup(jndiName);
rmiConnector = new RMIConnector(stub, environment);
rmiConnector.connect(environment);
beanServerConn = rmiConnector.getMBeanServerConnection();
} catch (Exception e) {
e.printStackTrace();
}
}
else{
beanServerConn = jmxConnector.getMBeanServerConnection();
}
if(beanServerConn == null)
{
System.out.println("Connection to JVM is not established for url : " + url);
return false;
}
else
{
flag = true;
}
}
catch(Exception ex)
{
System.out.println("Connection to JVM is not established for url : " + url);
//ex.printStackTrace();
return false;
}
return flag;
}