Using JMX to snoop on data manipulation events inside ADF Business Components

1

The steps for observing the Salary Changes made in an ADF BC application – JClient, JSF or WebService style does not matter – are pretty straightforward. Building on the implementation of the EmpListener in the article Using ADF BC Event Listeners to monitor data changes application wide through RSS Feeds and Monitor Pages, we simply add an MBean that is associated with the EmpListener and that exposes the most recent Salary Change Event information through the MBean Server. JMX Clients – either JConsole, other tools or a client we program ourselves – can connect to the MBean Server and read the details exposed by the MBean.

 

The steps:....

  • Define the SalChangeMonitorMBean interface
  • Implement the SalChangeMonitor class that implements that interface
  • Instantiate SalChangeMonitor upon instantiation of the EmpListener and inject the EmpListener in the MBean.
  • Run the ADF BC application with some Java arguments on the commandline: -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=1111 -Dcom.sun.management.jmxremote.authenticate=false  -Dcom.sun.management.jmxremote.ssl=false 
  • Make some changes to salary values – either in the ADF BC Tester, the Web Application, the JClient application or though a WebService. Or whatever. The MBean inside the application will report its findings in any case.

....
 

Define the SalChangeMonitorMBean interface

package nl.amis.adfbc;<br /><br />import java.util.List;<br /><br />public abstract interface SalChangeMonitorMBean {<br /><br />public List&lt;String&gt; getMostRecentChange();<br /><br />}<br />&nbsp;

Implement the SalChangeMonitor class

package nl.amis.adfbc;<br /><br />import java.text.SimpleDateFormat;<br /><br />import java.util.ArrayList;<br />import java.util.List;<br /><br />public class SalChangeMonitor implements SalChangeMonitorMBean{<br /><br />    private EmpListener empListener;<br />    <br />    public SalChangeMonitor() {<br />    }<br />    public SalChangeMonitor(EmpListener empListener) {<br />      this.empListener=empListener;<br />    }<br /><br />    public List&lt;String&gt; getMostRecentChange() {<br />        SimpleDateFormat dateFormat = new SimpleDateFormat(&quot;EEE, d MMM yyyy HH:mm:ss z&quot;);<br />        List&lt;String&gt; changes = new ArrayList(25);<br />        for (SalaryChangeEvent event: empListener.getEvents()) {<br />            changes.add(dateFormat.format(event.getTimestamp())+&quot; &quot;+event.getEmployeeName()+&quot; (&quot;+event.getJob()+&quot;) from &quot;+event.getOldSalary()+&quot; to &quot;+event.getNewSalary());<br />        }<br />        return changes;<br />    }<br />} <br />

Instantiate SalChangeMonitor with injection of the ADF BC EmpListener

Here are the critical components in the EmpListener class: 

package nl.amis.adfbc;<br /><br />import java.lang.management.ManagementFactory;<br />import javax.management.MBeanServer;<br />import javax.management.ObjectName;<br />…<br /><br />public class EmpListener implements RowSetListener {<br />   …<br /> public static EmpListener getEmpListener() {<br />        if (el == null) {<br />            el= new EmpListener();<br />            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();<br />            SalChangeMonitorMBean salChangeMonitorMBean = new SalChangeMonitor(el);<br />            try<br />            {<br />                mbs.registerMBean(salChangeMonitorMBean , new ObjectName(&quot;HrmMonitor:type=salChangeMonitor&quot;));<br />                System.out.println(&quot;Registered MBean&quot;);<br />            }<br />            catch(Exception e)<br />            {<br />                e.printStackTrace();<br />            }<br />        }<br />        return el;<br />    }<br />    <br />…<br />}<br />

With these elements in place, run the application based on the ADF BC Application Module – either Web Application, Stand Alone Java Client, WebService or EJB, … – and run using these parameters on the commandline: -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=1111 .

Read the MBean at run-time 

To monitor what is happening inside the application:

Start JConsole – from the command line, just type jconsole.

On the Remote tab, connect to the host running the ADF BC application – for example localhost – and enter the same port number used in the com.sun.management.jmxremote.port argument when starting the ADF BC application.


 
Go to the MBeans tab. Open the HrmMonitor tree and click in the salChangeMonitor node – this is the name of the MBean. The MBean exposes a single attribute, called MostRecentChange. This attribute is a List<String> of messages describing Salary Change Events.


 
This is the most straightforward way of reporting on Salary Change events. Note that we can monitor these changes from anywhere, outside of the application and with minimal intrusion in the application. We only had to register the RowSetListener on the EmpView ViewObject and hook it up with an MBean. The application itself is modified in just a single location: the overridden create() method in the EmpViewImpl class, where the listener is registered.

Share.

About Author

Lucas Jellema, active in IT (and with Oracle) since 1994. Oracle ACE Director for Fusion Middleware. Consultant, trainer and instructor on diverse areas including Oracle Database (SQL & PLSQL), Service Oriented Architecture, BPM, ADF, Java in various shapes and forms and many other things. Author of the Oracle Press book: Oracle SOA Suite 11g Handbook. Frequent presenter on conferences such as JavaOne, Oracle OpenWorld, ODTUG Kaleidoscope, Devoxx and OBUG. Presenter for Oracle University Celebrity specials.

1 Comment

  1. Lucas, is there a way that multiple ejb instances can increment a counter in one mbean without exposing the increment method to the jconsole? What I need is a reference to the mbean object instance in the ejb, not the interface. I don’t know if this question is on topic. But maybe you know a sollution?
    Thanx.