The following example shows how to create a JMX bean.
-
JMX bean interface:
package com.sample.sales.core; import org.springframework.jmx.export.annotation.*; @ManagedResource(description = "Performs operations on Orders") public interface OrdersMBean { @ManagedOperation(description = "Recalculates an order amount") @ManagedOperationParameters({@ManagedOperationParameter(name = "orderId", description = "")}) String calculateTotals(String orderId); }
The interface and its methods may contain annotations to specify the description of the JMX bean and its operations. This description will be displayed in all tools that work with this JMX interface, thereby helping the system administrator.
Since the JMX tools support a limited set of data types, it is desirable to use
String
as the type for the parameters and result of the method and perform the conversion inside the method, if necessary. -
The JMX bean class:
package com.sample.sales.core; import com.haulmont.cuba.core.*; import com.haulmont.cuba.core.app.*; import com.sample.sales.entity.Order; import org.apache.commons.lang.exception.ExceptionUtils; import javax.annotation.ManagedBean; import javax.inject.Inject; import java.util.UUID; @ManagedBean("sales_OrdersMBean") public class Orders implements OrdersMBean { @Inject protected OrderWorker orderWorker; @Inject protected Persistence persistence; @Authenticated @Override public String calculateTotals(final String orderId) { try { persistence.createTransaction().execute(new Transaction.Runnable() { @Override public void run(EntityManager em) { Order entity = em.find(Order.class, UUID.fromString(orderId)); orderWorker.calculateTotals(entity); } }); return "Done"; } catch (Throwable e) { return ExceptionUtils.getStackTrace(e); } } }
The
@ManagedBean
annotation defines class as a managed bean with thesales_OrdersMBean
name. The name is specified directly in the annotation and not in the constant, since access to the JMX bean from Java code is not required.Lets overview the implementation of the
calculateTotals()
method.-
The method has the
@Authenticated
annotation, i.e., system authentication is performed on method entry in the absence of the user session. -
The method’s body is wrapped in the
try/catch
block, so that, if successful, the method returns "Done", and in case of error – the stack trace of the exception as string.It should be kept in mind that, in this case, all exceptions are handled and therefore do not get logged automatically, because they never fall through to
MBeanInterceptor
. If logging of exceptions is required, the call of the logger should be added in thecatch
section. -
The method starts the transaction, loads the
Order
entity instance by identifier, and passes control to theOrderWorker
bean for processing.
-
-
The registration of the JMX bean in
spring.xml
:<bean id="sales_MBeanExporter" lazy-init="false" class="com.haulmont.cuba.core.sys.jmx.MBeanExporter"> <property name="beans"> <map> <entry key="${cuba.webContextName}.sales:type=Orders" value-ref="sales_OrdersMBean"/> </map> </property> </bean>
All JMX beans of a project are declared in one MBeanExporter
instance in the map/entry
elements of the beans
property. The key is JMX ObjectName, the value – the bean’s name specified in the @ManagedBean
annotation. ObjectName begins with the name of the web application, because several web applications, which export the same
JMX interfaces, can be deployed in one Tomcat instance (i.e., in one JVM).