Anwendungsausnahmen
Mit Anwendungsausnahmen werden dem Client anwendungsspezifische Probleme oder Probleme der Geschäftslogik gemeldet Ausnahmen auf Systemebene werden nicht gemeldet. Dieser Abschnitt enthält eine kurze Übersicht über das Definieren von Anwendungsausnahmen und Beispiele für die Annotation @ApplicationException sowie das entsprechende Implementierungsdeskriptorelement application-exception.
Definition von Anwendungsausnahmen
Bean-Provider definieren Anwendungsausnahmen im Rahmen der Geschäftslogik einer Anwendung. Anwendungsausnahmen werden im Gegensatz zu Systemausnahmen nicht verwendet, um Fehler auf Systemebene zu melden. Geschäftsmethoden verwenden Anwendungsmethoden dagegen, um den Client über die Aktivität auf Anwendungsebene zu informieren, die Fehler auslösten könnte, z. B. über ungültige Werte von Argumenten, die für eine Geschäftsmethode eingegeben werden. In den meisten Fällen können Clients nach Anwendungsausnahmen die normale Verarbeitung wiederaufnehmen.
Sie können Anwendungsausnahmen in der throws-Klausel einer Methode definieren. Bei der Methode, in der Sie die Anwendungsausnahme definieren, kann es sich um die Methode einer Geschäftsschnittstelle, einer Sicht ohne Schnittstelle, einer Home-Schnittstelle, einer Komponentenschnittstelle, einer Nachrichtenlistenerschnittstelle oder eines Web-Service-Endpunkt der Enterprise-Bean handeln. Wenn Sie die Anwendungsausnahme definieren, denken Sie daran, dass die Ausnahme eine der folgenden Unterklassen sein kann:
- Eine direkte oder indirekte Unterklasse der Ausnahme java.lang.Exception, die eine geprüfte Ausnahme wiedergibt
- Eine Unterklasse der Ausnahme java.lang.RuntimeException, die eine ungeprüfte Ausnahme wiedergibt
Die folgenden Standardanwendungsausnahmen werden mit den zugehörigen Unterklassen verwendet, um den Client über Fehler zu informieren:
- javax.ejb.CreateException
- javax.ejb.RemoveException
- javax.ejb.FinderException
Die obigen Anwendungsausnahmen werden in den Methoden create, remove und finder der EJBHome-Schnittstelle und/oder der EJBLocalHome-Schnittstelle definiert. Diese Schnittstellen stammen von Komponenten, die für die EJB-2.1-Clientsicht geschrieben wurden.
In der Spezifikation Enterprise Java™Beans 3.0 gab es für die Annotation @ApplicationException nur den Parameter "rollback". Das entsprechende Element application-exception hatte nur ein optionales Unterelement "rollback", das auf true oder false gesetzt werden konnte. Mit dem Parameter/Unterelement "rollback" wird angegeben, ob die Transaktion für ein Rollback markiert ist. Die Standardeinstellung ist "false". Die Vererbung einer Anwendungsausnahme konnte nicht angegeben werden, da die Spezifikation EJB 3.0 keinen expliziten Standardwert hierfür vorsah. Die Implementierung der Spezifikation EJB 3.0 durch das Produkt sah eine Vererbung von Anwendungsausnahmen nur vor, wenn in der Klausel throws einer Bean-Geschäftsmethode eine Anwendungsausnahme definiert ist. Mit der Spezifikation EJB 3.1 wurden nun der optionale Parameter inherited für die Annotation @ApplicationException und das optionale Unterelement inherited für das entsprechende Element application-exception des Implementierungsdeskriptors eingeführt. Wenn eine standardmäßig als Anwendungsausnahme markiert wird, werden standardmäßig alle Unterklassen dieser Ausnahme auch zu Anwendungsausnahmen (d. h., es gilt inherited=true). Sie können das Vererbungsverhalten inaktivieren, indem Sie den Parameter inherited von @ApplicationException auf false setzen. Sie können das Vererbungsverhalten auch inaktivieren, indem Sie das Unterelement inherited des Elements application-exception im Implementierungsdeskriptor auf false setzen. Weitere Informationen zu Anwendungsausnahmen enthält der Abschnitt 14.1.1 der Spezifikation EJB 3.1.
Beispiel: Vererbung von Anwendungsausnahmen mithilfe von Annotationen
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
}
Das obige Beispiel führt zu folgenden Ergebnissen:
- RTExceptionA ist eine Anwendungsausnahme mit Rollback der Transaktion.
- RTExceptionB ist eine Anwendungsausnahme mit Rollback der Transaktion.
- RTExceptionC ist eine Anwendungsausnahme ohne Rollback der Transaktion.
- RTExceptionD ist keine Anwendungsausnahme.
Beispiel: Vererbung von Anwendungsausnahmen mithilfe von 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
}
<!-- Beispiel für 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>
Das obige Beispiel führt wie bei der Annotationsversion zu folgenden Ergebnissen:
- RTExceptionA ist eine Anwendungsausnahme mit Rollback der Transaktion.
- RTExceptionB ist eine Anwendungsausnahme mit Rollback der Transaktion.
- RTExceptionC ist eine Anwendungsausnahme ohne Rollback der Transaktion.
- RTExceptionD ist keine Anwendungsausnahme.
Wenn Sie in der throws-Klausel einer Bean-Geschäftsmethode eine Ausnahme angeben, ist die resultierende geprüfte Ausnahme eine Anwendungsausnahme. Alle Unterklassen dieser Anwendungsausnahme sind ebenfalls Anwendungsausnahmen. Dieses Vererbungsverhalten von geprüften Anwendungsausnahmen kann nicht inaktiviert werden. Mit dem Element inherited können Sie den Rollback-Wert der Unterklassen von geprüften Anwendungsausnahmen festlegen. Ist das Element inherited der geprüften Anwendungsausnahme auf true und das zugehörige Element rollback auf true gesetzt, erbt die Unterklasse dieser geprüften Anwendungsausnahme die Einstellung rollback = true.
Vererbungsverhalten von Anwendungsausnahmen gemäß EJB 3.0 abrufen
- Sie können die Annotation @ApplicationException der Ausnahme modifizieren, indem Sie das Attribut inherited hinzufügen und dieses auf false setzen.
- Sie können einen Implementierungsdeskriptor der Version 3.1 hinzufügen und das Unterelement inherited des Elements application-exception explizit auf false setzen. Falls ein Implementierungsdeskriptor der Version 3.0 vorhanden ist, müssen Sie diesen auf einen Implementierungsdeskriptor der Version 3.1 und ein XSD-Schema migrieren und das Unterelement "inherited" des Elements "application-exception" auf false setzen.
Beispiel: Vererbungsverhalten von Anwendungsausnahmen gemäß EJB 3.0 mithilfe von Annotationen abrufen
Angenommen, Sie verfügen über den folgenden Code:
import javax.ejb.ApplicationException;
@ApplicationException()
public class EJB30_RTException extends RuntimeException{
// EJB30_RTException - In EJB 3.0 sind Unterklassen keine Anwendungsausnahmen.
}
Sie müssen die Annotation @ApplicationException so modifizieren, dass sie das Attribut inherited=false enthält:
import javax.ejb.ApplicationException;
@ApplicationException(inherited=false)
public class EJB30_RTException extends RuntimeException{
// EJB30_RTException - Sie müssen inherited explizit auf false setzen, um die Vererbung zu inaktivieren.
}
Beispiel: Vererbungsverhalten von Anwendungsausnahmen gemäß EJB 3.0 mithilfe von XML abrufen
Angenommen, Sie verfügen über den folgenden Code:
<!-- Beispiel für 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>
Sie müssen Ihren Code so modifizieren, dass er das auf false gesetzte Element inherited enthält und eine Migration auf einen Implementierungsdeskriptor der Version 3.1 und ein XSD-Schema durchführen:
<!-- Beispiel für 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>