Monitoring

Monitoring JBoss EJB Container

In this article we will show how easily you can write an Interceptor class which is added in the chain of EJB interceptors. We will show how to achieve it in all recent releases of the application server (5-6-7).
 
Interceptors are designed to separate common, or cross-cutting, code from business methods. A typical usage of interceptor are  logging, auditing, performance monitoring, or security checks.
 
Such aspects are shared among business methods and are often tangential to any business logic. Instead of cluttering business methods with cross-cutting code, any such code is encapsulated in separate methods or classes called interceptors.

EJB Interceptors can be added much the same way at two different levels:

  • At EJB Container level
  • At Application level

If you want to learn more Application level EJB interceptors you can have a look at this tutorial.

Here we will show how to apply EJB Interceptors at EJB Container level, which could be used for monitoring some aspects which are not peculiar with your applications, but can be reused in different contexts. You can configure EJB Container interceptors in different ways depending on the release of JBoss AS you are using

JBoss AS 7.2

EJB Container interceptors are available since the release 7.2.0 of the application server. You can configure them, by adding the Interceptor (or the chain of interceptors) in your jboss-ejb3.xml file which is JBoss AS 7 custom deployment descriptor for your EJB applications. Let's see one example:

<jboss xmlns="http://www.jboss.com/xml/ns/javaee"
       xmlns:jee="http://java.sun.com/xml/ns/javaee"
       xmlns:ci ="urn:container-interceptors:1.0">
 
    <jee:assembly-descriptor>
        <ci:container-interceptors>
            <!-- Default interceptor -->
            <jee:interceptor-binding>
                <ejb-name>*</ejb-name>
                <interceptor-class>com.mastertheboss.interceptor.GenericContainerInterceptor</interceptor-class>
            </jee:interceptor-binding>
 
        </ci:container-interceptors>
    </jee:assembly-descriptor>
</jboss>


This is a default Interceptor, which will be used for all your EJBs. And here's the Interceptor class, which simply includes the javax.interceptor.AroundInvoke annotation in one of its methods:

package com.mastertheboss.interceptor;

import org.jboss.logging.Logger;

import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;

public class GenericContainerInterceptor {
    private static Logger log = Logger.getLogger(GenericContainerInterceptor.class);
    
    @AroundInvoke
    private Object intercept(final InvocationContext invocationContext) throws Exception {
         
          log.info("Going to call " +invocationContext.getMethod());// singleton.getFromPool();

          // Invoke the EJB method
          Object result = this.getClass().getName() + " " + invocationContext.proceed();

          
        return result;
    }
 
}

When executed, this Interceptor will display the EJB being called and its method:
15:02:13,198 INFO  [com.mastertheboss.interceptor.GenericContainerInterceptor] (http-/127.0.0.1:8080-1) Going to call public void com.mastertheboss.ejb.ServiceBean.put(com.mastertheboss.model.SimpleProperty)

If you want to intercept just one EJB, you can specify the EJB name in the file jboss-ejb3.xml

<jee:interceptor-binding>
     <ejb-name>ServiceBean</ejb-name>
     <interceptor-class>com.mastertheboss.interceptor.GenericContainerInterceptor</interceptor-class>
</jee:interceptor-binding>


 Finally, you can intercept just a single method of the EJB, like in the following example:

<jee:interceptor-binding>
     <ejb-name>ServiceBean</ejb-name>
     <interceptor-class>com.mastertheboss.interceptor.GenericContainerInterceptor</interceptor-class>
     <method>
            <method-name>put</method-name>
     </method>
</jee:interceptor-binding>

JBoss AS 5 - 6

JBoss 5 EJB container is based on the concept of interceptors. These are simple classed based on the Proxy pattern, which allow to execute all the required steps before method invocation (security checks, instance creation, transaction propagation etc.).

The great benefit of interceptors is that they are a seamless way to add Aspect Oriented Programming to your business methods.

EJB 3 Interceptors are defined in the file server/<your server>/deploy/ejb3-interceptors.xml.

Here's the section we want to operate on:
 <domain name="Stateless Bean" extends="Intercepted Bean" inheritBindings="true">
     . . . .
      <bind pointcut="execution(public * *->*(..))">
         
         <interceptor-ref name="org.jboss.aspects.tx.TxPropagationInterceptor"/>
         <interceptor-ref name="org.jboss.ejb3.tx.CMTTxInterceptorFactory"/>
         <interceptor-ref name="org.jboss.ejb3.stateless.StatelessInstanceInterceptor"/>
         <interceptor-ref name="org.jboss.ejb3.tx.BMTTxInterceptorFactory"/>
         <interceptor-ref name="org.jboss.ejb3.AllowedOperationsInterceptor"/>
         <interceptor-ref name="org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor"/>
         <!-- interceptor-ref name="org.jboss.ejb3.interceptor.EJB3InterceptorsFactory"/ -->
         <stack-ref name="EJBInterceptors"/>
      </bind>
      <annotation expr="!class(@org.jboss.ejb3.annotation.Pool)">
         @org.jboss.ejb3.annotation.Pool (value="ThreadlocalPool", maxSize=30, timeout=10000)
      </annotation>
</domain>

#2 Update jboss-ejb3-core.jar

<!--------- OUR INTERCEPTOR ---------->
   
   <interceptor class="com.sample.PoolInterceptor" scope="PER_VM"/>
   
   ........
   
   <domain name="Stateless Bean" extends="Intercepted Bean" inheritBindings="true">
         
         <interceptor-ref name="org.jboss.aspects.tx.TxPropagationInterceptor"/>
         <interceptor-ref name="org.jboss.ejb3.tx.CMTTxInterceptorFactory"/>
         <interceptor-ref name="org.jboss.ejb3.stateless.StatelessInstanceInterceptor"/>
         <interceptor-ref name="org.jboss.ejb3.tx.BMTTxInterceptorFactory"/>
         <interceptor-ref name="org.jboss.ejb3.AllowedOperationsInterceptor"/>
         <interceptor-ref name="org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor"/>
         
         <!--------- OUR INTERCEPTOR ---------->
         <interceptor-ref name="com.sample.PoolInterceptor"/> 
         
         
         <stack-ref name="EJBInterceptors"/>
      </bind>
      <annotation expr="!class(@org.jboss.ejb3.annotation.Pool)">
         @org.jboss.ejb3.annotation.Pool (value="StrictMaxPool", maxSize=1000, timeout=100000)
      </annotation>
   </domain>


Compile the interceptor and add the class to the jboss-ejb3-core.jar

jboss as stateless slsb ejb pool
 That's all! restart the server and verify that your SLSB now debugs information about the current/max size of instances.

Related articles available on mastertheboss.com

How to monitor JBoss CPU usage ?

  JBoss AS 7 users and WildFly can use JConsole in order to moni

How to monitor jboss graphically ?

  You’ve been using the JMX Console to access yourMBeans. In thi

How to monitor JBoss with snapshots?

  JBoss gives you the ability to capture data not only in real t

JBoss Alarm configuration

An Alarm indicates that an event (generally an error) has happene

Monitor JBoss AS with Jolokia

Jolokia is a cool monitoring solution for accessing JMX MBeans re

How to solve java.lang.OutOfMemoryError: unable to create new nat

In Java you can stumble upon two kind of Out of Memory errors:

Follow us on Twitter