jueves, 22 de diciembre de 2011

Programmatically obtaining "Messages waiting for read" for OC4J 10g JMS memory topic using JMX

You have to configure your classpath with the following jars (I haven´t test which of them are extrictly necessary):
  • adminclient.jar
  • dms.jar
  • ejb.jar
  • javax77.jar
  • jms.jar
  • oc4jclient.jar
  • oc4j-internal.jar
  • optic.jar
  • pcl.jar

Although I'm working with OAS and not with OC4J standalone, I'll connect directly to the OC4J instance (not through OPMN). So I'll use this type of URL: service:jmx:rmi://[server]:[oc4j_rmi_port]. I just need to get the OC4J RMI port usign opmnctl -l.

Obtain the connection using the oc4jadmin credentials:

JMXServiceURL url = new JMXServiceURL(makeJmxUrl());
String[] creds = { "oc4jadmin", oc4jadminPassword };
Map<String, Object> env = new HashMap<String, Object>();
env.put(JMXConnector.CREDENTIALS, creds);
JMXConnector jmxc = JMXConnectorFactory.connect(url, env);
MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();


The JMS topic I'm trying to obtain the statistics from is one of the Oracle ESB 10g standard topics: ESB Java Deferred. I have several subscribers and each one of them has a corresponding MBean. The statistics are presented from each one of them, and not as totals for the topic. So, if for example, I want to get the "Messages waiting for read" for the topic, I have to obtain the value for each subscriber and add them. The wildarded URL to obtain the MBeans for the subscribes is as follows: oc4j:j2eeType=JMSStoreResource,*,JMSDestinationResource=\"Topic.ESB Deferred Topic\",JMSResource=\"JMS\",J2EEServer=standalone

ObjectName mbeanNameQueryPattern = new ObjectName("oc4j:j2eeType=JMSStoreResource,*,JMSDestinationResource=\"Topic.ESB Deferred Topic\",JMSResource=\"JMS\",J2EEServer=standalone");
Set<ObjectName> mbeansNames = mbsc.queryNames(mbeanNameQueryPattern, null);

Iterate over the MBeans to obtain their statistics: There are several statistics to choose (messageCommitted, messageRolledBack, messageCount -Messages waiting for read-, messageDequeued -Messages waiting for commit-, messageEnqueued, messageDiscarded, messageExpired, messagePagedIn, messagePagedOut, messageRecovered and pendingMessageCount), but right now I'm only getting this: messageCount.

long value = 0L;
Iterator mbeansNamesIter = mbeansNames.iterator();
while (mbeansNamesIter.hasNext()) {
    ObjectName mbeanName = mbeansNamesIter.next();
    JMSStoreStatsImpl jmsStats = (JMSStoreStatsImpl)mbsc.getAttribute(mbeanName, "stats");
    CountStatisticImpl countStatistic = (CountStatisticImpl)jmsStats.getStatistic(statisticName);
    value = value + countStatistic.getCount();
}

Thos are the related imports:

import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import oracle.oc4j.admin.management.shared.statistic.CountStatisticImpl;
import oracle.oc4j.admin.management.shared.statistic.JMSStoreStatsImpl;

JVM must be started with this flag: -Djmx.remote.protocol.provider.pkgs=oracle.oc4j.admin.jmx.remote

If you want to make a "real time" desktop chart with the values, there's a very nice and easy alternative: VisualVM's charting API. Here is an example.


No hay comentarios: