A Universal JMX Client for Weblogic – Monitoring BPEL Thread Pools in SOA 11g


Update Feb 2018: Please note that this blog was written in 2012 when SOA 11g was available. The tools and APIs described in this blog will work only with the 11g version. Current version of SOA 12.2.

Monitoring and optimizing BPEL Thread Pool utilization (and other metrics) is one of the key activities in performance tuning of BPEL/SOA based integrations. Although the EM console provides some basic monitoring of the BPEL engine statistics, it is limited regarding the update interval, detail and the recording interval and cannot display historic data. Of course you can setup Grid Control 11g with its Repository, but this is, in many cases, too complex to setup just for monitoring during performance and load testing.

Main Article

So, the idea came to create a tool which can easily record these statistics and export them to MS Excel or OpenOffice to create charts for the thread pool utilization over a time period (for example a whole load test execution).

All values of WLS or the SOA engine can be queried using the JMX MBean framework. I have designed the JMXClient to be able configure which MBeans should be queried by using a property file (beans.properties). I decided to connect in this first release to only one Managed Server of WLS to record / export data. This means that if you have a WLS cluster, you need to start multiple JMX Clients to record the values of each node. (In a later release the JMX Client could be optimized to query all nodes automatically).

JMXClient can be used by downloading from the project page at Sourceforge. (including JDeveloper project and sources)

After that you need to configure

  1. your connection properties, JAVA_HOME and WLS_HOME of your WLS managed server of SOA in jmxclient.bat (or jmxclient.sh)
  2. the MBeans names, WLS Server name and the attributes to record in classes/beans.properties (you can find the MBean names form the System MBean Browser in EM)

The syntax in jmxclient.bat is

java -cp classes;%INCLUDE_LIBS% jmxclient.JMXClient <server> <user> <password> -monitor 1000

For example

java -cp classes;%INCLUDE_LIBS% jmxclient.JMXClient 7001 weblogic welcome1 -monitor 1000

“1000” specifies the interval in milliseconds between the recording.
Then you can run it with

jmxclient > out.txt

Then simply import this text file using Excel or OpenOffice and a comma “,” as delimiter and create a line chart using line 2 as titles and lines 3 to end as data.

Let me first show a couple of results using JMXClient using the properties to record the BPEL thread pool statistics:

The following chart shows a scenario where the invoke thread pool is much too low (20) so that the queue of scheduled invocations waiting for a free thread is growing rapidly:


The second example shows a scenario where invoke and callback threads are within normal limits:


In the next posts I will show how to use JMXClient to record the BPEL process execution times or the number of messages in the AIA 11g JMS queues by simply exchanging the beans.properties file…..!

Update: The post mentioned above for recording BPEL process execution times can be found here.

Have fun,

DISCLAIMER: JMXClient is provided for free use “as is” without any support or warranty. Please provide enhancements or modifications you make yourself.

PS: for the experts: the format of the beans.properties file:

Every line contains 3 items separated by semicolon:

  1. the name of the MBean to query
  2. the attribute to query
  3. the title string which should be displayed for the column

Example for the bpel thread pools:

oracle.dms:Location=AdminServer,name=/soainfra/engines/bpel/requests/invoke,type=soainfra_bpel_requests;active_maxValue;Invoke Active Max
 oracle.dms:Location=AdminServer,name=/soainfra/engines/bpel/requests/invoke,type=soainfra_bpel_requests;scheduled_maxValue;Invoke Scheduled Max
 oracle.dms:Location=AdminServer,name=/soainfra/engines/bpel/requests/invoke,type=soainfra_bpel_requests;scheduled_value;Invoke Scheduled Current
 oracle.dms:Location=AdminServer,name=/soainfra/engines/bpel/requests/invoke,type=soainfra_bpel_requests;active_value;Invoke Active Value
 oracle.dms:Location=AdminServer,name=/soainfra/engines/bpel/requests/invoke,type=soainfra_bpel_requests;threadCount_value;Invoke Threads Value
 oracle.dms:Location=AdminServer,name=/soainfra/engines/bpel/requests/invoke,type=soainfra_bpel_requests;threadCount_maxValue;Invoke Threads Max
 oracle.dms:Location=AdminServer,name=/soainfra/engines/bpel/requests/system,type=soainfra_bpel_requests;active_maxValue;System Active Max
 oracle.dms:Location=AdminServer,name=/soainfra/engines/bpel/requests/system,type=soainfra_bpel_requests;scheduled_maxValue;System Scheduled Max
 oracle.dms:Location=AdminServer,name=/soainfra/engines/bpel/requests/system,type=soainfra_bpel_requests;scheduled_value;System Scheduled Current
 oracle.dms:Location=AdminServer,name=/soainfra/engines/bpel/requests/system,type=soainfra_bpel_requests;active_value;System Active value
 oracle.dms:Location=AdminServer,name=/soainfra/engines/bpel/requests/system,type=soainfra_bpel_requests;threadCount_value;Invoke Threads Value
 oracle.dms:Location=AdminServer,name=/soainfra/engines/bpel/requests/system,type=soainfra_bpel_requests;threadCount_maxValue;Invoke Threads Max
 oracle.dms:Location=AdminServer,name=/soainfra/engines/bpel/requests/engine,type=soainfra_bpel_requests;active_maxValue;Engine Active Max
 oracle.dms:Location=AdminServer,name=/soainfra/engines/bpel/requests/engine,type=soainfra_bpel_requests;scheduled_maxValue;Engine Scheduled Max
 oracle.dms:Location=AdminServer,name=/soainfra/engines/bpel/requests/engine,type=soainfra_bpel_requests;scheduled_value;Engine Scheduled Current
 oracle.dms:Location=AdminServer,name=/soainfra/engines/bpel/requests/engine,type=soainfra_bpel_requests;active_value;Engine Active value
 oracle.dms:Location=AdminServer,name=/soainfra/engines/bpel/requests/engine,type=soainfra_bpel_requests;threadCount_value;Engine Threads Value
 oracle.dms:Location=AdminServer,name=/soainfra/engines/bpel/requests/engine,type=soainfra_bpel_requests;threadCount_maxValue;Engine Threads Max
 oracle.dms:Location=AdminServer,name=/soainfra/engines/bpel/requests/audit,type=soainfra_bpel_requests;active_maxValue;Audit Active Max
 oracle.dms:Location=AdminServer,name=/soainfra/engines/bpel/requests/audit,type=soainfra_bpel_requests;scheduled_maxValue;Audit Scheduled Max
 oracle.dms:Location=AdminServer,name=/soainfra/engines/bpel/requests/audit,type=soainfra_bpel_requests;scheduled_value;Audit Scheduled Max
 oracle.dms:Location=AdminServer,name=/soainfra/engines/bpel/requests/audit,type=soainfra_bpel_requests;active_value;Audit Active value
 oracle.dms:Location=AdminServer,name=/soainfra/engines/bpel/requests/audit,type=soainfra_bpel_requests;threadCount_value;Audit Threads Value
 oracle.dms:Location=AdminServer,name=/soainfra/engines/bpel/requests/audit,type=soainfra_bpel_requests;threadCount_maxValue;Audit Threads Max


  1. You can get the state via the Facade API:

    Use oracle.soa.management.facade.Locator#getComposite(compositeDN) to get a reference to a composite of interest.

    From the composite reference, you can query the mode and state using the following methods:

    String getMode()

    String getState()

    see https://docs.oracle.com/cd/E21764_01/admin.1111/e10226/soaadmin_apimanage.htm#CACBGHGA

    • Khatri Rajesh says:

      Thanks for the response. The oracle.soa.management.facade will give the instances of composite but I want to check if service itself is up or down. I was under the impression that DomainRuntimeService ( code below ) should give the state.

      Please let me know. Thanks.

  2. Khatri Rajesh says:

    Hello, I am trying to build a script using JMX API to monitor state of our custom SOA services. Am able to navigate to System Mean Browser -> Application Definied M Beans -> oracle.soa.config -> soa_Server1 -> SCA Composite and access all composites using below code and also able to view other attributes but unable to access state. Can someone please provide some direction.

    import java.util.*;
    import javax.management.*;
    import javax.management.ObjectName;

    public class PrintMBeanNames {

    public static void main(String[] args) {

    private static void printMBeans() {

    try {

    // init wrapper
    JMXWrapperRemote myJMXWrapper = new JMXWrapperRemote();

    // Domain Runtime
    //myJMXWrapper.connectToAdminServer(false, true, “user”,”pass”,”http://localhost:7001″);

    MBeanServerConnection connection = myJMXWrapper.getConnection();
    Set mySet = connection.queryNames(new ObjectName(“oracle.soa.config:*,j2eeType=SCAComposite*”), null);
    Iterator it = mySet.iterator();

    while (it.hasNext()) {
    ObjectName myName = (ObjectName) it.next();

    try {
    System.out.println(“–> ” + myName.getCanonicalName());

    // get all attributes
    MBeanAttributeInfo[] atribs = connection.getMBeanInfo(myName).getAttributes();

    for (int i = 0; i < atribs.length; i++) {
    System.out.println(" Attribute: " + atribs[i].getName() +
    " of Type : " + atribs[i].getValue());

    // get all operations
    MBeanOperationInfo[] operations = connection.getMBeanInfo(myName).getOperations();

    for (int i = 0; i < operations.length; i++) {
    System.out.print(" Operation: " +
    operations[i].getReturnType() + " " +
    operations[i].getName() + "(");

    for (int j = 0; j < operations[i].getSignature().length;j++)
    getName() + ":" +
    getType() + " ");


    } catch (Exception ex) {

    // disconnect
    catch (Exception ex) {

Add Your Comment