java - 如何创建一个简单的 JMX 客户端?

标签 java rmi jmx

假设我们在服务器端有带有预定义 API 的 MBean。我想直接使用 API 从客户端计算机调用该 MBean。如何创建简单的 JMX 客户端以通过 RMI 获取远程 java 对象?

最佳答案

使用

private CacheMBean<String, Message> messageStorage = newJmxClient(  
    CacheMBean.class,   
    "com.my.company:type=cache,name=MessageCacheImpl",   
    "service:jmx:rmi:///jndi/rmi://<host>:<port>/karaf-root",   
    "smx",   
    "smx");
...
Message message = messageStorage.get(messageId);

实现

import com.google.common.collect.ImmutableMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.util.Map;

import javax.management.InstanceAlreadyExistsException;
import javax.management.JMX;
import javax.management.MBeanServer;
import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.StandardMBean;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

public final class JmxUtils {

    private static final Logger LOG = LoggerFactory.getLogger(JmxUtils.class);

    private JmxUtils() {
    }

    public static <T> T newJmxClient(Class<T> clazz, String objectName, String serviceUrl) {
        return newJmxClient(clazz, objectName, serviceUrl, null, null);
    }

    public static <T> T newJmxClient(Class<T> clazz, String objectName, String serviceUrl, final String user, final String pass) {
        try {
            JMXServiceURL jmxServiceUrl = new JMXServiceURL(serviceUrl);
            Map<String, ?> env = user == null ? null : ImmutableMap.of(JMXConnector.CREDENTIALS, new String[] {user, pass});
            JMXConnector jmxc = JMXConnectorFactory.connect(jmxServiceUrl, env);
            MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
            ObjectName mbeanName = new ObjectName(objectName);
            return JMX.newMBeanProxy(mbsc, mbeanName, clazz, true);
        } catch (IOException | MalformedObjectNameException e) {
            throw new RuntimeException("Can not create client for remote JMX " + serviceUrl, e);
        }
    }

    /**
     * @param objName
     *            domain:type=value[,name=value]
     * @param implementation
     * @param mbeanInterface
     * @see ObjectName
     * @see StandardMBean
     */
    public static <I> ObjectInstance registerMBean(String objName, I implementation, Class<I> mbeanInterface) {
        int counter = 0;
        String uniqueSuffix = "";
        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
        while (true) {
            try {
                ObjectName name = new ObjectName(objName + uniqueSuffix);
                StandardMBean mbean = new StandardMBean(implementation, mbeanInterface);
                return mbs.registerMBean(mbean, name);
            } catch (InstanceAlreadyExistsException e) {
                LOG.trace("JMX instance exists, trying next available", e);
                uniqueSuffix = "" + ++counter;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }

    /**
     * @param objName
     * @see ObjectName
     */
    public static void unregisterMBean(String objName) {
        try {
            final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
            final ObjectName name = new ObjectName(objName);
            mbs.unregisterMBean(name);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

关于java - 如何创建一个简单的 JMX 客户端?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36201654/

相关文章:

java - 构建随机排列列表的最有效方法

java - 从本地机器上的多个线程通过 RMI 调用线程安全方法是否安全?

java - 计算范围内的素数 RMI 版本与并发版本

java - 使用 jconsole 连接到没有 jmx 参数的 java 进程

java - 在 JMX 中设置每用户或每组安全性

命令行中的 Java 执行因 JMX 错误而失败

java - 在启动时使用 cmd 运行 sh 文件 - 能够看到它

java - 泛型扩展而不扩展 - 如何做

java - 无法在 Windows 7 32 位控制面板中设置 JRE 参数

java.rmi.ServerException : RemoteException occurred in server thread (ClassNotFoundException)