Java EE Exceptions

Em complemento ao meu post anterior sobre tratamento de exceções, quero neste post focar em Java EE Exceptions.

As exceções Java EE se dividem em duas categorias básicas: System Exceptions e Applicatipon Exceptions. A grosso modo, uma System Exception (SE) é qualquer exceção que estenda a classe java.lang.RuntimeException enquanto que Application Exception (AE) é qualquer derivada de java.lang.Exception. Cada uma possui um conjunto de peculiaridades que dizem respeito à forma com que elas serão capturadas, encapsuladas e eventualmente repassadas para o cliente.

Application Exceptions

Uma AE pode ser qualquer tipo de exceção que estenda a classe java.lang.Exception como o exemplo a seguir:

public class MyAppException extends Exception {}

Para lançá-la, o método deve explicitamente declarar que o faz, utilizando a cláusula throws.

public void someMethod() throws MyAppException {
    // ...
}

A principal característica desse tipo de exceção é que ela será entregue ao cliente exatamente como ela foi lançada e, em contrapartida, fará com que o cliente explicitamente utilize um bloco try-catch para executar a chamada do método.

System Exceptions

As SE são as exceções que derivam da classe java.lang.RuntimeException (RTE).

public MySysException extends RuntimeException {}

Por se tratar de uma RTE, o método que a lança não precisa explicitamente declarar que o faz e o cliente também não necessariamente precisa executar a chamada dentro de um bloco try-catch. Quando um método lança uma SE, o container deve tomar algumas precauções importantes em relação ao EJB que a lança: se for um session bean (stateless ou stateful) ou um MDB, a instância que a lançou é destruída e a transação subjacente (se houver) será revertida (rolled-back). Essa é a diferença principal entre AEs e SEs. Enquanto que as AE são entregues para o cliente em seu estado original e sem forçar com que o container tome quaisquer medidas em relação à instâncias ou transações, as SEs sim o fazem.

Ainda quanto as SEs, o container irá encapsular a exceção original (a que foi lançada) em um javax.ejb.EJBException antes de entregá-la para o cliente.

A anotação @ApplicationException

A anotação @javax.ejb.ApplicationException serve para misturar os dois mundos. Por exemplo: ao utilizá-la em uma exceção do tipo RTE, faz com que ela seja tratada com exceção de aplicação:

@ApplicationException
public MySysException extends RuntimeException {}

Desta forma, sempre que um método lançar uma MySysException, o container irá se comportar da mesma forma com que se comporta em relação as AE convencionais  subclasses diretas de Exception  entregando a exceção original para o cliente (sem encapsulá-la em EJBException) e não tomando qualquer medida no sentido de destruir instância do EJB que a lançou ou reverter a transação subjacente.

A anotação ainda especifica um atributo boolean denominado rollback. Este atributo serve para indicar ao container se a transação deve ou não ser revertida.

@ApplicationException(rollback=true)
public MyAEException extends RuntimeException {}

A qualquer momento que uma instância da exceção MyAEException for lançada, ela fará com que a transação envolvida seja revertida.

Resumidamente é isso.
Até o próximo.