Application exceptions
Application exceptions alert the client of application specific or business logic issues; they do not report system level exceptions. This topic includes a brief overview of how application exceptions are defined and examples of the @ApplicationException annotation and corresponding application-exception deployment descriptor element.
Definition of Application Exception
Bean providers define application exceptions along with the business logic of an application. Unlike system exceptions, application exceptions are not used to report system-level errors. Instead, business methods use application exceptions to notify the client of application-level activity that might cause errors; for example, invalid input argument values to a business method. In most cases, clients can return to normal processing after experiencing application exceptions
We can define application exceptions in the throws clause of a method. The method used to define the application exception can be that of a business interface, no-interface view, home interface, component interface, message listener interface, or web service endpoint of the enterprise bean. When defining the exception, remember that application exceptions can be:
- A subclass, either direct or indirect, of the java.lang.Exception exception, which renders a checked exception
- A subclass of the java.lang.RuntimeException exception, which renders an unchecked exception
We cannot define an application exception as a subclass of java.rmi.RemoteException because this exception and its subclasses are for system-level problems.
The following standard application exceptions and their subclasses are used to report errors to the client:
- javax.ejb.CreateException
- javax.ejb.RemoveException
- javax.ejb.FinderException
The previous application exceptions are defined in the create, remove, and finder methods of the EJBHome interface, the EJBLocalHome interface, or both. These interfaces come from components that are written to the EJB 2.1 client view.
In the Enterprise Java beans 3.0 specification, the @ApplicationException annotation had only one optional parameter of rollback. The corresponding application-exception element had only one optional subelement, rollback, that we set to true or false. The rollback parameter/subelement specifies whether the transaction is marked for rollback. By default this value is false. Inheritance of an application exception could not be specified and was not given an explicit default value in the EJB 3.0 specification. The product implementation of the EJB 3.0 specification did not provide application exception inheritance, unless an application exception was defined on the throws clause of a business method of a bean. In contrast, the EJB 3.1 specification has introduced the optional inherited parameter to the @ApplicationException annotation and the optional inherited subelement to the corresponding application-exception deployment descriptor element. By default, marking an exception as an application exception causes all subclasses of that exception to also be application exceptions (that is, inherited=true). We can disable the inheriting behavior by setting the inherited parameter of the @ApplicationException to false. Likewise, we can disable the inheriting behavior by setting the inherited subelement of the application-exception element in the deployment descriptor to false. For more information about application exceptions, refer to section 14.1.1 of the EJB 3.1 specification.
Example: Inherited application exceptions using annotations
import javax.ejb.ApplicationException; @ApplicationException(inherited=true, rollback=true) public class RTExceptionA extends RuntimeException{ //RTExceptionA }public class RTExceptionB extends RTExceptionA{ //RTExceptionB }import javax.ejb.ApplicationException; @ApplicationException(inherited=false, rollback=false) public class RTExceptionC extends RTExceptionB{ //RTExceptionC }public class RTExceptionD extends RTExceptionC{ //RTExceptionD }The previous example yields the following results:
- RTExceptionA is an application exception with transaction rollback.
- RTExceptionB is an application exception with transaction rollback.
- RTExceptionC is an application exception without transaction rollback.
- RTExceptionD is not an application exception.
Example: Inherited application exceptions using XML
public class RTExceptionA extends RuntimeException{ //RTExceptionA }public class RTExceptionB extends RTExceptionA{ //RTExceptionB }public class RTExceptionC extends RTExceptionB{ //RTExceptionC }public class RTExceptionD extends RTExceptionC{ //RTExceptionD }<!-- Example ejb-jar.xml --> <?xml version="1.0" encoding="UTF-8"?> <ejb-jar id="ejb-jar_ID" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd" metadata-complete="true" version="3.1"> <assembly-descriptor> <application-exception> <exception-class>myXML.example.package.RTExceptionA</exception-class> <rollback>true</rollback> <inherited>true</inherited> </application-exception> <application-exception> <exception-class>myXML.example.package.RTExceptionC</exception-class> <rollback>false</rollback> <inherited>false</inherited> </application-exception> </assembly-descriptor> </ejb-jar>As in the annotation version, the previous example yields the following results:
- RTExceptionA is an application exception with transaction rollback.
- RTExceptionB is an application exception with transaction rollback.
- RTExceptionC is an application exception without transaction rollback.
- RTExceptionD is not an application exception.
Remember: Use the rollback and inherited subelements of the application-exception to explicitly override the rollback and inherited attribute values that were specified or implicitly set by the @ApplicationException annotation.
When we specify an exception on the throws clause of a business method of a bean, the resulting checked exception is an application exception. All subclasses of this application exception are also application exceptions. No option is available to disable this inheriting behavior of checked application exceptions. Use the inherited element to determine the rollback value of the checked application exception subclasses. If the inherited element of the checked application exception is set to true and its rollback element is set to true, then the subclasses of that checked application exception inherit the rollback = true value.
Getting EJB 3.0 application exception inheritance behavior:
We have the following options if we have an existing EJB 3.0 application and we want to continue having the application exception inheritance behavior be false, which means that the subclasses of an application exception are not application exceptions themselves.
- We can modify the exception's @ApplicationException annotation of the exception by adding the inherited attribute and setting it to false.
- We can add a version 3.1 deployment descriptor and explicitly set the inherited subelement of the application-exception element to false. If we have an existing version 3.0 deployment descriptor we must migrate to a version 3.1 deployment descriptor and XSD schema and set the inherited subelement of the application-exception element to false.
Example: Getting EJB 3.0 application exception inheritance behavior with annotations
Suppose that we previously had the following code:
import javax.ejb.ApplicationException; @ApplicationException() public class EJB30_RTException extends RuntimeException{ //EJB30_RTException, in EJB 3.0 subclasses were not application exceptions }We must modify the @ApplicationException annotation to include the inherited=false attribute:
import javax.ejb.ApplicationException; @ApplicationException(inherited=false) public class EJB30_RTException extends RuntimeException{ //EJB30_RTException, now we must explicitly set inherited to false to disable inheritance }
Example: Getting EJB 3.0 application exception inheritance behavior using XML
Suppose that we previously had the following code:
<!-- Example ejb-jar.xml --> <?xml version="1.0" encoding="UTF-8"?> <ejb-jar id="ejb-jar_ID" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd" metadata-complete="true" version="3.0"> <assembly-descriptor> <application-exception> <exception-class>myXML.example.package.EJB30_RTException</exception-class> </application-exception> </assembly-descriptor> </ejb-jar>We must modify the code to include the inherited element set to false as well as migrate to a version 3.1 deployment descriptor and XSD schema:
<!-- Example ejb-jar.xml --> <?xml version="1.0" encoding="UTF-8"?> <ejb-jar id="ejb-jar_ID" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd" metadata-complete="true" version="3.1"> <assembly-descriptor> <application-exception> <exception-class>myXML.example.package.EJB30_RTException</exception-class> <rollback>false</rollback> <inherited>false</inherited> </application-exception> </assembly-descriptor> </ejb-jar>
EJB metadata annotations Developing enterprise beans