Problem with JMX query of Coherence node MBeans visible in JConsole
-
21-08-2019 - |
Question
I'm using JMX to build a custom tool for monitoring remote Coherence clusters at work. I'm able to connect just fine and query MBeans directly, and I've acquired nearly all the information I need. However, I've run into a snag when trying to query MBeans for specific caches within a cluster, which is where I can find stats about total number of gets/puts, average time for each, etc.
The MBeans I'm trying to access programatically are visible when I connect to the remote process using JConsole, and have names like this:
Coherence:type=Cache,service=SequenceQueue,name=SEQ%GENERATOR,nodeId=1,tier=back
It would make it more flexible if I can dynamically grab all type=Cache
MBeans for a particular node ID without specifying all the caches. I'm trying to query them like this:
QueryExp specifiedNodeId = Query.eq(Query.attr("nodeId"), Query.value(nodeId));
QueryExp typeIsCache = Query.eq(Query.attr("type"), Query.value("Cache"));
QueryExp cacheNodes = Query.and(specifiedNodeId, typeIsCache);
ObjectName coherence = new ObjectName("Coherence:*");
Set<ObjectName> cacheMBeans = mBeanServer.queryMBeans(coherence, cacheNodes);
However, regardless of whether I use queryMBeans()
or queryNames()
, the query returns a Set containing...
- ...0 objects if I pass the arguments shown above
- ...0 objects if I pass
null
for the first argument - ...all MBeans in the
Coherence:*
domain (112) if I passnull
for the second argument - ...every single MBean (128) if I pass
null
for both arguments
The first two results are the unexpected ones, and suggest a problem in the QueryExp
I'm passing, but I can't figure out what the problem is. I even tried just passing typeIsCache
or specifiedNodeId
for the second parameter (with either coherence
or null
as the first parameter) and I always get 0 results.
I'm pretty green with JMX — any insight on what the problem is? (FYI, the monitoring tool will be run on Java 5, so things like JMX 2.0 won't help me at this point.)
Solution
Just wanted to post my solution for posterity...
I have been able to successfully retrieve the set of MBeans matching the specified characteristics through a simpler (yet stranger) approach. I still don't know why the QueryExp
approach doesn't work, but here's what does work (replaces the last line of code in my question):
Set<ObjectName> cacheMBeans = mBeanServer.queryNames(new ObjectName("Coherence:type=Cache,nodeId="+nodeId+",*"), null);
It also works when adding a fragment service=SequenceQueue
in the ObjectName constructor string to filter by Coherence service (cache) name.
As long as it works somehow, it's enough for me to get my job done, but this seems like a glaring flaw in the JMX implementation. And don't get me started on the process for creating a working JMXServiceURL using JMX and RMI...
OTHER TIPS
I fell down the same path as you, and I think the JDK docs could be clearer.
The Query.* appear to be only able to match attributes of the underlying MBean (i.e. real POJO getters), whereas ObjectName patterns is able to match against key/values within the ObjectName itself.
It would be nice to have the flexibility of doing more complex queries within the ObjectName domain.