Enterprise JavaBeans (mit JBoss) Christian Hülsmeier Matrikelnummer: 7051315 [email protected] Ausarbeitung zum Vortrag vom 25.05.2004 Sommersemester 2004 Seminar: „Komponentenorientierte Softwareentwicklung und Hypermedia“ Dozent: Prof. Dr. Frank Thiesing Fachhochschule Dortmund Fachbereich Informatik Inhaltsverzeichnis 1 Einleitung .....................................................................................................................................1 2 Enterprise JavaBeans ...................................................................................................................2 2.1 Was ist Enterprise JavaBeans?.............................................................................................2 2.2 Architektur ...........................................................................................................................2 2.2.1 Der Applikationsserver ................................................................................................2 2.2.2 Der EJB-Container.......................................................................................................3 2.2.3 Der Persistenz-Manager...............................................................................................3 2.2.4 Typen von Enterprise-Beans........................................................................................3 2.2.5 Bestandteile einer Enterprise-Bean..............................................................................4 2.3 2.3.1 Was ist eine Entity-Bean? ............................................................................................5 2.3.2 Persistenz .....................................................................................................................6 2.3.3 Beziehungen zwischen Entitäten .................................................................................7 2.3.4 EJB Query Language ...................................................................................................9 2.4 3 4 Entity-Bean ..........................................................................................................................5 Session-Bean......................................................................................................................10 2.4.1 Was ist eine Session-Bean?........................................................................................10 2.4.2 Zustandslose Session-Beans ......................................................................................11 2.4.3 Zustandsbehaftete Session-Beans ..............................................................................11 2.5 Deployment-Deskriptor .....................................................................................................12 2.6 Client-Anwendungen .........................................................................................................15 JBoss ..........................................................................................................................................16 3.1 Was ist der JBoss Application Server? ..............................................................................16 3.2 Aufbau des JBoss Application Server................................................................................16 3.3 Installation des JBoss Application Server..........................................................................17 3.4 Konfiguration des JBoss Application Server .....................................................................18 3.5 Deployen von Enterprise-Beans.........................................................................................19 XDoclet ......................................................................................................................................20 5 6 Fallbeispiel .................................................................................................................................23 5.1 Entwicklungsumgebung.....................................................................................................23 5.2 MySQL-Datenbank............................................................................................................24 5.3 JBoss Application Server ...................................................................................................24 5.4 Ant-Skript ..........................................................................................................................24 5.5 Enterprise JavaBeans .........................................................................................................25 Anhang .......................................................................................................................................26 6.1 Literaturverzeichnis ...........................................................................................................26 6.2 Listingverzeichnis ..............................................................................................................26 6.3 Tabellenverzeichnis ...........................................................................................................26 6.4 Abbildungsverzeichnis.......................................................................................................27 1 Einleitung Die vorliegende Seminarausarbeitung befasst sich mit dem Thema „Enterprise JavaBeans (mit JBoss)“. Ziel dieser Ausarbeitung ist es, dem Leser einen Einblick in die Welt der Enterprise JavaBeans zu geben. Zunächst wird in Kapitel 2 dem Leser ein Überblick über Enterprise JavaBeans und die zu Grunde liegende Architektur gegeben. Danach werden die Bean-Typen „Entity-Bean“ und „Session-Bean“ in den Kapiteln 2.3 und 2.4 erläutert. Ein besonderes Augenmerk liegt im Bereich der Entity-Beans auf der „Container Managed Persistence“ als eine Persistenzform von Daten. Zuletzt wird in Kapitel 2.4 der Deployment-Deskriptor einer Enterprise JavaBean und in Kapitel 2.5 mögliche Formen von Clients erläutert. In Kapitel 3 wird auf den JBoss eingegangen. Im Speziellen werden die Themen Aufbau, Installation, Konfiguration und Deployment behandelt. Kapitel 4 befasst sich mit dem Open-Source-Projekt XDoclet, dass eine aspektorientierte Programmierung (AOP) von Enterprise JavaBeans unterstützt und die Entwicklung eigener Enterprise JavaBeans erheblich vereinfacht. Im letzten Kapitel (Kapitel 5) wird kurz das zur Seminarausarbeitung gehörige Fallbeispiel bzgl. Installation, Konfiguration und Inhalt erläutert. Der Anhang beinhaltet Literatur-, Listing-, Abbildungs- und Tabellenverzeichnisse. 1 2 Enterprise JavaBeans 2.1 Was ist Enterprise JavaBeans? Enterprise JavaBeans (kurz: EJB) ist das serverseitige Komponentenmodell der Firma Sun Microsystems für die Programmiersprache Java bzw. für die Java 2 Enterprise Edition (J2EE) Plattform. [SunEJB] Eine Enterprise-Bean ist eine Komponente, die Clients von einem Server bereitgestellt wird. Da es sich bei Enterprise JavaBeans um eine verteilte Objekt-Architektur handelt, basiert die Kommunikation zwischen Client und Server auf Java RMI. Genauer gesagt definiert Enterprise JavaBeans die entfernten Interfaces einer Bean mit Java RMI-IIOP, was für CORBAKonformität sorgt. [Monson-Haefel] Das Komponentenmodell der Enterprise JavaBeans ermöglicht es, dass Komponenten unabhängig vom zu Grunde liegenden Server entwickelt werden und somit die angestrebte Wiederverwendbarkeit gewährleistet bleibt. Um diese Wiederverwendbarkeit zu gewährleisten sind gewisse Restriktionen für Server und Komponente vorhanden, die im Folgenden erklärt werden. Neben der Wiederverwendbarkeit werden auch Services wie Transaktionen und Autorisierung von Enterprise JavaBeans unterstützt, was eine Vereinfachung der Beans und die Möglichkeit für den Komponentenentwickler sich bei der Entwicklung auf die reine Fachlichkeit zu konzentrieren bedeutet. 2.2 Architektur 2.2.1 Der Applikationsserver Ein Applikationsserver soll die Komplexität der Entwicklung von Geschäftsprozessen in der heutigen Internet-Welt beherrschbar machen. Er besteht oft aus einer Kombination verschiedener Technologien wie Webservern, Object Request Brokern (ORBs), nachrichtenorientierter Middleware (message-oriented middleware, MOM), Datenbanken und so weiter. [MonsonHaefel] Der Applikationsserver – genauer der J2EE-Appliationsserver – ist die Basiskomponenten der EJB-Architektur. Er ist eine Laufzeitumgebung für verschiedene (EJB-)Container. [Denninger] Ein J2EE-Applikationsserver muss folgende grundlegende Funktionalitäten bereitstellen: • das Thread- und Prozessmanagement, • die Unterstützung von Clustering und Lastverteilung, • die Ausfallsicherheit, • einen Namens- und Verzeichnisdienst, • eine Zugriffsmöglichkeit auf und das Pooling von Betriebssystemresourcen. 2 2.2.2 Der EJB-Container Der EJB-Container ist Teil des J2EE-Applikationsservers und stellt die Laufzeitumgebung für EJB-Komponenten dar. Außerdem stellt er der Bean alle benötigten Dienste bereit. Folgende Programmierschnittstellen (Dienste) muss der Container mindestens bereitstellen: • das API der J2SE (Java 2 Platform, Standard Edition), • das API der EJB 2.0 Spezifikation, • das API des JNDI 2.0 (Java Naming and Directory Interface), • das UserTransaction-API aus JTA 1.0.1 (Java Transaction API), • das API der JDBC-2.0-Erweiterung (Java Database Connectivity), • das API des JMS 1.0.2 (Java Messaging Service), • das API von JavaMail 1.1, • das API von JAXP 1.0 (Java XML Parser). [Denninger] Neben dem Bereitstellen der oben genannten Dienste hat der EJB-Container noch weitere Aufgaben. Der EJB-Container ist für die Kontrolle des Lebenszyklus einer Bean zuständig, erzeugt Bean-Instanzen, setzt sie in verschiedene Zustände und verwaltet sie in Pools, für den Fall, dass sie gerade nicht benötigt werden (Instanzenpooling). Die Lebenszyklen der verschiedenen Bean-Typen werden in den Kapiteln 2.3.5 (Entity-Beans), 2.4.2 und 2.4.3 (Session-Beans) erklärt. Des Weiteren kümmert sich der EJB-Container um Persistenz, Transaktionen, Messaging und Sicherheit. 2.2.3 Der Persistenz-Manager Der Persistenz-Manager ermöglicht die automatische Persistenz bestimmter Komponenten. Er wurde mit der Spezifikation 2.0 eingeführt. Wann die Daten einer Komponente geladen und gespeichert werden, bestimmt zwar weiterhin der EJB-Container, aber verantwortlich für das Wo und Wie der Speicherung der Daten ist der Persistenz-Manager. Er kommuniziert mit dem Speichermedium, z.B. einer relationalen Datenbank. Der Persistenz-Manager ist auch für Suchanfragen verantwortlich. Er kann – mit Kenntnis über die Abbildung der Daten – abstrakte Suchanfragen in konkrete Suchanfragen umwandeln. Enterprise JavaBeans stellt hierzu die Abfragesprache EJB-QL bereit (siehe Kapitel 2.3.4). 2.2.4 Typen von Enterprise-Beans Es gibt drei Typen von Enterprise-Beans: Entity-, Session- und Message-Driven-Beans. Da Message-Driven-Beans zumindest grundlegende Kenntnisse in JMS (Java Messaging Service) voraussetzen, die Vermittlung der Kenntnisse aber an dieser Stelle zu aufwendig wären, werden hier und im Folgenden nur die ersten beiden Bean-Typen behandelt. 3 Tabelle 1 gibt einen Überblick über die Aufgabe der, den Zugriff auf und die Persistenz der jeweiligen Bean(-Typen) [Denninger]. Entity-Bean Aufgabe der Bean Zugriff auf die Bean Persistenz der Bean Session-Bean Repräsentiert ein Geschäftsobjekt, dessen Daten sich in einem dauerhaften Speicher befinden. Repräsentiert einen serverseitigen Dienst, der Aufgaben für einen Client ausführt. Beispiel: Tabelle in einer Datenbank Beispiel: Warenkorb (Stateful Bean) Die Entity-Bean ist eine zentrale Ressource; die Bean-Instanz wird von mehreren Clients gleichzeitig benutzt und ihre Daten stehen allen Clients zur Verfügung. Eine Session-Bean ist für den Client eine private Ressource. Sie steht ihm exklusiv zur Verfügung. Persistent; Zustand der Bean befindet sich auf einem persistenten Speichermedium, wenn Client oder Server terminiert werden. Nicht persistent; wenn der verbunden Client oder der Server terminiert werden, ist die Bean nicht mehr verfügbar. Beispiel: Datensatz in einer Tabelle Tabelle 1: Unterscheidungskriterien zwischen Bean-Typen 2.2.5 Bestandteile einer Enterprise-Bean Um Entity- und Session-Beans zu implementieren, müssen die Komponenten-Interfaces, eine Bean-Klasse und ein Primärschlüssel, sofern es sich um eine Entity-Bean handelt, definiert werden. Außerdem wird ein Deployment-Deskriptor benötigt (siehe Kapitel 2.5). Es gibt vier Typen von Interfaces [vgl. Monson-Haefel]: • Entferntes Interface (remote interface) Das entfernte Interface definiert die Geschäftsmethoden der Bean, auf die Anwendungen außerhalb des EJB-Containers zugreifen können. • Entferntes Home-Interface (home interface) Das entfernte Home-Interface definiert die Lebenszyklus-Methoden von Beans, auf die Anwendungen außerhalb des EJB-Containers zugreifen können. Diese dienen zum Erzeugen neuer Beans, zum Löschen von Beans und zum Suchen von Beans. • Lokales Interface (local interface) Das lokale Interface einer Enterprise-Bean definiert die Geschäftsmethoden der Bean, die von anderen Beans, die sich im gleichen EJB-Container befinden, verwendet werden können. Beans können somit ohne den Aufwand eines verteilten Objekt-Protokolls miteinander kommunizieren. 4 • Lokales Home-Interface (local home interface) Das lokale Home-Interface definiert die Lebenszyklus-Methoden einer Bean, die von anderen Beans verwendet werden können, die sich im gleichen EJB-Container befinden. Die Unterscheidung von entfernten und lokalen Interfaces resultiert aus den Sichtbarkeiten einer Bean. Auf diese wird in Kapitel 2.6 im Rahmen der Betrachtung der möglichen Clients einer Bean noch eingegangen. Die Bean-Klasse ist diejenige Klasse, in der die Geschäfts- bzw. Lebenszyklusmethoden einer Bean implementiert werden. Allerdings werden die Home- und Remote-Interfaces nicht über das Schlüsselwort implements eingebunden. Die Signaturen der Methoden in der Bean-Klasse müssen allerdings den Signaturen der Methoden in den Interfaces entsprechen. Dies ist zum Teil recht verwirrend und kann bei der Entwicklung von Enterprise-Beans schnell zu Problemen führen, da evtl. Methoden bei der Implementierung der Bean vergessen werden oder mit einer falschen Signatur erstellt werden. Abhilfe schafft hier mitunter das Tool XDoclet, das in Kapitel 4 kurz erläutert wird. Zu den Lebenszyklusmethoden einer Bean gehören auf jeden Fall die Methoden ejbCreate und ejbRemove zum Erzeugen bzw. Entfernen einer Bean-Instanz. Bei Entity-Beans hat dies vor allem Auswirkungen auf den zu Grunde liegenden Datenspeicher – es werden ggf. Datensätze im Datenspeicher angelegt bzw. gelöscht. Der Primärschlüssel, der bei Entity-Beans benötigt wird, ist eine einfache Klasse, die als einzige Anforderung hat, dass sie das Interface java.io.Serializable implementieren muss. Die Klasse identifiziert eine Entität eines bestimmten Typs eindeutig. 2.3 Entity-Bean 2.3.1 Was ist eine Entity-Bean? Eine Entity-Bean ist ein Objekt, das persistente Daten repräsentiert. In den meisten Fällen werden die Daten in einer Datenbank gespeichert. [Denninger] Allerdings muss man feststellen, dass eine Entity-Bean mehr als ein reiner Datencontainer bzw. ein reine Datenrepräsentation darstellt, sondern, dass es sich um ein Geschäftsobjekt handelt, das einem Benutzer Daten aus einer Datenbank transaktionsgesichert bereitstellt. Beispiele für solche Geschäftsobjekte könnten z.B. ein Seminar, ein Dozent oder ein Student sein, wie es im Fallbeispiel der Fall ist. Entity-Beans werden in Anwendungen dann benutzt, wenn Daten über einen längeren Zeitraum gespeichert bzw. zur Verfügung bereitgestellt werden sollen. Ihr Zustand bleibt erhalten, wenn der Applikationsserver angehalten und wieder gestartet wird. Dies liegt vor allem daran, dass die Daten, die die Entity-Bean repräsentiert, von einem (externen) DBMS verwaltet werden. Wie schon in Kapitel 2.2.4 erwähnt, werden Entity-Beans als zentrale Ressourcen verwaltet. Das heißt aber auch, dass ein paralleler Zugriff von mehreren Clients auf eine Ressource verwaltet 5 werden muss. Der EJB-Container synchronisiert und serialisiert die Anfragen die Zugriffe auf die Entity-Beans. Der EJB-Container ist ebenfalls für den Lebenszyklus einer Entity-Bean zuständig. Eine EntityBean hat immer einen der folgenden drei Zustände [vgl. Monson-Haefel]: • Kein Zustand In diesem Zustand existiert keine Instanz der Bean. • Gepoolter Zustand In diesem Zustand befindet sich eine Instanz im Container. Diese Instanz ist aber noch keinem EJB-Objekt zugeordnet. • Bereit-Zustand In diesem Zustand befindet sich eine Instanz im Container, die einem EJB-Objekt ist. Abbildung 1 stellt den Lebenszyklus einer Entity-Bean in einer Art Zustandautomat dar. Abbildung 1: Lebenszyklus einer Entity-Bean-Instanz 2.3.2 Persistenz Um den Zustand einer Entity-Bean zu sichern, gibt es zwei verschiedene Persistenzmechanismen. Bei der Bean-Managed-Persistence (kurz: BMP) übernimmt der Entwickler selber die Verantwortung dafür, dass die Attribute der Bean vollständig und korrekt in die zu Grunde liegende Datenquelle gespeichert werden. Bei der Container-Managed-Persistence (kurz: CMP) übernimmt der EJB-Container die Verantwortung für die Speicherung des Zustands der Bean. Im Folgenden wird nur die CMP behandelt, da sie zum einen einfacher zu verstehen ist und zum anderen auch in der Praxis mehr Verwendung findet bzw. finden sollte. 6 Bei der Entwicklung von CMP-Entity-Beans erstellt der Bean-Entwickler eine abstrakte Klasse, die zum Zugriff auf ihre Attribute abstrakte getter- und setter-Methoden enthält. Es muss gemäß EJB-Spezifikation keine Implementierung für diese Zugriffsmethoden erstellt werden, da der EJB-Container beim Deployen der Bean eine Implementierung der abstrakten Klasse erstellt. Die Attribute werden auch nicht in der abstrakten Klasse definiert, wie es bei üblichen JavaBeans der Fall ist, sondern sind ebenfalls Teil der implementierenden Klasse. Gültige Datentypen für die Attribute einer Bean sind die primitiven Datentypen der Programmiersprache Java bzw. ihre Objektrepräsentation (z.B. int, java.lang.Integer usw.) und serialisierbare Datentypen der Programmiersprache Java, d.h. solche Klassen, die java.io.Serializable implementieren (z.B. java.lang.String oder java.util.Date). Natürlich können auch selbst definierte Datentypen benutzt werden, solange diese serialisierbar sind. Grundsätzlich werden Attribute in zugeordneten Spalten einer durch die Entity-Bean repräsentierten Tabelle gespeichert. Die Java-Datentypen werden vom Applikationsserver den jeweiligen SQL-Datentypen zugeordnet. So wird beispielsweise String dem SQL-Typ VARCHAR zugeordnet. Bei der Speicherung von Attributen eines selbst definierten Datentypen mittels eines normalen RDBMS muss allerdings beachtet werden, dass ein entsprechender SQLDatentyp für dieses Attribut verwendet wird. Meistens ist dies ein sog. BLOB (Binary Large Object). 2.3.3 Beziehungen zwischen Entitäten Aus dem klassischen Relationenmodell sind Beziehungen zwischen einzelnen Entitäten bereits bekannt. In relationalen DBMSs werden diese Beziehungen über Foreign-Key-Constraints abgebildet. Da Entity-Beans im Prinzip Tabellen (genauer: Entitäten) in einem RDBMS objektorientiert abbilden, liegt die Vermutung nahe, dass es auch bei Entity-Beans entsprechende Techniken für die Abbildung solcher Beziehungen gibt. Im Zusammenhang mit CMP-EntityBeans spricht man von Container Managed Relationships (CMR). Es gibt sieben verschiedene Beziehungstypen [vgl. Monson-Haefel], die hier kurz an Hand des Fallbeispiels erläutert werden: • Eins-zu-eins, unidirektional Beziehung zwischen Dozent und Lehrgebiet; es ist mit Sicherheit interessant zu wissen, zu welchem Lehrgebiet ein Dozent (und damit sein Seminar) gehört, aber für eine Seminarverwaltung ist es nicht unbedingt notwendig für ein bestimmtes Lehrgebiet den Dozenten zu wissen. • Eins-zu-eins, bidirektional Beziehung zwischen Dozent und Lehrgebiet; möchte man aus einem bestimmten Lehrgebiet ein Seminar auswählen, so muss auch eine Verbindung zwischen Dozent und Lehrgebiet bestehen, da keine direkte Zuordnung des Lehrgebiets zum Seminar existiert. Dies ist nur über den Dozenten möglich. 7 • Eins-zu-viele, unidirektional Beziehung zwischen Dozent und Seminar; ein Dozent hält mehrere Seminare. Es ist vielleicht wünschenswert nur eine Liste aller Seminare eines Dozenten zu haben, aber nicht unbedingt zu wissen, welcher Dozent zu einem Seminar gehört (wobei dies im Allgemeinen natürlich schon relativ interessant für einen Studenten ist). • Eins-zu-viele, bidirektional Beziehung zwischen Dozent und Seminar; ein Dozent hält mehrere Seminare. Es ist mit Sicherheit interessant zu wissen, welcher Dozent ein bestimmtes Seminar hält, aber auch welche Seminare ein Dozent überhaupt hält oder gehalten hat. • Viele-zu-eins, unidirektional Dies ist der umgekehrte Fall zu „Eins-zu-viele, unidirektional“. • Viele-zu-viele, unidirektional Beziehung zwischen Seminar und Student; ein Student kann mehrere Seminare besuchen und an einem Seminar nehmen mehrere Studenten teil. Bei einer reinen Seminarverwaltung ist es mir Sicherheit interessant zu wissen, welche Studenten an einem Seminar teilnehmen, aber nicht unbedingt, an welchen Seminaren ein Student teilnimmt. • Viele-zu-viele, bidirektional Beziehung zwischen Seminar und Student; ein Student kann mehrere Seminare besuchen und an einem Seminar nehmen mehrere Studenten teil. Erweitert man die reine Seminarverwaltung, um eine Verwaltung der Studenten, so ist es mit Sicherheit auch sehr interessant zu wissen, welche Seminare ein Student besucht bzw. besucht hat. Die Definition dieser Beziehungen wird im Deployment-Deskriptor der Entity-Bean vorgenommen. Ein Beispiel für die Definition einer bidirektionalen Eins-zu-eins-Beziehung ist in Kapitel 2.5 zu finden. Wichtig ist vor allem zu wissen, dass die Zugriffsmethoden für die über CMR definierten Werte ebenfalls abstrakt sind. Listing 1 zeigt die Klasse für die Bean „Lehrgebiet“ mit ihren abstrakten CMR-Methoden getDozent und setDozent. Die Methoden werden für den Zugriff auf den Dozenten eines Lehrgebiets benutzt und sind Teil der bidirektionalen Eins-zu-eins-Beziehung. Nachdem nun dargelegt wurde, was eine Entity-Bean ist, wie sie persistiert wird und wie Beziehungen zwischen Container Managed Persistence Entity-Beans über Container Managed Relationships dargestellt werden, wird abschließend noch kurz erläutert, wie Beans bzw. ihre Daten aus dem Datenspeicher geholt werden. Die Lösung hierzu ist die EJB Query Language. 8 // ... do some imports and package definition here! public abstract class LehrgebietBean implements EntityBean { public abstract Long getId(); public abstract void setId(Long id); public abstract String getName(); public abstract void setName(String name); public abstract DozentLocal getDozent(); public abstract void setDozent(DozentLocal dozent); public Long ejbCreate(String name) throws javax.ejb.CreateException { // ... set new id and name! } public void ejbPostCreate(String name) throws javax.ejb.CreateException { // do nothing; exists due to ejb specification! } } Listing 1: Bean-Klasse der Entity-Bean „Lehrgebiet“ 2.3.4 EJB Query Language Seit der Version 1.0 der EJB Spezifikation gibt es bereits Suchmethoden, so genannte FinderMethoden. Sie dienen zum Auffinden von Entity-Beans. Alle Entity-Beans müssen eine Methode namens findByPrimaryKey() haben, die den Primärschlüssel der Bean als Parameter übergeben bekommt [Monson-Haefel]. Seit der Version 2.0 ist es mittels der EJB Query Language (EJB QL) möglich relativ einfach eigene Suchmethoden zu definieren. (Zwar war dies auch schon vor Version 2.0 der EJB Spezifikation möglich, aber es gab keine standardisierte Vorgehensweise.) Die EJB QL ist eine deklarative Abfragesprache. Sie ähnelt in gewisser Weise der in relationalen Datenbanken verwendeten Sprache SQL. Die Listings 2, 3 und 4 enthalten einige Vergleiche von SQL und EJB QL. Die angegebenen Beispiele sollen ein Gefühl dafür vermitteln, wie die EJB QL funktioniert. Grundsätzlich wird sie nur für die Abfrage von Daten – also SELECTs – benutzt, da das Ändern und neu Anlegen von Datensätzen über die setter-Methoden und die ejbCreate-Methoden geschieht. Tiefergehende Erläuterungen der EJB QL finden sich in [Monson-Haefel] und [Denninger]. Standard-SQL-Abfrage: SELECT * FROM Lehrgebiet EJB QL-Abfrage: SELECT OBJECT( l ) FROM Lehrgebiet l Listing 2: Vergleich einer „einfachen Abfrage“ 9 Standard-SQL-Abfrage: SELECT l.name FROM Lehrgebiet l, Dozent d WHERE d.lehrgebiet_id = l.id EJB QL-Abfrage: SELECT d.lehrgebiet.name FROM Dozent d Listing 3: Vergleich einer „einfachen Abfrage mit Pfad“ Standard-SQL-Abfrage: SELECT d.name FROM Lehrgebiet l, Dozent d WHERE d.lehrgebiet_id = l.id AND l.name = ... EJB QL-Abfrage: SELECT d.name FROM Dozent d WHERE d.lehrgebiet.name = ?1 Listing 4: Vergleich einer „einfachen Abfrage mit Bedingung“ 2.4 Session-Bean 2.4.1 Was ist eine Session-Bean? Eine Session-Bean ist ein Geschäftsobjekt, da sie typischerweise die Logik eines Geschäftsprozesses realisiert. [Denninger] Eine Session-Bean wird als serverseitige Erweiterung einer Anwendung verstanden. Der Client greift auf eine Session-Bean zu, sobald er Funktionalitäten benutzen möchte, die er für sein Programm benötigt. In einer auf dem MVC-Konzept basierenden Anwendung würde das Model somit komplett durch EJB abgebildet werden, während die Anwendung im Controller den Aufruf der Bean-Funktionalität implementiert. Nachdem nun kurz erklärt wurde, was eine Session-Bean generell ist, stellen sich noch die Fragen „Wann werden Session-Beans eingesetzt?“ und „Wie hängen Session- und Entity-Beans zusammen?“. Session-Beans werden eingesetzt, sobald auf konzeptübergreifende Daten zugegriffen wird, die nicht gemeinsam genutzt werden und normalerweise nur gelesen werden. [Monson-Haefel] Zum Zusammenhang von Session- und Entity-Beans beschreibt Richard Monson-Haefel sehr einfach und treffend wie folgt: „Session-Beans können die Interaktionen zwischen Entity-Beans verwalten und beschreiben, wie diese zusammenarbeiten, um eine bestimmte Aufgabe zu erledigen. Die Beziehung zwischen Session-Beans und Entity-Beans ähnelt der Beziehung 10 zwischen einem Drehbuch eines Theaterstücks und den Schauspielern in diesem Stück; die Entity-Beans sind die Schauspieler, die Session-Bean ist das Drehbuch.“ [Monson-Haefel] Es gibt zwei Arten von Session-Beans. Diese sollen im Folgenden kurz erläutert werden. 2.4.2 Zustandslose Session-Beans Zustandslose Session-Beans haben keinen so genannten „Conversational-State“, d.h. Attributwerte, Referenzen auf andere Beans, Datenbankverbindungen etc. werden nicht persistent gehalten. Eine Instanz hat genau für einen Methodenaufruf einen „ConversationalState“, in dem alle Informationen behalten werden, und beim nächsten Methodenaufruf sind die Informationen aus einem vorherigen Aufruf nicht mehr vorhanden. Dies hat auch zur Folge, dass Instanzen von zustandslosen Session-Beans neben dem Zustand „Existiert nicht“ sich nur in einem anderen Zustand befinden können, nämlich dem Zustand „Methoden-bereit Pool“ (engl. „pooled ready“). Instanzen stehen einem Client für die Dauer eines Methodenaufrufs zur Verfügung. Abbildung 2: Lebenszyklus einer zustandslosen Session-Bean Aufgrund der „Zustandslosigkeit“ werden zustandslose Session-Beans auf als leichtgewichtig bezeichnet. Sie benötigen weniger Server-Ressourcen, da sie weder persistiert werden müssen noch einem Client zugeordnet sind, weswegen sich EJB-Objekte auch nur wenige BeanInstanzen teilen müssen. Beispiele für den Einsatz von zustandslosen Session-Beans sind die Erzeugung von Berichten, Stapelverarbeitung oder das Überprüfen von Kreditkarten. Dies alles sind Beispiele von generischen und wieder verwendbaren Diensten – dem typischen Einsatz von zustandslosen Session-Beans. 2.4.3 Zustandsbehaftete Session-Beans Zustandsbehaftete Session-Beans besitzen einen „Conversational-State“, was zur Folge hat, dass der EJB-Container wesentlich mehr Arbeit verrichten muss als bei zustandslosen Session-Beans. 11 Für den Erhalt des Zustands ist es nötig, dass jedem Client eine Session-Bean-Instanz zugewiesen wird. Zustandsbehaftete Session-Beans werden somit auch als schwergewichtig bezeichnet. Um trotzdem effizient zu bleiben, d.h. möglichst wenig Instanzen gleichzeitig betreiben zu müssen, können Instanzen von zustandsbehafteten Session-Beans passiviert und später wieder aktiviert werden. Passivierung bedeutet im Prinzip nur, dass die Bean-Instanz aus dem Arbeitsspeicher ausgelagert wird. Bei Bedarf wird sie aktiviert, d.h. wieder in den Arbeitsspeicher aufgenommen. Abgesehen vom Zustand „Passiv“ verhält sich eine zustandsbehaftete Session-Bean genau so wie eine zustandslose Session-Bean. Der Unterschied ist also die Aktivierung und Passivierung. Dieser Unterschied reichte aber schon aus, um eine Unterteilung der Session-Beans in zwei Arten vorzunehmen. [Denninger] Abbildung 3: Lebenszyklus einer zustandsbehafteten Session-Bean Ein typisches Beispiel für eine zustandsbehaftete Session-Bean ist ein Warenkorb in einem Shop-System. Je Client muss ein Warenkorb über mehr als einen Methodenaufruf bzw. über einen längeren Zeitraum seinen Zustand behalten. 2.5 Deployment-Deskriptor Der Deployment-Deskriptor einer Bean hat eine ähnliche Funktion wie eine Eigenschaftsdatei. Das Verhalten der Komponente kann hier konfiguriert und auch zur Laufzeit – ohne Änderung der Software selber – geändert werden. Vor dem Deployen einer Bean wird eine .jar-Datei erstellt. Neben der Bean-Klasse und den Interfaces enthält diese auch den Deployment-Deskriptor ejb-jar.xml. Wenn eine Bean bzw. die .jar-Datei nun deployt wird, wird der Deployment-Deskriptor ausgelesen und der EJBContainer erhält Informationen über die Bean. Informationen sind zum Beispiel um welche Art von Bean es sich handelt (Session, Entity, Message Driven) oder, wenn es sich um eine CMPEntity-Bean handelt, welche Attribute welchen Spalten einer Tabelle entsprechen. 12 Die Listings 5-7 zeigen Auszüge aus dem Deployment-Deskriptor des Fallbeispiels inklusive der Definition einer bidirektionalen Eins-zu-eins-Beziehung. Eine ausführliche Erklärung zu den einzelnen Teilen des Deployment-Deskriptor liefert Richard Monson-Haefel in seinem Buch „Enterprise JavaBeans“ in einem gesonderten Kapitel. [MonsonHaefel] <entity > <description><![CDATA[]]></description> <ejb-name>Lehrgebiet</ejb-name> <local-home>de.christianhuelsmeier.seminar.interfaces. LehrgebietLocalHome</local-home> <local>de.christianhuelsmeier.seminar.interfaces. LehrgebietLocal</local> <ejb-class>de.christianhuelsmeier.seminar.ejb. LehrgebietCMP</ejb-class> <persistence-type>Container</persistence-type> <prim-key-class>java.lang.Long</prim-key-class> <reentrant>False</reentrant> <cmp-version>2.x</cmp-version> <abstract-schema-name>Lehrgebiet</abstract-schema-name> <cmp-field > <description><![CDATA[Gibt die Id des Lehrgebiets zurueck.]]></description> <field-name>id</field-name> </cmp-field> <cmp-field > <description><![CDATA[Gibt den Namen des Lehrgebiets zurueck.]]></description> <field-name>name</field-name> </cmp-field> <primkey-field>id</primkey-field> <query> <query-method> <method-name>findAll</method-name> <method-params></method-params> </query-method> <result-type-mapping>Local</result-type-mapping> <ejb-ql><![CDATA[SELECT OBJECT(o) FROM Lehrgebiet o]]></ejb-ql> </query> </entity> Listing 5: Definition einer Entity-Bean im Deployment-Deskriptor 13 <session > <description><![CDATA[]]></description> <ejb-name>Seminarverwaltung</ejb-name> <home>de.christianhuelsmeier.seminar.interfaces. SeminarverwaltungHome</home> <remote>de.christianhuelsmeier.seminar.interfaces. Seminarverwaltung</remote> <local-home>de.christianhuelsmeier.seminar.interfaces. SeminarverwaltungLocalHome</local-home> <local>de.christianhuelsmeier.seminar.interfaces. SeminarverwaltungLocal</local> <ejb-class>de.christianhuelsmeier.seminar.ejb. SeminarverwaltungSession</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> </session> Listing 6: Definition einer Session-Bean im Deployment-Deskriptor <ejb-relation > <ejb-relation-name>DOZENT-cmp20-LEHRGEBIET-cmp20</ejb-relation-name> <ejb-relationship-role > <ejb-relationship-role-name> DOZENT-cmp20-has-LEHRGEBIET-cmp20 </ejb-relationship-role-name> <multiplicity>One</multiplicity> <relationship-role-source > <ejb-name>Dozent</ejb-name> </relationship-role-source> <cmr-field > <cmr-field-name>lehrgebiet</cmr-field-name> </cmr-field> </ejb-relationship-role> <ejb-relationship-role > <ejb-relationship-role-name> LEHRGEBIET-cmp20-has-DOZENT-cmp20 </ejb-relationship-role-name> <multiplicity>One</multiplicity> <relationship-role-source > <ejb-name>Lehrgebiet</ejb-name> </relationship-role-source> <cmr-field > <cmr-field-name>dozent</cmr-field-name> </cmr-field> </ejb-relationship-role> </ejb-relation> Listing 7: Definition einer bidirektionalen 1-zu-1-Beziehung im Deployment-Deskriptor 14 2.6 Client-Anwendungen Grundsätzlich kann man drei verschiedene Arten von Client-Anwendungen einer Bean unterscheiden. • Enterprise JavaBeans: Eine Enterprise JavaBean kann Client einer anderen Bean innerhalb des EJB-Containers sein. Es wird ein lokaler Zugriff (local) auf die andere Bean durchgeführt. • (Web-)Anwendungen, die sich auf dem gleichen Server wie die Bean befinden: Eine Anwendung, die sich auf dem gleichen Server wie die Bean befinden, (typischerweise eine Web-Anwendung) greift auf eine Bean zu. Dieser Zugriff passiert zwar innerhalb des Servers und ist deswegen auch schneller, als ein Zugriff, der von einem externen Client (ein Client, der auf einem anderen Rechner oder außerhalb der Server-Software läuft) getätigt wird, aber er wird als entfernter Zugriff (remote) bezeichnet. • eine (externe) Java-Anwendung: Eine Anwendung (z.B. ein Swing-Client), die auf einem anderen Rechner oder auf dem gleichen Rechner, aber außerhalb der Server-Software, läuft und auf die Bean zugreift. Ein solcher Zugriff wird als entfernter Zugriff (remote) bezeichnet. Insgesamt unterscheidet man also drei Typen von Klienten und zwei Sichten bzw. Zugriffsarten auf eine Bean. Zum einen den lokalen Zugriff und zum anderen den entfernten Zugriff. Aus diesem Grund wird in der EJB 2.0-Spezifikation auch zwischen lokalen und entfernten Interfaces unterschieden (vgl. Kapitel 2.2.5). Die Trennung von lokalen und entfernten Interfaces ermöglicht es der Bean für verschiedene Typen von Klienten verschiedene Dienste bereit zu stellen. Zum Beispiel ist es durchaus möglich, dass eine bestimmte Funktionalität einer SessionBean von anderen Session-Beans oder von Message-Driven-Beans aufgerufen werden darf, aber es nicht beabsichtigt ist, dass externe Klienten wie Web-Anwendungen oder Swing-Client diese Funktionalitäten aufrufen dürfen. Neben der Idee der Bereitstellung verschiedener Dienste in verschiedenen Sichten war vor allem die Interaktion zwischen Beans der ausschlaggebende Punkt für die Einführung von lokalen Interfaces. Da Beans, die untereinander interagieren, kein Netzwerk brauchen, die EJB 1.1Spezifikation aber verlangt, dass Beans die miteinander interagieren auch die Java RMI-IIOPSemantik verwenden müssen und immer mehr Hersteller versuchten den zusätzlichen Aufwand durch das Netzwerk zu vermeiden, entschloss sich Sun letztlich die Option des lokalen Zugriffs in die Spezifikation aufzunehmen. Vor allem auch deshalb, weil die Optimierungen der Hersteller quasi allgegenwärtig wurden. [Monson-Haefel] 15 3 JBoss 3.1 Was ist der JBoss Application Server? Der JBoss Application Server (kurz: JBoss AS) ist ein kostenloser Open-SourceApplikationsserver, der von der JBoss Group entwickelt wird. Mittlerweile ist die aktuellste Version des JBoss AS die Version 4.0 im Developer Release 4. Die aktuellste stabile Version ist die Version 3.2.3, die auch als Grundlage für diese Seminarausarbeitung und das damit zusammenhängende Fallbeispiel dient. Was ein Application Server im Allgemeinen ist, wurde bereits in Kapitel 2.2.1 kurz erläutert. Im Zusammenhang mit dem JBoss AS muss noch erwähnt werden, dass für J2EEApplikationsserver von der Firma Sun ein Kompatibilitätszertifikat für das J2EE ausgestellt wird, wenn er J2EE-kompatibel ist. Der JBoss AS besitzt dieses Zertifikat derzeit noch nicht, bietet aber laut der JBoss Group „full J2EE support“ [JBossAS]. Der Zertifizierungsprozess für den JBoss AS läuft mittlerweile, nachdem Meinungsverschiedenheit zwischen Sun und der JBoss Group beigelegt wurden und Sun einer Zertifizierung zugestimmt hat. Da der JBoss AS sehr leistungsfähig und zudem kostenlos ist – da er wie schon erwähnt ein Open-Source-Produkt ist –, erfreut er sich wachsender Beliebtheit bei Entwicklern. Vor allem für Forschungs- und Ausbildungszwecke bietet sich somit an, um z.B. Studenten ohne großen (finanziellen) Aufwand J2EE-Technologien wie EJB, JSP oder JMS nahe zu bringen. Allerdings ist beim Einsatz des JBoss AS zu beachten, dass zwar das Produkt selber kostenlos ist, das Handbuch und sonstige Dokumentationen aber weitestgehend kostenpflichtig sind, was bei Personen oder Gesellschaften mit entsprechend fehlenden finanziellen Mitteln (z.B. bei Studenten) doch mitunter manchmal zu Problemen beim Installieren und vor allem Konfigurieren führen kann. Weitere Informationen zum JBoss AS finden sich auf der Produkt-Homepage des JBoss AS. [JBossAS] 3.2 Aufbau des JBoss Application Server Der JBoss AS stellt die Möglichkeit bereit verschiedene Konfigurationen zu verwenden. Diese Konfigurationen werden in unterschiedlichen Ordnern im server-Verzeichnis des JBoss verwaltet (siehe Abbildung 4). Standardmäßig wird der JBoss mit drei (Server-)Konfigurationen ausgeliefert: default, minimal und all. Die minimal-Konfiguration stellt das Minimum an Services bereit, die der JBoss zum Starten benötigt. Beim Start der all-Konfiguration hingegen werden alle verfügbaren Services geladen. Anhand der default-Konfiguration soll kurz erklärt werden, welche Verzeichnisse es innerhalb einer Konfiguration gibt und welchen Zweck sie haben. • conf Beinhaltet Konfigurationsdateien Konfiguration. 16 der Services der jeweiligen Server- • data Daten • Das Verzeichnis in dem die im JBoss integrierte Datenbank Hypersonic ihre ablegt. deploy Das Verzeichnis in das die Applikation zum Deployen abgelegt wird. Näheres zum Deployen einer Applikation bzw. von Enterprise JavaBeans findet sich in Kapitel 3.4. • lib • log Beinhaltet sämtliche Logging-Informationen einer Server-Konfiguration. • tmp Beinhaltet temporäre Dateien, die vom Deployer benutzt werden. • work Das Verzeichnis wird vom internen Tomcat (JSP-Container und -Server) für die Kompilierung von JSP-Seiten benutzt. Beinhaltet sämtliche .jar-Dateien (Bibliotheken), die von der ServerKonfiguration benötigt werden Abbildung 4: Verzeichnisstruktur des JBoss Application Server Neben dem server-Verzeichnis des JBoss AS gibt es noch das bin-Verzeichnis, dass u.a. die Startskripte für den JBoss bereit stellt, sowie das lib-Verzeichnis, das sämtliche .jar-Dateien (Bibliotheken) beinhaltet, die zum Starten des JBoss AS benötigt werden. Außerdem sind ein clients-Verzeichnis und ein docs-Verzeichnis vorhanden. clients beinhaltet .jar-Dateien, die von Java Anwendungen benötigt werden. docs beinhaltet XML DTDs, die im JBoss benutzt werden. Weitere Informationen zum Aufbau des JBoss AS sind im frei verfügbaren Dokument „Getting started with JBoss“ zu finden. [Taylor] 3.3 Installation des JBoss Application Server Die Installation des JBoss AS ist prinzipiell recht einfach. Nachdem zunächst die .zip-Datei, die die Dateien des JBoss beinhaltet, von der JBoss-Homepage [JBoss] heruntergeladen wurde, muss sie anschließend nur noch in das Verzeichnis kopiert, in das der JBoss installiert werden soll, z.B. „C:\Programme“. 17 Nun muss die .zip-Datei nur noch entpackt werden und der JBoss ist prinzipiell startfähig. Wenn er korrekt installiert wurde, befindet er sich jetzt z.B. im Verzeichnis „C:\Programme\jboss3.2.3“. Um den JBoss zu starten, muss nur die Startdatei run.bat im bin-Verzeichnis des JBoss ausgeführt werden. Beim Ausführen der Startdatei wird die default-Konfiguration verwendet. Möchte man den JBoss mit einer eigenen Konfiguration starten, so ruft man die Startdatei mit dem Parameter -c und dem Namen der Konfiguration auf, z.B. run -c seminar. Vor dem Start des JBoss muss sichergestellt werden, dass die Umgebungsvariable JAVA_HOME im Betriebssystem gesetzt wurde. Um sicher zu gehen, dass dies auch wirklich geschieht, empfiehlt es sich ein Skript zu schreiben, dass das Setzen der Umgebungsvariable sowie den Start des JBoss selber übernimmt. Listing 8 stellt dies exemplarisch für Windows dar. set JAVA_HOME=C:\ j2sdk1.4.2_03 run –c seminar Listing 8: Beispiel für ein JBoss-Startskript 3.4 Konfiguration des JBoss Application Server Wenn man von der Konfiguration des JBoss AS spricht, so ist immer die Konfiguration einer Server-Konfiguration gemeint. Normalerweise ist für eine Standard-Anwendung mit einfachen Session- und Entity-Beans meist, neben der für die Anwendung nötigen Bibliotheken, nur die Konfiguration der Datenbank notwendig. Die für die Anwendung benötigt .jar-Dateien (Bibliotheken) werden in das lib-Verzeichnis kopiert. Für die Konfiguration der Datenbank müssen zwei Schritte durchgeführt werden. Zum einen muss eine XML-Datei (dbname-ds.xml) für die Datenbankkonfiguration im deploy-Verzeichnis angelegt werden. Für eine MySQL-Datenbank wäre dies z.B. die Datei mysql-ds.xml, mit sämtlichen Zugriffsinformationen für die Datenbank (URL, Username, Passwort). Vorlagen für verschiedene Datenbankkonfigurationsdateien sind im docs-Verzeichnis des JBoss unter jca zu finden. Zum anderen muss die Datei standardjbosscmp-jdbc.xml im conf-Verzeichnis angepasst werden. Die Listings 9 und 10 sind Beispiele für die Datenbankkonfigurationen. <?xml version="1.0" encoding="UTF-8"?> <datasources> <local-tx-datasource> <jndi-name>MySqlDS</jndi-name> <connection-url>jdbc:mysql://localhost:3306/seminar</connection-url> <driver-class>org.gjt.mm.mysql.Driver</driver-class> <user-name>seminar_dba</user-name> <password></password> </local-tx-datasource> </datasources> Listing 9: Beispielkonfiguration einer MySQL-Datenbank (mysql-ds.xml) 18 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE jbosscmp-jdbc PUBLIC "-//JBoss//DTD JBOSSCMP-JDBC 3.2//EN" "http://www.jboss.org/j2ee/dtd/jbosscmp-jdbc_3_2.dtd"> <jbosscmp-jdbc> <defaults> <datasource>java:/MySqlDS</datasource> <datasource-mapping>mySQL</datasource-mapping> <create-table>false</create-table> <remove-table>false</remove-table> <read-only>false</read-only> ... Listing 10: Beispielkonfiguration einer MySQL-Datenbank (standardjbosscmp-jdbc.xml) Bei der Konfiguration ist vor allem zu beachten, dass der JNDI-Name in der Datei mysqlds.xml die gleiche Bezeichnung hat, wie der Name der Datasource nach dem Prefix java:/, der in der Datei standardjbosscmp-jdbc.xml. 3.5 Deployen von Enterprise-Beans Das Deployen von Enterprise JavaBeans (.jar), Web-Applikationen (.war) oder Enterprise Applikationen (.ear) im JBoss ist recht einfach. Voraussetzung für ein korrektes und fehlerloses Deployen ist lediglich die korrekte Konfiguration der jeweiligen Server-Konfiguration (siehe Kapitel 3.5). Um z.B. eine Enterprise JavaBean zu deployen muss man lediglich das .jar-Archiv, in dem sich die Bean befindet, in den deploy-Ordner der Server-Konfiguration kopieren und beim nächsten Start deployt der JBoss die Bean automatisch. Da der JBoss auch Hot-Deployment – das Hinzufügen von Anwendungen und Services zur Laufzeit, d.h. während der JBoss AS läuft – unterstützt, kann ein .jar-, .war- oder .ear-Archiv jederzeit in das deploy-Verzeichnis kopiert werden. Bei Web-Applikationen ist allerdings zu beachten, dass evtl. bestehende Sessions verloren gehen. 19 4 XDoclet „XDoclet is a code generation engine. It enables Attribute-Oriented Programming for java. In short, this means that you can add more significance to your code by adding meta data (attributes) to your java sources. This is done in special JavaDoc tags.” [XDoclet] Im Prinzip sagt diese Definition alles über XDoclet aus, was der Benutzer wissen muss: er schreibt spezielle JavaDoc-Tags, so genannte XDoclet-Tags, in die Kommentare von Klassen und Methode, die dann dazu benutzt werden, die entsprechenden Sourcen – z.B. Interfaces einer Enterprise JavaBean oder den XML-Deployment-Deskriptor – zu generieren. Für das Erzeugen der Interfaces und Klassen einer Bean werden nur wenige Tags benötigt. Anhand der Entity-Bean „Lehrgebiet“ aus dem Fallbeispiel soll der Einsatz und die Wirkung dieser Tags erläutert werden. package de.christianhuelsmeier.seminar.ejb; import ... /** * @ejb.bean * type="CMP" * cmp-version="2.x" * name="Lehrgebiet" * local-jndi-name="LehrgebietLocalHome" * view-type="local" * primkey-field="id" * * @ejb.finder * signature="java.util.Collection findAll()" * result-type-mapping="Local" * method-intf="LocalHome" * query="SELECT OBJECT(o) FROM Lehrgebiet o" * * @ejb.persistence table-name="Lehrgebiet" * * @ejb.util generate="physical" */ public abstract class LehrgebietBean implements EntityBean { ... Listing 11: Klassenkommentare in der Bean „Lehrgebiet“ Im Klassenkommentar einer (Entity-)Bean-Klasse werden die Tags @ejb.bean und @ejb.persistence auf jeden Fall benötigt. Die Tags @ejb.util und @ejb.finder sind optional. @ejb.bean stellt Informationen über die Bean bereit. type beschreibt hierbei den Bean-Typen. Gültige Werte sind CMP und BMP für Entity-Beans sowie Stateful und Stateless für SessionBeans. Bei CMP-Entity-Beans kann noch die cmp-version angegeben werden. Standardmäßig ist diese auf "1.x" eingestellt. Da das Fallbeispiel komplett auf der EJB 2.0-Spezifikation basiert, wird der Wert hier noch explizit gesetzt. name spezifiziert den Namen der Bean, der auch im XML-Deployment-Deskriptor benutzt wird. Der unter local-jndi-name angegebene Name ist der JNDI-Name für die lokale EJB. view-type gibt an, ob die Bean nur lokal gesehen werden kann oder auch „entfernt gesehen werden kann“. D.h., dass bei der Angabe von local nur die 20 lokalen Interfaces erstellt werden, während bei der Angabe von both auch die entfernten Interfaces erstellt werden. @ejb.persistence gibt an, in welcher Tabelle einer relationalen Datenbank die Werte der Bean gespeichert werden sollen. Mittels @ejb.finder kann man eigene Suchemethoden für Entity-Beans für definieren. Denkbar wäre z.B. neben der standardmäßig vorhandenen findByPrimaryKey-Methode, die Definition von Methoden, die alle Datensätze zurückgeben oder die Datensätze nach anderen Kriterien als dem Primärschlüssel zurückgeben. Bei Personen wäre dies evtl. der Nachname oder Vorname. In Methodenkommentaren werden neben dem (optionalen) Tag @ejb.interface-method noch die Tags @ejb.persistence, @ejb.relation sowie @ejb.pk-field und @ejb.createmethod benutzt. ... /** * @ejb.pk-field * @ejb.interface-method view-type="local" * @ejb.persistence column-name="id" */ public abstract Long getId(); /** * @ejb.interface-method view-type="local" */ public abstract void setId(Long id); ... /** * @ejb.interface-method view-type="local" * * @ejb.relation * name="DOZENT-cmp20-LEHRGEBIET-cmp20" * role-name="LEHRGEBIET-cmp20-has-DOZENT-cmp20" * * @jboss.relation-mapping style="foreign-key" */ public abstract de.christianhuelsmeier.seminar.interfaces.DozentLocal getDozent(); /** * @ejb.interface-method view-type="local" */ public abstract void setDozent(de.christianhuelsmeier.seminar.interfaces.DozentLocal dozent); /** * @ejb.create-method */ public Long ejbCreate(String name) throws javax.ejb.CreateException { ... } ... Listing 12: Methodenkommentare in der Bean „Lehrgebiet“ @ejb.interface-method gibt an, ob eine Methode später beim Generieren der Interfaces übernommen werden soll oder, ob sie nicht im Interface angegeben wird (entspricht dem 21 Weglassen des Tags). Über das Attribut view-type kann man angeben, ob Methoden im entfernten, lokalen oder in beiden Interfaces verfügbar sein sollen. Wird view-type nicht angegeben, so wird die Sichtbarkeit der Methode an die Sichtbarkeit der Bean, die unter @ejb.bean definiert wurde, angepasst. @ejb.persistence definiert die Spalte, in der das Datum in der zur Bean gehörigen Tabelle gespeichert wird. @ejb.pk-field kennzeichnet den Primärschlüssel der Entity-Bean. @ejb.create-methode kennzeichnet eine ejbCreate-Methode, die zum Erzeugen einer Bean- Instanz benötigt wird. Weitere Informationen über XDoclet bzw. den Einsatz von XDoclet sind auf der Homepage des XDoclet-Projekts [XDoclet] zu finden. 22 5 Fallbeispiel 5.1 Entwicklungsumgebung Als Entwicklungsumgebung für dieses Beispiel würde die IDE Eclipse in der Version 2.1.2 benutzt. Eclipse ist mittlerweile wohl die bekannteste Open-Source-Entwicklungsumgebung im Bereich der Programmiersprache Java. Folgende Schritte sind zu befolgen, um die Entwicklungsumgebung für das Projekt zu konfigurieren: 1. Kopieren der Quellen von der CD in eine beliebiges „E:\Daten\seminar“ (im Folgenden %SEMINAR_HOME%). Verzeichnis, z.B. 2. Anlegen eines neuen Java-Projekts. Als Name gibt man „Seminarverwaltung“ an und als Projektverzeichnis das Verzeichnis mit den Seminar-Sourcen (%SEMINAR_HOME%). Klickt man nun auf „Next“, so erscheint eine Liste von Source-Pfaden. In ihr sollten nur folgende Verzeichnisse aufgelistet sein: • %SEMINAR_HOME%/ejb/src • %SEMINAR_HOME%/ejb/build/gen-src • %SEMINAR_HOME%/web/src Als Standard-Ausgabeverzeichnis wird „Seminarverwaltung/output“ angegeben. Nun kann der Assistent zur Anlage eines neuen Projektes beendet werden. 3. Zuletzt müssen noch die Ant-Skripte zum Erzeugen und Compilieren der Quelldateien in Eclipse eingebunden werden. Hierzu wählt man im „Window“-Menü unter dem Untermenü „Show View“ den Punkt „Ant“ aus. Nun fügt man in dem neuen Fenster eine Skriptdatei wie folgt ein. Zunächst klickt man auf das Symbol mit den drei Plus-Zeichen. Im sich nun öffnenden Dialog wählt man unter „Seminarverwaltung\ejb\script“ die Datei build.xml aus und schließt den Dialog wieder. Der Eintrag für dieses Skript ist nun im Ant-Ansichtsfenster vorhanden. Nun wählt man im Kontext-Menü (rechte Maustaste) dieses Eintrages den Punkt „Properties“ und wählt da den Karteireiter „Classpath“ aus. Nachdem man die Option „Use global classpath as specified in the Ant runtime properties“ deaktiviert hat, fügt man die Datei tools.jar aus dem lib-Verzeichnis des JDK in die Liste der „Additional classpath entries“ ein. Diese Prozedur wiederholt man für die build.xml-Dateien in den Verzeichnissen „Seminarverwaltung\script“ und „Seminarverwaltung\web\script“. 23 5.2 MySQL-Datenbank Für die Benutzung der Entity-Beans wird eine MySQL-Datenbank benötigt. Ein Skript zum Erzeugen der Tabellen in der Datenbank findet sich im Verzeichnis „Datenbank“ auf der CD. Die darin enthaltenen SQL-Befehle müssen nur noch in einer MySQL-Datenbank ausgeführt werden. Voraussetzung für ein erfolgreiches Ausführen der Befehle ist ein installierter MySQL-Server und eine darin eingerichtete Datenbank mit Name, Benutzername und Passwort. Auf die Installation einer MySQL-Datenbank soll an dieser Stelle nicht weiter eingegangen werden. 5.3 JBoss Application Server Wie der JBoss AS aufgebaut ist und wie er sich prinzipiell installieren lässt wurde bereits in Kapitel 3 beschrieben. Hier wird nun beschrieben, wie man den JBoss AS konkret für das Fallbeispiel konfiguriert. Zunächst kopiert man die default-Konfiguration (siehe Kapitel 3.2) und benennt sie zum Beispiel in „seminar“ um. Danach beginnt man die Konfigurationsdateien anzupassen. Hierzu kann man als Vorlage die Dateien aus dem Verzeichnis „JBoss-Konfigurationsdateien“ von der CD nehmen. Die Datei standardjbosscmp-jdbc.xml kann ohne Änderungen in das conf-Verzeichnis der seminar-Konfiguration kopiert werden. Die Datei mysql-ds.xml wird in das deployVerzeichnis kopiert, allerdings muss in der Datei noch die URL der Datenbank, z.B. jdbc:mysql://localhost:3306/seminar, wenn die Datenbank den Namen „seminar“ trägt, sowie der Benutzername und das Passwort entsprechend der Einstellungen der MySQLDatenbank (vgl. Kapitel 5.2) gesetzt werden. Wichtig ist, dass der Name unter dem die Datenbank angesprochen wird – in den Konfigurationsdateien ist dies „MySqlDS“ – der gleiche ist, wie der in der build.xml-Datei im ejb\script-Verzeichnis im jboss-Tag. Benutzt man allerdings die Dateien von der CD als Vorlage, so ist dies kein Problem. Nachdem diese Einstellungen gemacht wurden, ist der JBoss AS für den Betrieb des Fallbeispiels „Seminarverwaltung“ konfiguriert. Zuletzt sollte noch der Ordner jms im deploy-Verzeichnis der seminar-Konfiguration gelöscht werden, um Fehler- und Warnmeldungen beim Start zu verhindern. Da im Fallbeispiel keine Message-Driven-Beans enthalten sind, wird der JMS-Service auch nicht benötigt. 5.4 Ant-Skript Mittels der Ant-Skripte können die Enterprise JavaBeans sowie der Web-Client erzeugt, compiliert und im JBoss deployt werden. Die Skripte selber sind relativ zum Stammverzeichnis der Quelldateien (oberhalb vom ejb- und web-Verzeichnis) programmiert worden, dass heißt, dass sie nicht geändert werden müssen. Die einzigen absoluten Pfade, die auf das jeweilige 24 System des Benutzers angepasst werden müssen, befinden sich in der Datei build.properties im script-Verzeichnis des Stammverzeichnisses. Beim Ausführen der Skripte sollte man die Ausführungsreihenfolge beachten. Zunächst führt man das Skript für die Enterprise JavaBeans aus, danach das Skript für die Web-Applikation und zuletzt das Skript zum Deployen der gesamten Anwendung. Die Ant-Skripte erzeugen als Ausgabe eine .war-Datei, die die Web-Anwendung beinhaltet, eine .jar-Datei, die die Enterprise JavaBeans enthält, sowie eine .ear-Datei, die die WebAnwendung und die Enterprise JavaBeans zu einer Enterprise Applikation zusammenfasst. 5.5 Enterprise JavaBeans Die Seminarverwaltung besteht aus fünf CMP-Entity-Beans und einer Stateless-Session-Bean. Vier der fünf Entity-Beans stellen fachliche Geschäftsobjekte dar (Student, Seminar, Dozent, Lehrgebiet), während die fünfte Entity-Bean (PkGenerator) nur technischen Charakter hat. Leider musste eine Primary-Key-Generator-Bean erstellt werden, da MySQL leider keine Sequenzen unterstützt wie dies zum Beispiel bei Oracle der Fall ist. Zwar gibt es bei MySQL die Funktion des auto_increment, aber in einem normalen insert-Statement gibt man den Wert null für den Primary-Key (klassischerweise eine Id) an, was bei der Container Managed Persistance eine NullPointerException auslöst und dazu führt, dass der Datensatz nicht angelegt wird. Die Session-Bean Seminarverwaltung stellt Dienste für Klienten bereit, die es ermöglichen Studenten, Dozenten und Seminar anzulegen sowie An- und Abmeldungen von Seminaren durchzuführen. 25 6 Anhang 6.1 Literaturverzeichnis [Denninger] Denninger, Stefan; Peters, Ingo: Enterprise JavaBeans 2.0. 2.Auflage. München: Addison-Wesley, 2002. [JBossAS] JBoss Group: JBoss Application Server. http://www.jboss.org/products/jbossas/ 23.05.2004 [Monson-Haefel] Monson-Haefel, Richard: Enterprise JavaBeans. 3.Auflage. Köln: O’Reilly, 2002. [SunEJB] Sun Microsystems: Enterprise JavaBeans Technology. http://java.sun.com/products/ejb/, 26.04.2004 [Taylor] Taylor, Luke (and The JBoss Group): Getting started with JBoss. http://www.jboss.org/docs/index#free-32x, 23.05.2004 [XDoclet] XDoclet – Attribute Oriented Programming. http://xdoclet.sourceforge.net/, 20.05.2004 6.2 Listingverzeichnis Listing 1: Bean-Klasse der Entity-Bean „Lehrgebiet“....................................................................9 Listing 2: Vergleich einer „einfachen Abfrage“ .............................................................................9 Listing 3: Vergleich einer „einfachen Abfrage mit Pfad“.............................................................10 Listing 4: Vergleich einer „einfachen Abfrage mit Bedingung“...................................................10 Listing 5: Definition einer Entity-Bean im Deployment-Deskriptor ............................................13 Listing 6: Definition einer Session-Bean im Deployment-Deskriptor..........................................14 Listing 7: Definition einer bidirektionalen 1-zu-1-Beziehung im Deployment-Deskriptor .........14 Listing 8: Beispiel für ein JBoss-Startskript .................................................................................18 Listing 9: Beispielkonfiguration einer MySQL-Datenbank (mysql-ds.xml) ................................18 Listing 10: Beispielkonfiguration einer MySQL-Datenbank (standardjbosscmp-jdbc.xml) ........19 Listing 11: Klassenkommentare in der Bean „Lehrgebiet“ ..........................................................20 Listing 12: Methodenkommentare in der Bean „Lehrgebiet“.......................................................21 6.3 Tabellenverzeichnis Tabelle 1: Unterscheidungskriterien zwischen Bean-Typen...........................................................4 26 6.4 Abbildungsverzeichnis Abbildung 1: Lebenszyklus einer Entity-Bean-Instanz ..................................................................6 Abbildung 2: Lebenszyklus einer zustandslosen Session-Bean....................................................11 Abbildung 3: Lebenszyklus einer zustandsbehafteten Session-Bean ...........................................12 Abbildung 4: Verzeichnisstruktur des JBoss Application Server .................................................17 27