通过mx4j实现JMXConnectorServer和JMXConnector
看了两天文档,总算对JMX有了一个整体的认识。发现使用mx4j实现JMX还是相当的轻松的。MBeans可以使用mx4j-tools中的 Xdoclet偷一下懒,让它自动的生成MBeans和Descriptions,ant有相应的支持,还是比较方便的,对于MBean接口的实现,自己写了。
对于如何产生和注册MBeans,mx4j提供了一个相当方便的工具,为什么说相当方便,是因为它真的实在是太方便了。通过写一个xml配置文件可以完成所有的工作。比起M-LET确实是强了不少。下面就是一个在MBean Server产生注册一个NamingService、JMXConnectorServer和一个自写的MBean的配置文件。
<?
xml version="1.0" encoding="UTF-8"
?>
< configuration port ="9999" >
< startup >
< create classname ="mx4j.tools.naming.NamingService" objectname ="naming:type=rmiregistry" >
< arg type ="int" > 1099 </ arg >
</ create >
< call operation ="start" objectname ="naming:type=rmiregistry" />
< object objectid ="rmi" >
< call classname ="javax.management.remote.JMXConnectorServerFactory" method ="newJMXConnectorServer" >
< arg type ="javax.management.remote.JMXServiceURL" >
< new classname ="javax.management.remote.JMXServiceURL" >
< arg type ="string" > service:jmx:rmi://localhost/jndi/rmi://localhost:1099/jmx </ arg >
</ new >
</ arg >
< arg type ="java.util.Map" />
< arg type ="javax.management.MBeanServer" />
</ call >
</ object >
< register objectname ="connectors:type=rmi,protocol=jrmp" >
< arg type ="object" refobjectid ="rmi" />
</ register >
< call method ="start" refobjectid ="rmi" />
< create classname ="nsmp.examples.mbeans.rmi.MyRemoteServiceObject" objectname ="services:type=my-remote" />
</ startup >
< shutdown >
< call operation ="stop" objectname ="services:type=my-remote" />
< call method ="stop" refobjectid ="rmi" />
< call operation ="stop" objectname ="naming:type=rmiregistry" />
< unregister objectname ="services:type=my-remote" />
< unregister objectname ="connectors:type=rmi,protocol=jrmp" />
< unregister objectname ="naming:type=rmiregistry" />
</ shutdown >
</ configuration >
< configuration port ="9999" >
< startup >
< create classname ="mx4j.tools.naming.NamingService" objectname ="naming:type=rmiregistry" >
< arg type ="int" > 1099 </ arg >
</ create >
< call operation ="start" objectname ="naming:type=rmiregistry" />
< object objectid ="rmi" >
< call classname ="javax.management.remote.JMXConnectorServerFactory" method ="newJMXConnectorServer" >
< arg type ="javax.management.remote.JMXServiceURL" >
< new classname ="javax.management.remote.JMXServiceURL" >
< arg type ="string" > service:jmx:rmi://localhost/jndi/rmi://localhost:1099/jmx </ arg >
</ new >
</ arg >
< arg type ="java.util.Map" />
< arg type ="javax.management.MBeanServer" />
</ call >
</ object >
< register objectname ="connectors:type=rmi,protocol=jrmp" >
< arg type ="object" refobjectid ="rmi" />
</ register >
< call method ="start" refobjectid ="rmi" />
< create classname ="nsmp.examples.mbeans.rmi.MyRemoteServiceObject" objectname ="services:type=my-remote" />
</ startup >
< shutdown >
< call operation ="stop" objectname ="services:type=my-remote" />
< call method ="stop" refobjectid ="rmi" />
< call operation ="stop" objectname ="naming:type=rmiregistry" />
< unregister objectname ="services:type=my-remote" />
< unregister objectname ="connectors:type=rmi,protocol=jrmp" />
< unregister objectname ="naming:type=rmiregistry" />
</ shutdown >
</ configuration >
java代码:
package nsmp.agent;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.Reader;
import java.net.Socket;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import mx4j.tools.config.ConfigurationLoader;
import nsmp.util.NsmpGlobals;
/**/ /**
* @version 1.0
* @author tower
*
* TODO write the comment of this type
*/
public class NsmpServer {
public void startup() throws Exception {
MBeanServer server = MBeanServerFactory.newMBeanServer();
ConfigurationLoader loader = new ConfigurationLoader();
server.registerMBean(loader, ObjectName.getInstance("config:service=loader"));
Reader reader = new BufferedReader(new FileReader(NsmpGlobals.NSMP_HOME + "/conf/config.xml"));
loader.startup(reader);
reader.close();
System.out.println("Start the nsmp server successfully!");
}
public void shutdown() throws Exception {
String shutdownCommand = "shutdown";
Socket socket = new Socket("127.0.0.1", 9999);
socket.getOutputStream().write(shutdownCommand.getBytes());
socket.close();
}
}
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.Reader;
import java.net.Socket;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import mx4j.tools.config.ConfigurationLoader;
import nsmp.util.NsmpGlobals;
/**/ /**
* @version 1.0
* @author tower
*
* TODO write the comment of this type
*/
public class NsmpServer {
public void startup() throws Exception {
MBeanServer server = MBeanServerFactory.newMBeanServer();
ConfigurationLoader loader = new ConfigurationLoader();
server.registerMBean(loader, ObjectName.getInstance("config:service=loader"));
Reader reader = new BufferedReader(new FileReader(NsmpGlobals.NSMP_HOME + "/conf/config.xml"));
loader.startup(reader);
reader.close();
System.out.println("Start the nsmp server successfully!");
}
public void shutdown() throws Exception {
String shutdownCommand = "shutdown";
Socket socket = new Socket("127.0.0.1", 9999);
socket.getOutputStream().write(shutdownCommand.getBytes());
socket.close();
}
}
startup方法调用配置文件的startup部分完成创建和注册,shutdown方法调用配置文件的shutdown部分释放相应的资源。通过调用 startup方法就可以起动MBeanServer提供服务了。对于shutdown开始搞了我半天startup后 ConfigurationLoader都没有创建一个侦听端口来接收shutdown命令,看了看mx4j的源码发现 ConfigurationLoader也没有发现什么特殊地方。捉摸半天终于发现了自己放了一个愚笨的错误,eclipse是用普通用户权限开的,没有办法创建侦听,改成root后一切ok。
接下就随便写了一个JMXConnector,代码:
/**/
/*
* Copyright (C) The MX4J Contributors.
* All rights reserved.
*
* This software is distributed under the terms of the MX4J License version 1.0.
* See the terms of the MX4J License in the documentation provided with this software.
*/
package nsmp.examples.mbeans.rmi;
import java.util.Map;
import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
/**/ /**
* @version $Revision: 1.3 $
*/
public class Client
{
public static void main(String[] args) throws Exception
{
JMXServiceURL address = new JMXServiceURL("service:jmx:rmi://localhost/jndi/rmi://localhost:1099/jmx");
Map creationEnv = null;
JMXConnector connector = JMXConnectorFactory.newJMXConnector(address, creationEnv);
Map connectionEnv = null;
connector.connect(connectionEnv);
MBeanServerConnection serverConnection = connector.getMBeanServerConnection();
ObjectName name = ObjectName.getInstance("services:type=my-remote");
MBeanInfo mbInfo = serverConnection.getMBeanInfo(name);
MBeanOperationInfo[] operationInfo = mbInfo.getOperations();
for (int i = 0; i < operationInfo.length; i++) {
System.out.println(operationInfo[i].getName());
}
serverConnection.invoke(name, "sayHello", new Object[] {"Tower He"}, new String[] {"java.lang.String"});
}
}
* Copyright (C) The MX4J Contributors.
* All rights reserved.
*
* This software is distributed under the terms of the MX4J License version 1.0.
* See the terms of the MX4J License in the documentation provided with this software.
*/
package nsmp.examples.mbeans.rmi;
import java.util.Map;
import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
/**/ /**
* @version $Revision: 1.3 $
*/
public class Client
{
public static void main(String[] args) throws Exception
{
JMXServiceURL address = new JMXServiceURL("service:jmx:rmi://localhost/jndi/rmi://localhost:1099/jmx");
Map creationEnv = null;
JMXConnector connector = JMXConnectorFactory.newJMXConnector(address, creationEnv);
Map connectionEnv = null;
connector.connect(connectionEnv);
MBeanServerConnection serverConnection = connector.getMBeanServerConnection();
ObjectName name = ObjectName.getInstance("services:type=my-remote");
MBeanInfo mbInfo = serverConnection.getMBeanInfo(name);
MBeanOperationInfo[] operationInfo = mbInfo.getOperations();
for (int i = 0; i < operationInfo.length; i++) {
System.out.println(operationInfo[i].getName());
}
serverConnection.invoke(name, "sayHello", new Object[] {"Tower He"}, new String[] {"java.lang.String"});
}
}
JMXConnector是通过获取一个MBeanServerConnection来实现远程调用的,运行了一下一切顺利通过。
下载:MX4JExample.rar