Sunday, March 4, 2012

How to expose a class through JMX in CQ5.5 / WEM

Use case: Starting with CQ5.5 / CRX2.3, JMX has eventually been integrated to expose various repository related statistics and information. There are also certain operations that can be triggered via JMX, such as online backup or TarPM optimization.

The Felix Console comes with a dedicated JMX plugin to access the JMX interface.


You can use any JMX client (Visual VM, Jconsole) to perform these operation, Here is screen shot of how it will look like



You can also perform JMX related operation through felix console




The main 2 classes that provide JMX information and data in CRX are as follows:
com.day.crx.sling.server.jmx.ManagedRepositoryMBean
com.day.crx.sling.server.impl.jmx.ManagedRepository
The former is an interface which defines the methods being exposed to JMX. These methods can be either read-only, so purely informative or writeable as well in which case e.g. configuration settings can be adjusted during runtime.

Creating custom JMX classes

Creating custom so called MBean classes is also quite straightforward. In the end, such classes are plain OSGi components that need to declare the javax.management.DynamicMBean interface, these are then automatically discovered during deployment and registered with JMX.

Here is sample class

package com.adobe.test;

import com.adobe.granite.jmx.annotation.Description;

@Description("JMX MBean example")
public interface JMXTestMBean {
@Description("Get bean name")
public String getName();
@Description("Get Bean Id")
public String getId();
@Description("Get repository Description")
public String getRepositoryName();
}


And implementation

package com.adobe.test.impl;

import javax.management.MBeanAttributeInfo;
import javax.management.MBeanInfo;
import javax.management.NotCompliantMBeanException;
import javax.management.StandardMBean;

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.jcr.api.SlingRepository;

import com.adobe.test.JMXTestMBean;

@Component(immediate=true)
@Property(name="jmx.objectname", value="com.adobe.test:type=test")
@Service(value=javax.management.DynamicMBean.class)
public class JMXTestMBeanImpl extends StandardMBean implements JMXTestMBean {

@Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY)
private SlingRepository repository;

public JMXTestMBeanImpl() throws NotCompliantMBeanException {
super(JMXTestMBean.class);
}

@Override
protected String getDescription(MBeanInfo arg0) {
return "MBean Test example";
}

@Override
protected String getDescription(MBeanAttributeInfo mBeanAttributeInfo) {
return "MBean Attribute";
}

public String getName() {
// TODO Auto-generated method stub
return "Test JMX Bean";
}

public String getId() {
// TODO Auto-generated method stub
return "v0.1";
}

public String getRepositoryName(){
return repository.getDescriptor("jcr.repository.name");
}

}








You can get entire package from here

JMX API in CQ: http://dev.day.com/docs/en/cq/current/javadoc/com/adobe/granite/jmx/annotation/package-summary.html

2 comments:

  1. Hello,
    Is it possible to overwrite the joinCluster() method in "ManagedRepository" ?
    The class seems to be declared Public in (com.day.crx.sling.server-2.3.15.jar) but is not exposed through CQ API.

    We need to overwrite the method to incorporate some custom code to make enable the initial clustering connection.

    Many thanks.
    Cheers,
    Piyush

    ReplyDelete
    Replies
    1. Piyush,

      crx-server bundle is deployed as fragment bundle and part of crx. Join cluster should be there in granite API. I would strongly recommend not to change any thing here unless there is very strong reason to do so.

      Yogesh

      Delete