使用相同的连接环境连接到启用SSL和禁用SSL的JMX远程代理



我有一个程序,它监视来自JMX远程代理的进程性能数据。

其中一些远程代理被配置为使用SSL,将JVM参数com.sun.management.jmxremote.sslcom.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;
}

最新更新