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...
null
for the first argumentCoherence:*
domain (112) if I pass null
for the second argumentnull
for both argumentsThe 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.)
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...