ClientCommunicatorAdmin restart/Checker-run 等异常的处理

在做JMX相关的开发过程中,下面这个异常一个会遇到:
2013-7-11 15:58:05 ClientCommunicatorAdmin restart
警告: Failed to restart: java.io.IOException: Failed to get a RMI stub: javax.naming.ServiceUnavailableException [Root exception is java.rmi.ConnectException: Connection refused to host: 10.10.4.18; nested exception is: 
	java.net.ConnectException: Connection refused: connect]
2013-7-11 15:58:06 RMIConnector RMIClientCommunicatorAdmin-doStop
警告: Failed to call the method close():java.rmi.ConnectException: Connection refused to host: 10.10.4.18; nested exception is: 
	java.net.ConnectException: Connection refused: connect
2013-7-11 15:58:06 ClientCommunicatorAdmin Checker-run
警告: Failed to check connection: java.net.ConnectException: Connection refused: connect
2013-7-11 15:58:06 ClientCommunicatorAdmin Checker-run

但具体解决方式却不是显而易见的。Google了好长时间,大部分都提到了使用完Socket要及时关闭之类的,并不相关。
我大大致分析了java代码后,解决了该问题。

分析过程如下:
我们一般创建一个MBeanServerConnection的过程
JMXServiceURL serviceurl = new JMXServiceURL(url);
	JMXConnector conn = JMXConnectorFactory.connect(serviceurl, null);
					MBeanServerConnection mbsc = conn
							.getMBeanServerConnection();

此时可以用mbsc来获取相应的属性值,执行相应的方法等。但如果此时远程MBeanServer关闭了,不久就会抛出上面的异常。该异常是不受代码控制的,也就是try,catch并不能捕获。
而如果要屏蔽掉异常信息,只能从java代码入手分析。
我们在创建一个JMXConnector时使用如下方式:
JMXConnector conn = JMXConnectorFactory.connect(serviceurl, null);

此时,第二个参数可以指定一些环境信息。
当JMXConnector为RMI的时候,RMI的connect方法中有如下代码:
   final long checkPeriod = EnvHelp.getConnectionCheckPeriod(usemap);
	    communicatorAdmin = new RMIClientCommunicatorAdmin(checkPeriod);

	public RMIClientCommunicatorAdmin(long period) {
	    super(period);
	}
其super方法调用:
 public ClientCommunicatorAdmin(long period) {
	this.period = period;

	if (period > 0) {
	    checker = new Checker();

	    Thread t = new Thread(checker);
	    t.setDaemon(true);
	    t.start();
	} else
	    checker = null;
    }

从上面的代码可以看出,RMIConnector的connect方法中会创建一个RMIClientCommunicatorAdmin,该类会根据传入的env创建一个Checker,用来检测MBeanServer和Client的心跳。
其默认值
    public static long getConnectionCheckPeriod(Map env) {
	return getIntegerAttribute(env, CLIENT_CONNECTION_CHECK_PERIOD, 60000L,
				   0, Long.MAX_VALUE);
    }

大于0,所以Checker会成功创建。

通过以上分析,如果我们不需要Checker,只需要在创建Connector的时候提供env,设置相应的属性值不大于0就可以了。
所以改成如下创建方式:
JMXServiceURL serviceurl = new JMXServiceURL(url);
					Map m = new HashMap();
					m.put("jmx.remote.x.client.connection.check.period", 0L);
					conn = JMXConnectorFactory.connect(serviceurl, m);
					MBeanServerConnection mbsc = conn
							.getMBeanServerConnection();

即可成功屏蔽开头提到的异常信息。

你可能感兴趣的:(ClientCommunicatorAdmin restart/Checker-run 等异常的处理)