This hack is so awful that I am almost embarrassed to blog about it, but this was the only way to obtain the information we needed from ActiveMQ to display in an MBean in JConsole.
We have written a Java proxy server to allow Window CE devices running a C# application to connect to our JMS message broker. The proxy server runs within a Glassfish instance to make managing its lifecycle a bit easier. For system diagnostics and debugging purposes we created an MBean to be accessed via JMX so we could get real-time statistics from the proxy through JConsole or VisualVM, such as # of clients connected, message counts, as well as total connections open from the proxy to the broker.
The number of connections that the proxy had opened to the broker seemed like it *should* be a fairly straightforward task. Enable statistics on the ActiveMQConnectionFactory instance by calling setStatsEnabled(true) and then retrieve the connection statistics from the factory via a call to the getStats() method, and then get the total number of open connections. However, no matter what we did, the getStats() call always returned null, and for good reason, upon inspecting the ActiveMQConnectionFactory source code we found:
218 public StatsImpl getStats() { 219 // TODO 220 return null; 221 }
In the ActiveMQConnectionFactory class there resides a field called factoryStats of type JMSStatsImpl. The field is protected and there are no get() methods to retrieve this field, so we had to resort to drastic measures if we really wanted to know how many open connections the proxy had open to the broker. The code to get the connection information from the factory appears below.
@Override public int getBrokerConnectionCount() { int count = -1; try { Field factoryStatsField = ActiveMQConnectionFactory.class.getDeclaredField("factoryStats"); factoryStatsField.setAccessible(true); JMSStatsImpl factoryStats = (JMSStatsImpl) factoryStatsField.get(connectionFactory); count = factoryStats.getConnections().length; } catch (Exception ex) { logger.error("Attempted to get Broker connection count, but failed due to: " + ex.getMessage()); } return count; }
Even though the field is protected, reflection can be used to set the field to “accessible” and then the value of the field can be read directly from the factory object. This is not guaranteed to work in future releases of ActiveMQ, but since this is only for informational purposes in JConsole this was good enough for what we needed.
Twitter: @RobTerp
Hi
I have logged a ticket in AMQ about the implementation of the getStatus method.
https://issues.apache.org/jira/browse/AMQ-3788
Thank you Claus! I’ll see you at CamelOne in Boston in May!
Ah cool, see you there.