JMXBean entries are not showing up

2019-08-06 01:54发布

Implementation of JMXBean

PerformanceMetadata jmxBean = new PerformanceMetadata();                        
responseDocument = (Document) serviceOperation.invoke(serviceComponent,RequestDocument);
jmxBean.setNumOfRequests(1);

JMXBean class:

public class PerformanceMetadata implements PerformanceMetadataMBean{
    private int numOfRequests;
        public int getNumOfRequests() {
        return numOfRequests;
    }

    public void setNumOfRequests(int numOfRequests) {
        this.numOfRequests = numOfRequests;
    }

Class Registering the JMXBean: I call this class while booting up the server.

public class JMXBeans {
    public void registerJMXBeans() 
    {
        MBeanServer mbs = null;
        PerformanceMetadata metadataObj = null;
        ObjectName name;
        try 
        {
            metadataObj = new PerformanceMetadata();
            mbs = ManagementFactory.getPlatformMBeanServer();
            name = new ObjectName("test.performace:type=PerformanceMetadataMBean");
            mbs.registerMBean(metadataObj, name);
        }

But I don't see any value for JMXBean.NumberOfRequests

1条回答
迷人小祖宗
2楼-- · 2019-08-06 02:24

The issue here is that the instance of the bean being registered is not the same as the instance you are setting the values on. So you need to coordinate passing around the same instance that was registered (optionally implementing as a singleton) or you could simply update the MBean using a JMX operation. The complexity of executing a JMX operation can also be simplified by creating a proxy invoker. I suggest this approach:

  • Change your NumOfRequests field to an AtomicInteger since you want to make the MBean thread-safe[er]. ie.

  • Your MBean and the interface should have an attribute accessor (a getter) and an incrementor.

Interface

public int getNumOfRequests();
public void incrementNumOfRequests(int requests);

Implementation

private final AtomicInteger numOfRequests = new AtomicInteger(0);
public int getNumOfRequests() {
    return numOfRequests.get();
}
public void incrementNumOfRequests(int requests) {
   numOfRequests.addAndGet(requests);
}

Now you can register the bean instance once, and update it through the JMX proxies which you can generate on the fly. This is done using a MBeanServerInvocationHandler.

PerformanceMetadataMBean proxy = (PerformanceMetadataMBean)MBeanServerInvocationHandler.newProxyInstance(ManagementFactory.getPlatformMBeanServer(),
                                                   new ObjectName("test.performace:type=PerformanceMetadataMBean"),
                                                   PerformanceMetadataMBean.class,
                                                   false);

Now, when you invoke proxy.incrementNumOfRequests(14), under the covers, it is invoking the bean's incrementNumOfRequests operation.

Give it a spin.

查看更多
登录 后发表回答