Search code examples
javaspringthreadpooljmxmbeans

how to modify ThreadPoolTaskExecutor at runtime through jmx


I'm having trouble modifying my MBean properties through JConsole. I have a Threading bean which invoked with:

public static void main(String[] args) throws Exception {
    // JMX
    new SimpleJmxAgent();

    // spring executor context
    ApplicationContext ctx = new FileSystemXmlApplicationContext(
            "src/resources/ThreadContent.xml");

    startThreads(ctx);
}

private static void startThreads(ApplicationContext ctx) {

    TaskExecutor tE = (TaskExecutor) ctx.getBean("TaskExecutor");

    System.out.println("Starting threads");

    for (int i = 0; i < 10; i++) {
        tE.execute(new RepeatingGrpPoC());
    }

ThreadContent.xml contains all default property values.

SimpleJmxAgent looks like:

public SimpleJmxAgent() {

    mbs = ManagementFactory.getPlatformMBeanServer();

    // Spring context - used to load MBeans
    XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource(
            "resources/JMXcontent.xml"));

    // Unique identification of MBeans
    ThreadPoolManager threadBean = (ThreadPoolManager) factory.getBean("ThreadPoolBean");
    ObjectName threadName = null;

      try {
          // Uniquely identify the MBeans and register them with the platform MBeanServer 
          threadName = new ObjectName("THREADING:name=ThreadBean");
          mbs.registerMBean(threadBean, threadName);
       } catch(Exception e) {
          e.printStackTrace();
       }

I have the ThreadPoolManager inherting from ThreadPoolTaskExecutor in order to give it access to the getter and setter methods of the Thread properties such as: public void setCorePoolSize(int corePoolSize)

EDIT:

I have implemented the use of:

public void setCorePoolSize(int corePoolSize){
    super.setCorePoolSize(corePoolSize);
}

wrapped in a:

    public void changeCorePoolSize(int x){
    setCorePoolSize(x);

}

So now the Operation appears in MBeans tab. However the Attributes are shown as different values as what is being used. I have set in my ThreadContext.xml

property name="corePoolSize" value="5"

However when viewing attribute is set to 1 which is a default value. I can change this through the Jconsole via the changeCorePoolSize operation but has only a cosmetic effect changing the value displayed but not changing the ongoing process which still has 5 TaskExecutor threads still going.

Am I missing something in what I am doing? What could causing the disconnect between the properties I'm setting through ThreadContext.xml and that being displayed in the attributes in Jconsole?


Solution

  • Reducing the CorePoolSize should be enough to reduce the the number of active thread but it only takes effect after the currently running commands complete.

    Beware of the effect of MaxPoolSize wich may increse the number of active threads if the workQueue is full.

    If you are interested, we packaged a JMX enabled util.concurrent ThreadPoolExecutor and expose it via a simple spring XML namespaced based configuration. It exposes both metrics (activeCount, completedTackCount, etc) and runtime configuration parameters (corePoolsize, maxPoolsize). You simply have to declare :

    <beans 
       xmlns:management="http://www.xebia.fr/schema/xebia-management-extras"
       ... >
    
       <!-- MBeanExporter is in charge of registering the ExecutorService MBean -->
       <context:mbean-export />
    
       <management:executor-service 
           id="my-executor" 
           pool-size="1-10" 
           queue-capacity="5"
           keep-alive="5"
           rejection-policy="ABORT" />
       ...
    <beans>

    The library contains JSP page and an Hyperic HQ plugin to monitor these thread pools.

    This <executor-service /> is packaged with many other JMX extras to ease monitoring of common components (dbcp, util.concurrent, cxf, jms, etc) and proposed under a business friendly Apache Software License at http://code.google.com/p/xebia-france/wiki/XebiaManagementExtras .

    Hope this helps,

    Cyrille