Exception Handling

Before exploring exception related annotation (just one!), let's first understand the basic types of exceptions defined by the EJB specification

  • System Exceptions

  • Application Exceptions

System Exceptions

As per the EJB specification, a System exception is defined by the following criteria

  1. It is of the type java.rmi.RemoteException or its descendant, or

  2. It is of type java.lang.RuntimeException (unchecked) which is not annotated with @ApplicationException

System Exceptions are to EJBs what Errors are to the Java language. They help deal with scenarios where the issue should be propagated to the EJB container rather than handling it within the application itself.

The EJB container defines standard mechanism or pathways which are followed when a System application is thrown e.g. rolling back the transaction.

Application Exceptions

By design, Application Exceptions are meant to expressing business specific error scenarios and they can be propagated to the caller. Application Exceptions can be modelled as both checked and unchecked exceptions. An EJB can throw a checked exception and declare it in the throws clause. In case you want to model your application exception as an unchecked (RuntimeException) exception (here is where the @ApplicationException annotation comes into the picture)

@ApplicationException

If an exception extends RuntimeException, then you have to use this annotation so that the EJB container treats it as an Application Exception. Failure to use this will result in your exception being interpreted as a System Exception (which is handled differently)

package ejbap.exceptions;

public class CustomerNotFoundException extends Exception{
    //details ommitted
}
package ejbap.exceptions;

import javax.ejb.ApplicationException;

@ApplicationException
public class BookNotFoundException extends RuntimeException{
    //details ommitted
}

Rollback semantics

By default, the container does not roll back the transaction as a result of an Application exception. You can toggle the annotation property to refine this as per your business requirements.

package ejbap.exceptions;

import javax.ejb.ApplicationException;

@ApplicationException(rollback = true)
public class UpdateException extends RuntimeException{
    //details ommitted
}

Exception handling in Message Driven Beans

The entry point into a MDB is the overridden onMessage method. It does not provide any scope for throwing checked exceptions and as a result, you will need to propagate unchecked exceptions (subclass of java.lang.RuntimeException) from your code if you want to handle error scenarios. In case of System Exceptions, the container always discards the MDB instance, so make sure that you are using these exceptions for their intended reason. In case you are using Application Exceptions and they are unchecked ones (they have to be in case of MDBs), make sure you annotate them with @ApplicationException. This will ensure that the MDB instance is not discarded in case of an exception.

For optimum performance under heavy loads, you would want to have as many MDBs in the pool as possible. In such a case you would want to avoid MDB instances being destroyed due to excpetions. Sensible exception handling can help you realize this goal. It is simple as annotating your exception class with @ApplicationException and leaving the rest to the container

Moving on...

Let's explore the security related annotations and how they can help secure EJBs

Last updated