Thursday, December 20, 2007

Counter MBean to measure EJB calls

Thursday, December 20, 2007 Posted by Andre Broers
In this example I create a Counter MBean which I will install in the Glassfish server. This bean has three methods getCounter, incrementCounter and resetCounter. After this I create an EJB which will increment the counter each time sayHello is called. We can then monitor the counter with the jconsole app. After reading a lot of different implementations I think this is in my opinion the best way to implement this. The problem I have with this implementation is that I can call the increment function from jconsole with which I can influence the counter.

Let's start with the MBean:

/home/broersa/work/HelloApp/MyCounterMBean/src/com/bekijkhet/MyCounterMBean.java

[sourcecode language="java"]

package com.bekijkhet;

public interface MyCounterMBean {
public int getCounter();
public void incrementCounter();
public void resetCounter();
}[/sourcecode]
/home/broersa/work/HelloApp/MyCounterMBean/src/com/bekijkhet/MyCounter.java
[sourcecode language="java"]

package com.bekijkhet;

public class MyCounter implements MyCounterMBean {
public int counter = 0;

public int getCounter() {
return counter;
}

public void incrementCounter() {
counter++;
}

public void resetCounter() {
counter = 0;
}
}[/sourcecode]
/home/broersa/work/HelloApp/MyCounterMBean/build.xml
[sourcecode language="xml"]

<project name="MyCounterMBean" default="compile" basedir=".">
<description>
simple example build file
</description>
<!-- set global properties for this build -->
<property name="src" location="src"/>
<property name="build" location="build"/>

<target name="init">
<!-- Create the time stamp -->
<tstamp/>
<!-- Create the build directory structure used by compile -->
<mkdir dir="${build}"/>
</target>

<target name="compile" depends="init"
description="compile the source " >
<!-- Compile the java code from ${src} into ${build} -->
<javac srcdir="${src}" destdir="${build}"/>
</target>

<target name="clean"
description="clean up" >
<!-- Delete the ${build} and ${dist} directory trees -->
<delete dir="${build}"/>
</target>
</project>[/sourcecode]
type:asant compileto compile the MBean.cd build

cp -r com /home/broersa/glassfish/domains/domain1/applications/mbeans

asadmin create-mbean com.bekijkhet.MyCounter

to deploy the managed bean.

Now it is time to create the statefull EJB which increments the counter in the MBean.

/home/broersa/work/HelloApp/MyCounterEJB/src/com/bekijkhet/MyCounterEJB.java

[sourcecode language="java"]

package com.bekijkhet;
public interface MyCounterEJB {
public String sayHello();
}[/sourcecode]
/home/broersa/work/HelloApp/MyCounterEJB/src/com/bekijkhet/MyCounterEJB.java
[sourcecode language="java"]

package com.bekijkhet;
import javax.ejb.Stateless;
import javax.ejb.EJB;
import javax.ejb.Remote;
import java.util.Properties;
import java.net.URL;
import javax.naming.*;
import javax.management.*;
import java.lang.management.*;

@Stateless
@Remote(MyCounterEJB.class)
public class MyCounterEJBBean implements MyCounterEJB {

private MyCounterMBean mbean = null;

public MyCounterEJBBean() {

try {
// Get the platform MBeanServer
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName name = new ObjectName("user:impl-class-name=com.bekijkhet.MyCounter,name=com.bekijkhet.MyCounter,server=server");

mbean = (MyCounterMBean) MBeanServerInvocationHandler.newProxyInstance(mbs, name, MyCounterMBean.class, false);
} catch(Exception e) {
e.printStackTrace();
}
}

public String sayHello() {
mbean.incrementCounter();
return "Hello From Glassfish!!!! ";
}
}[/sourcecode]
/home/broersa/work/HelloApp/MyCounterEJB/build.xml
[sourcecode language="XML"]

<project name="MyCounterEJB" default="dist" basedir=".">
<description>
simple example build file
</description>
<!-- set global properties for this build -->
<property name="src" location="src"/>
<property name="build" location="build"/>
<property name="dist" location="dist"/>

<target name="init">
<!-- Create the time stamp -->
<tstamp/>
<!-- Create the build directory structure used by compile -->
<mkdir dir="${build}"/>
</target>

<target name="compile" depends="init"
description="compile the source " >
<!-- Compile the java code from ${src} into ${build} -->
<javac srcdir="/home/broersa/work/HelloApp/MyCounterMBean/src" destdir="${build}"/>
<javac srcdir="${src}" destdir="${build}"/>
</target>

<target name="dist" depends="compile"
description="generate the distribution" >
<!-- Create the distribution directory -->
<mkdir dir="${dist}"/>

<!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
<jar jarfile="${dist}/MyCounterEJB.jar" basedir="${build}"/>
</target>

<target name="clean"
description="clean up" >
<!-- Delete the ${build} and ${dist} directory trees -->
<delete dir="${build}"/>
<delete dir="${dist}"/>
</target>
</project>[/sourcecode]
In this build.xml I included a second javac rule that includes the MBean classes in this ejb.Now we build and deploy the ejb:

asant dist

asadmin deploy dist/MyCounterEJB.jar

Now it is time to create the client that calls the ejb sayhello method that increments our counter in the mbean.

[sourcecode language="java"]

package com.bekijkhet.helloclient;
import javax.naming.*;
import com.bekijkhet.MyCounterEJB;
public class HelloClient {
public static void main(String[] args) {
try {
InitialContext ctx = new InitialContext();
MyCounterEJB m = (MyCounterEJB)ctx.lookup("com.bekijkhet.MyCounterEJB");
System.out.println(m.sayHello());
}
catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
}
}[/sourcecode]
compile the code:javac -cp $GLASSFISH_HOME/lib/appserv-rt.jar:$GLASSFISH_HOME/lib/javaee.jar:$HOME/work/HelloApp/MyCounterEJB/dist/MyCounterEJB.jar:. -d . HelloClient.java

open a jconsole to monitor our Mbean. connect to localhost:8686 (which is the default portnumber) and connect with admin pwd: adminadmin

jconsole

See the counter which has the value 0.

Now we run our client:

java -cp $GLASSFISH_HOME/lib/appserv-rt.jar:$GLASSFISH_HOME/lib/javaee.jar:$HOME/work/HelloApp/MyCounterEJB/dist/MyCounterEJB.jar:. com.bekijkhet.helloclient.HelloClient

And the counter is incremented by one:

jconsole1