I don’t particularly like developing on JBoss - I think its bloated and slow. But with EJB3 the platform has become more viable. The turn around time to get a relatively complex application with web services etc. done is great.
One thing I like about JBoss 5.x are the JMX extensions to EJB3. Its really amazing how simple installing a JMX MBean is. Let’s say I have to write a CalculatorService represented by this interface:
package net.ahlawat.cricket;
import javax.ejb.Remote;
import org.jboss.ejb3.annotation.Management;
@Management
@Remote
public interface CalculatorService {
public double add(double a, double b);
public double subtract(double a, double b);
public double performOperation(double a, double b);
public String getDefaultOperation();
public void setDefaultOperation(String operation);
}
The interesting annotations here are @Management which tells JBoss deployer that the interface is to be bound as a JMX MBean. The implementation of this bean can be simple pojo - listed here.
package net.ahlawat.cricket;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.ejb3.annotation.Service;
@Service(objectName = "ahlawat:service=CalculatorService")
public class CalculatorServiceImpl implements CalculatorService {
static Log logger = LogFactory.getLog(CalculatorServiceImpl.class);
Method defaultOperation;
@Override
public double add(double a, double b) {
return a+b;
}
@Override
public String getDefaultOperation() {
return defaultOperation.getName();
}
@Override
public double performOperation(double a, double b) {
try {
BigDecimal bd = (BigDecimal) defaultOperation.invoke(new BigDecimal(a), new BigDecimal(b));
return bd.doubleValue();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return Double.NaN;
}
@Override
public void setDefaultOperation(String operation) {
try {
Method m = BigDecimal.class.getMethod(operation, BigDecimal.class);
logger.info("Setting default operation to " + operation);
defaultOperation = m;
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
@Override
public double subtract(double a, double b) {
return a-b;
}
//lifecycle methods
public void create() throws Exception {
logger.info("Creating service");
}
public void start() throws Exception {
logger.info("Starting service");
setDefaultOperation("add");
}
}
The only interesting thing here is @Service - which tells Jboss that this is a singleton bean. And the fact that MBean lifecycle methods like create() and start() are available to be implemented here.
The complete list of life cycle methods are:
void create() throws Exception;
void start() throws Exception;
void stop();
void destroy();
Once this is jar’d up and deployed to Jboss - you can go to jmx-console and see that the service is visible:

jmx-console
You can also look up the bean using the default JNDI name CalculatorServiceImpl/remote
public class Main {
public static void main(String[] args) throws Exception {
InitialContext ctx = new InitialContext();
CalculatorService cs = (CalculatorService)ctx.lookup("CalculatorServiceImpl/remote");
System.out.println(cs.add(2.1, 3.2));
}
}
Here is the jndi.properties:
#jboss JNDI properties
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=jnp://localhost:1099
java.naming.factory.url.pkgs=org.jnp.interfaces
And you can also inject the referece to another EJB using the @EJB annotation like this:
@Stateless
public class PlayerServiceImpl implements PlayerService {
static Log logger = LogFactory.getLog(PlayerServiceImpl.class);
@PersistenceContext(unitName = "default")
EntityManager entityManager;
@EJB
CalculatorService calculatorService;
@PostConstruct
public void gotCalculator() {
System.out.println(">>>>>>>>>>>>>>>>>> " + calculatorService.add(1.0, 1.0));
}
...
}
Really small amount of code and guess what - no XML. I really like it.