Thursday, December 20, 2007

Counter MBean to measure EJB calls

Thursday, December 20, 2007 Posted by Andre Broers 6 comments
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

6 comments:

  1. Hi how can this work when there are many instances of this EJB? The ObjectName of the is unique so you actually can only see the counter of one MBean?

    ReplyDelete
  2. Hi
    What should the system properties be in order to make sure that the MyCounterEJB bean is found in the InitialContext?

    MyCounterEJB m = (MyCounterEJB)ctx.lookup("com.bekijkhet.MyCounterEJB");

    Regards
    Nico

    ReplyDelete
  3. Quester is a Pakistan-based questioning answering website where people can ask questions and we try our best to provide them with the best answers. Anyone can ask any legit question in English or Roman Urdu and we provide answers in the same language format. www.quester.pk

    ReplyDelete