Exceções de Aplicativo
Exceções de aplicativo alertam o cliente de problemas de lógica de negócios ou específicos de aplicativos; elas não relatam exceções no nível do sistema. Este tópico inclui uma visão geral resumida de como as exceções de aplicativos são definidas, além de exemplos da anotação @ApplicationException e do elemento do descritor de implementação application-exception correspondente.
Definição da Exceção do Aplicativo
Provedores de bean definem exceções de aplicativo junto com a lógica de negócios de um aplicativo. Ao contrário de exceções do sistema, as exceções de aplicativo não são usadas para relatar erros no nível do sistema. Em vez disso, os métodos de negócios usam exceções de aplicativo para notificar o cliente da atividade no nível do aplicativo que pode causar erros; por exemplo, valores de argumento de entrada inválidos para um método de negócios. Na maioria dos casos, os clientes podem retornar ao processamento normal após enfrentarem exceções de aplicativo
É possível definir exceções de aplicativo na cláusula de lançamento de um método. O método usado para definir a exceção de aplicativo pode ser o de uma interface de negócios, visualização sem interface, interface inicial, interface do componente, interface do listener de mensagem ou terminal de serviço da Web do enterprise bean. Ao definir a exceção, lembre-se de que as exceções de aplicativo podem ser:
- Uma subclasse, direta ou indireta, da exceção java.lang.Exception, que renderiza uma exceção verificada
- Uma subclasse da exceção java.lang.RuntimeException, que renderiza uma exceção não verificada
As exceções de aplicativo padrão a seguir e suas subclasses são usadas para relatar erros ao cliente:
- javax.ejb.CreateException
- javax.ejb.RemoveException
- javax.ejb.FinderException
As exceções de aplicativo anteriores definidas nos métodos create, remove e finder da interface EJBHome, interface EJBLocalHome, ou ambas. Essas interfaces são provenientes de componentes que são gravados na visualização do cliente EJB 2.1.
Na especificação Enterprise Java™ Beans 3.0, a anotação @ApplicationException tinha apenas um parâmetro opcional de retrocesso. O elemento application-exception correspondente tinha apenas um subelemento opcional, rollback, que você configura como true ou false. O parâmetro/subelemento rollback é usado para especificar se a transação está marcada para retrocesso. Por padrão, esse valor é false. A herança de uma exceção de aplicativo não pôde ser especificada e não recebeu um valor padrão explícito na especificação EJB 3.0. A implementação do produto da especificação EJB 3.0 não forneceu uma herança de exceção de aplicativo, a menos que uma exceção de aplicativo tenha sido definida na cláusula throws de um método de negócios de um bean. Em contraste, a especificação EJB introduziu o parâmetro inherited opcional na anotação @ApplicationException e o subelemento inherited opcional no elemento do descritor de implementação application-exception correspondente. Por padrão, a marcação de uma exceção como uma exceção de aplicativo faz com que todas as subclasses dessa exceção também sejam exceções de aplicativo (ou seja, inherited=true). É possível desativar o comportamento de herança configurando o parâmetro inherited da @ApplicationException como false. Da mesma forma, é possível desativar o comportamento de herança configurando o subelemento inherited do elemento application-exception no descritor de implementação como false. Para obter informações adicionais sobre exceções de aplicativo, consulte a seção 14.1.1 da especificação EJB 3.1.
Exemplo: Exceções de aplicativo herdado utilizando anotações
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
}
O exemplo anterior produz os seguintes resultados:
- RTExceptionA é uma exceção de aplicativo com retrocesso de transação.
- RTExceptionB é uma exceção de aplicativo com retrocesso de transação.
- RTExceptionC é uma exceção de aplicativo sem retrocesso de transação.
- RTExceptionD não é uma exceção de aplicativo.
Exemplo: Exceções de aplicativo herdado usando 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
}
<!-- Exemplo de 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>
Como na versão da anotação, o exemplo anterior produz os seguintes resultados:
- RTExceptionA é uma exceção de aplicativo com retrocesso de transação.
- RTExceptionB é uma exceção de aplicativo com retrocesso de transação.
- RTExceptionC é uma exceção de aplicativo sem retrocesso de transação.
- RTExceptionD não é uma exceção de aplicativo.
Quando você especifica uma exceção na cláusula de lançamento de um método de negócios de um bean, a exceção verificada resultante é uma exceção de aplicativo. Todas as subclasses dessa exceção de aplicativo também são exceções de aplicativo. Nenhuma opção está disponível para desativar esse comportamento de herança das exceções de aplicativo verificadas. É possível usar o elemento inherited para determinar o valor de retrocesso das subclasses da exceção do aplicativo verificada. Se o elemento inherited da exceção de aplicativo verificada for configurado como true e seu elemento rollback for configurado como true, as subclasses dessa exceção de aplicativo verificada herdarão o valor rollback = true.
Obtendo o Comportamento de Herança de Exceção do Aplicativo EJB 3.0:
- É possível modificar a anotação @ApplicationException da exceção incluindo o atributo inherited e configurando-a como false.
- É possível incluir um descritor de implementação versão 3.1 e configurar explicitamente o subelemento inherited do elemento application-exception como false. Se tiver um descritor de implementação da versão 3.0 existente, você deverá migrar para um descritor de implementação e esquema XSD da versão 3.1 e configurar o elemento subelemento herdado de application-exception como false.
Exemplo: Obtendo o comportamento de herança de exceção do aplicativo EJB 3.0 com anotações
Suponha que você tinha anteriormente o seguinte código:
import javax.ejb.ApplicationException;
@ApplicationException()
public class EJB30_RTException extends RuntimeException{
//EJB30_RTException, no EJB 3.0, as subclasses não eram exceções de aplicativo
}
Você deve modificar a anotação @ApplicationException para incluir o atributo inherited=false:
import javax.ejb.ApplicationException;
@ApplicationException(inherited=false)
public class EJB30_RTException extends RuntimeException{
//EJB30_RTException, agora você deve configurar herdado explicitamente como false para desativar a herança
}
Exemplo: Obtendo o comportamento de herança de exceção do aplicativo EJB 3.0 usando XML
Suponha que você tinha anteriormente o seguinte código:
<!-- Exemplo de 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>
Você deve modificar seu código para incluir o elemento inherited configurado como false, bem como migrar para um esquema XSD e descritor de implementação versão 3.1:
<!-- Exemplo de 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>