
| Java Specification Request (JSR) JSR kennzeichnet eine Anforderung für eine Änderung der Programmier- sprache Java, die vom Standardisierungskomitee, dem Java Community Process, eingebracht wird. |
| Doclet Als Doclet bezeichnet man - in Anlehnung an Applet - Module, die von Dokumen- tationswerkzeugen zur Verarbeitung und automa- tischen Erzeugung von Dokumentationen und eventuell auch Code eingesetzt werden. Bekannt sind Doclets insbesondere im Umfeld der Programmier- sprache Java, wo sie als Module im Dokumentations- werkzeug Java-Doc eingesetzt werden. |
Weiterführende Links
Kritiker von Enterprise Java Beans (EJB) gibt es viele - wohl manchmal auch zu recht. Dabei ist einer der erstgenannten Kritikpunkte, dass für die Implementierung einer simplen EJB 2.0 Anwendung sieben Dateien und mehr erstellt und gepflegt werden müssen (siehe Abbildung 1).
|
| Abb. 1: Mögliche Artefakte von EJB 2.0. |
Neben der eigentlichen Bean verlangen bis zu vier Java-Interfaces sowie zwei Deployment-Deskriptoren die Aufmerksamkeit des Programmierers. Diese Artefakte der EJB-Spezifikation sind anfällig für Fehler und Unachtsamkeiten. Zudem treten viele damit verbundenen Fehler erst beim Deployment in den Applikationsserver auf.
Für den Java-Compiler ist es zudem noch kein Grund, beim Übersetzungsvorgang einen Fehler anzuzeigen, wenn sich die throws-Klauseln einer Methode der eigentlichen Bean von denen des EJB Remote Interfaces unterscheiden.
Wurde hier in der eigentlichen Bean ein Exception-Wurf verzeichnet, jedoch nicht im EJB Remote Interface, wird dieser Verstoß gegen die J2EE-Spezifikation meist erst beim Deployment in den Applikationsserver als Fehler erkannt.
Eine neu implementierte Methode, zu der in den Deployment-Deskriptoren die Angaben für das Verhalten zu Datenbanktransaktionen nicht korrekt definiert sind, zeigt meist erst bei kontrollierten Fehlerfällen ihre fatalen Auswirkungen auf die Konsistenz der Datenbestände. Eine halb durchgeführte Kontobuchung wäre sicher ein mögliches Worst-Case-Szenario.
Gerne wird bei der Implementierung von neuer Geschäftslogik auch die korrekte Definition der JAAS-Einstellungen der EJB vergessen.
Auswirkungen können sein, dass z. B. ein in der Software abgebildeter Geschäftsvorfall nicht für alle beteiligten Nutzer zur Verfügung steht und der Container das Ansprechen der Schnittstelle mit einer java.lang.SecurityException verweigert.
Für den Programmierer sind die EJB-Artefakte einer einzigen, zu implementierenden EJB-Methode (z. B. einer Stateless Session Bean) nicht alle auf einen Blick verfügbar. Sie müssen an diversen Stellen in XML und in separatem Java-Code gepflegt werden.
In den letzten Jahren haben sich in der Softwareentwicklung diverse Verfahren herausgebildet, um diese Hindernisse bei der EJB 2.0 Entwicklung zu reduzieren. Alle modernen, integrierten Entwicklungsumgebungen unterstützen den Entwickler bereits bei der Einhaltung diverser J2EE-Spezifikationen.
So werden mit Eclipse oder IDEA IntelliJ bei Refactorings der EJB-Methoden auch die jeweiligen Stellen in den EJB-Interfaces angepasst, obwohl diese nicht in direkter Implementierungsbeziehung zu dieser Bean stehen. Anstatt die Einstellungen der Deployment-Deskriptoren umständlich über XML zu regeln, lassen sie sich zudem auch zentral über eine GUI steuern.
Jenseits einer IDE hat sich im Open Source Bereich XDoclet als ungeschriebener Standard zur Pflege von EJB-Artefakten durchgesetzt.
XDoclet ist ein Code-Generierungstool, das als Plugin für JavaDoc mit Hilfe von ant ausgeführt werden kann.
Mit XDoclet hatte man ursprünglich genau jene EJB-Artefakte im Visier, die eine EJB-Entwicklung bislang unnötig erschwerte: XDoclet generiert die oben erwähnten, ungeliebten Artefakte (in Form von Text, XML- und Java-Quellcode) mit Hilfe von Auszeichnungen (Tags) innerhalb von Java-Kommentaren zu Klassen und Methoden.
Die Anwendung von XDoclet folgt dabei dem gleichen Prinzip, wie es zur Erstellung einer aussagekräftigen API-Dokumentation notwendig ist: Es werden im Java-Kommentar von Klassen, Methoden und Attributen spezielle Anmerkungen (Tags) vorgenommen, die das jeweilige Element speziell auszeichnen.
Soll in der API-Dokumentation beispielsweise für eine Klasse ein Autor benannt sein, lässt sich im Java-Kommentar der Klasse das Tag @author Autorname einfügen, um die Information über einen Autor der Klasse in die Dokumentation einfließen zu lassen.
Auf XDoclet übertragen fügt man so im Kommentar einer Klasse z. B. die Anmerkung @ejb.bean type="Stateless" ein, um XDoclet mitzuteilen, dass bei der javaDoc-Prozessierung dieser Klasse die EJB-Artefakte einer Stateless Session EJB generiert werden sollen.
Über Tags lassen sich so alle benötigten Zusatzinformationen angeben, die zur Erstellung von gültigen EJB-Artefakten notwendig sind.
Innerhalb der Steuerskripte für die Laufzeitumgebung ant oder über die Java-Umgebungsvariablen lassen sich zusätzlich Einstellungen für den Generierungsvorgang von XDoclet vorgeben. Sie definieren, was alles von XDoclet generiert werden soll. Hier lässt sich festlegen, ob definierte XDoclet-Tags ausgewertet und wo z. B. generierte Quellen abgelegt werden sollen.
XDoclet folgt den Ansprüchen zur Generierung von Quellen und Metadaten unterschiedlichen Typs. So können neben dem EJB-Umfeld auch Quellen und Metadaten für JMX, Spring, Tapestry, Hibernate oder JDO erzeugt werden.
Selbst in komplexeren Code-Generierungsszenarien, die einem modellzentrierten Software-Entwicklungsansatz folgen, findet XDoclet seinen Einsatz. Mit Tools wie AndroMDA oder Middlegen lassen sich auf der Grundlage eines Datenmodells Quelldateien erzeugen, die um XDoclet-Tags angereichert sind. Mit XDoclet lassen sich über diese Quelldateien fertige Software-Bausteine generieren [1].
Zu XDoclet gibt es auch eine alternative, erweiterte Implementierung: XDoclet2. Im Wesentlichen unterscheidet sie sich von der Vorversion durch diverse Verbesserungen bei der Unterstützung von Hibernate. Es gibt aber auch Verschlechterungen: In einigen Bereichen fehlen XDoclet2 einige Funktionalitäten der früheren Version. Zudem unterstützt auch XDoclet2 noch nicht die neuen Features von Java 5.
Mit Java 5 wird das Prinzip der Auszeichnungen von Xdoclet im Standard "JSR 175 Metadata Annotations" auf die elementare Sprachebene von Java gebracht. Annotationen liegen nicht mehr innerhalb von Kommentaren als Bestandteil der Dokumentation, sondern sind nun echte Metadaten als Bestandteil des Quelltextes.
Im Gegensatz zu den rein textbasierten JavaDoc-Kommentaren, deren Verhalten in den JavaDoc-Plugins bzw. in XDoclet implementiert ist, kommt mit den JSR-175-Annotationen ein stark typisiertes Verfahren daher. Jede Annotation wird durch ein eigenes Sprachelement, den Annotation-Typ, beschrieben. Dieser steht auf einer sprachlichen Stufe mit den anderen, syntaktischen Elementen, wie Interface, Klasse etc.
Damit einher gehen der Vorteil der Syntaxprüfung beim Übersetzungsvorgang und die Möglichkeit der Erweiterbarkeit um eigene, z. B. projektspezifische, Annotationen. Im Gegensatz zu XDoclet-Annotationen können Java-Annotationen direkt in die Java-Klasse mit einkompiliert werden. Sie sind anschließend derart mit der Klasse verbunden, dass sie auch noch zur Laufzeit per Reflection abgefragt werden können.
Im (künftigen) Standard EJB 3.0 (JSR-220) wird von den Java-Annotationen rege Gebrauch gemacht. Alle Metadaten lassen sich mit Hilfe der neu eingeführten Java-Annotationen beschreiben. Wurde ein bestimmter Wert nicht definiert, greift ein Standard. Bei der Entwicklung kann nun prinzipiell komplett auf XML-Deployment-Deskriptoren verzichtet werden. Der Verzicht ist jedoch nicht zwingend erforderlich. Jede EJB 3.0-Metainformation kann immer noch in gesonderten Deployment-Deskriptoren definiert werden und überschreibt somit die am Quellcode vorgenommene Auszeichnung.
Die althergebrachten, von Sun definierten, EJB-Zuständigkeitsbereiche wie z. B. "Application Component Provider", "Application Assembler" und "Application Deployer" sind damit immer noch gültig. Gerade dies wurde ja vor einigen Jahren als großer Vorteil der EJB-Komponentenentwicklung gefeiert. Eine Software-Komponente, die eigene JAAS-Rollen verwendet, kann nun z. B. immer noch über die Anpassung der Deployment-Deskriptoren in die JAAS-Umgebung einer bestehenden EJB-Anwendung integriert werden.
Es sollte gut überlegt sein, welche Metainformationen direkt mit dem Quellcode verbunden werden. Von der Laufzeitumgebung abhängige Eigenschaften, wie der JNDI-Name einer Datenbank-Ressource, werden sicher besser immer in einem XML-Deployment-Deskriptor definiert. Hierzu siehe auch den empfehlenswerten Artikel unter [2].
Dem Entwickler wird die hohe Ähnlichkeit von EJB 3.0 Annotationen mit XDoclet Annotationen für Hibernate auffallen. Kein Wunder, denn die Entwickler von Hibernate sind doch an der Definition des Standards beteiligt und die Erfahrungen aus den Open Source Tools Hibernate und XDoclet in die Spezifikation eingeflossen.
So ist ein Vergleich dieser Tools mit dem neuen Standard nicht abwegig. Im Folgenden sei ein näherer Blick auf die Implementierungsunterschiede der beiden Technologien im Quellcode gewagt.
Auf Grundlage der aktuellen JBoss-Version (4.0.4.GA) und der dafür verfügbaren, vorläufigen EJB 3.0 Implementierung soll ein kleiner Vergleich mit einer einfachen Stateless Session Bean unter EJB 2.x mit XDoclet und EJB 3.0 gezeigt werden. Das Augenmerk liegt hier besonders auf dem Prinzip der Annotationen sowie auf den Artefakten, die in den unterschiedlichen EJB-Versionen benötigt werden.
Im Folgenden wird dazu der Quellcode einer einfachen Stateless Session EJB gezeigt, die die beiden im EJB-Interface zu veröffentlichenden Methoden String doSomeAction() und int getCount() enthält. Die Implementierung dieser Methoden enthält keine Logik. Für den Vergleich mit Blick auf Annotationen und Artefakte ist dies auch nicht nötig. Für das Beispiel wird die Bean um die jeweiligen Metainformationen zu Transaktions- und Sicherheitseinstellungen erweitert.
Es fallen die großen Ähnlichkeiten der beiden Auszeichnungsvarianten auf (siehe Abbildung 2), wenngleich die zugrundeliegenden, technischen Unterschiede immens sind. Der EJB 2.x Entwickler bemerkt, dass die Session-Bean des XDoclet-Beispiels abstrakt deklariert ist und nicht die für EJB 2.x obligatorischen Methoden des SessionBean Interfaces implementiert.
| Um XDoclet-Tags angereicherter Quellcode |
package ordix.xdoclet.ejb;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.ejb.CreateException;
import javax.ejb.EJBException;
import java.rmi.RemoteException;
/**
* Diese Klasse ist ein Beispiel für die XDoclet-Nutzung
*
* @ejb.bean name="FooFacadeBean" type="Stateless"
* view-type="both" transaction-type="Container"
*/
public abstract class FooFacadeBean implements SessionBean {
/**
* @ejb.interface-method
* @ejb.permission unchecked="true"
* @ejb.transaction type="Required"
*/
public String doSomeAction() { return "I made it."; }
/**
* @ejb.interface-method
* @ejb.transaction type="RequiresNew"
* @ejb.permission role-name="Administrator"
*/
public int getCount() { return 68; }
}
|
| Um EJB 3.0 Annotationen angereicherter Quellcode (in aktueller JBoss EJB 3.0 Implementierung) |
package ordix.EJB 3.0.ejb;
import org.jboss.aspects.security.Unchecked;
import org.jboss.annotation.security.SecurityDomain;
import java.rmi.RemoteException;
import javax.ejb.*;
import javax.annotation.security.RolesAllowed;
/**
* Diese Klasse ist ein Beispiel für die EJB 3.0-Nutzung
*/
@Stateless
public class FooFacadeBean
implements FooFacade {
@TransactionAttribute
(TransactionAttributeType.REQUIRED)
@Unchecked
public String doSomeAction() { return "I made it."; }
@TransactionAttribute
|
| Abb. 2: Die Implementierungsunterschiede im Quellcode der beiden Technologien im Vergleich. |
Erst beim Generierungsvorgang von XDoclet wird eine konkrete Implementierung erzeugt, die auch die Servicemethoden wie ejbStart(), ejbStop() oder setSessionContext() enthält. Auf die erzeugte Bean-Implementierung wird dann in den generierten Deployment-Deskriptoren verwiesen.
Betrachtet man die verwendeten Auszeichnungen, fallen Ähnlichkeiten auf. XDoclet erwartet als Auszeichnung einer zu prozessierenden EJB das Tag @ejb.bean, bei dem als Attribut definiert ist, um welchen Typ von EJB (hier Stateless Session Bean) es sich handelt.
Unter EJB 3.0 wird das Gleiche durch die Annotation @Stateless erreicht. Sofern hier nichts weiter definiert wurde, greifen Standardwerte, die im JBoss z. B. die EJB unter dem JNDI-Pfad mit dem Namen der Klasse ablegt. In unserem Vergleich in Abbildung 2 lautet der JNDI-Pfad /FooFacadeBean.
Unter XDoclet muss jede Methode, die in den EJB-Interfaces publiziert werden soll, durch das Tag @ejb.interface-method ausgezeichnet werden. In EJB 3.0 passiert das Gleiche durch die Deklaration in dem implementierten Interface. Hier werden standardmäßig alle Methoden-Interfaces als zu veröffentlichende EJB-Methoden verwendet.
Auch bei den Sicherheitseinstellungen und bei der Transaktionssteuerung entdeckt man Ähnlichkeiten. Verwendet XDoclet das Tag @ejb.permission mit dem Attribut unchecked, um eine Methode als ungeprüft im Sicherheitskontext zu kennzeichnen, macht es in EJB 3.0 die Annotation @Unchecked. Das EJB 3.0 Äquivalent zum XDoclet Tag @ejb.transaction type="Required" ist in der Annotation @TransactionAttribute (TransactionAttributeType.REQUIRED)zu finden.
|
+---META_INF
| ejb-jar.xml
| jboss.xml
|
\---ordix
\---xdoclet
+---ejb
| FooFacadeBean.java
| FooFacadeSession.java
|
+---interfaces
| FooFacade.java
| FooFacadeHome.java
| FooFacadeLocal.java
| FooFacadeLocalHome.java
\---util
FooFacadeUtil.java
|
| Abb. 3: Verzeichnisbaum mit Quelldateien nach der Generierung durch XDoclet. |
Betrachtet man die beiden Technologien nach der XDoclet-Generierung, werden die großen Vereinfachungen deutlich, die EJB 3.0 mit sich bringt. In EJB 3.0 reicht es aus, die Klassen in einen JAR zu verpacken und dann dem Applikationsserver bereitzustellen.
Bei EJB 2.x gibt es eine Reihe von Artefakten, die XDoclet generiert hat (siehe Abbildung 3). Neben den Deployment-Deskriptoren ejb-jar.xml und jboss.xml werden alle EJB-Interfaces generiert. Ebenso werden die konkrete Implementierung von javax.ejb.SessionBean und die Erweiterung von FooFacadeBean mit dem Namen FooFacadeSession generiert. Die ebenfalls generierte Util-Klasse stellt eine Implementierung eines J2EE-Patterns zum Caching der EJB Home Interfaces zur Verfügung, die dem Client unnötige JNDI-Lookups erspart.
Auch wenn sich die Technologien EJB 2.x und EJB 3.0 in der Praxis in den Grundsätzen stark unterscheiden, dürfte für den XDoclet-erfahrenen Entwickler ein Umstieg auf EJB 3.0 relativ einfach sein. Die verschiedenen Auszeichnungen sind in beiden Fällen ähnlich und lassen ein Gefühl der Vertrautheit mit dem Verfahren aufkommen.
Mit XDoclet und EJB 2.x hat sich in der Entwicklergemeinde bereits ein hohes Erfahrungspotential aufgebaut, das in Grundzügen dem Verständnis von EJB 3.0 dienlich sein kann. Nichtsdestotrotz ist EJB 3.0 eine komplexe, neue Technologie, die weit über die Fähigkeiten von XDoclet/EJB 2.x hinausgeht (siehe Abbildung 4).
Überblick über die Neuerungen von EJB 3.0
|
| Abb. 4: Zusammenfassung der Neuerungen von EJB 3.0. (Quelle: http://www.java-tutor.com/java/ejb-3.0-links.htm) |
Lassen Sie sich überraschen und begeistern von den neuen Möglichkeiten, die sich mit EJB 3.0 bieten. Mit den Artikeln aus den Literaturhinweisen kommen Sie vielleicht auf den Geschmack.
Holger Bartnick (info@ordix.de).