Einleitung:
In der Softwareentwicklung werden
heute fast nur noch verteilte Anwendungen realisiert.
Hier haben sich so genannte „Enterprise
Java Beans“ als Standardlösung etabliert. Da die Anwendung aus verschiedenen
Schichten besteht, wird der Entwicklungsprozess wesentlich erschwert. Mithilfe
von WebSphere Application Developer lässt sich diese Aufgabe jedoch bewältigen.
Fließtext:
Das Enterprise Java Beans-Komponentenmodell ist prädestiniert zur Entwicklung
von funktionstüchtigen und leistungsfähigen Komponenten für den Server. Diese
können auf eine Vielzahl von Servern verschiedenster Anbieter ablaufen. Der
Entwickler kann plattform-neutrale, verteilte, transaktionsorientierte
Anwendungen realisieren. Dabei definiert das Enterprise Java Beans-Modell eine strikte Trennung zwischen der
anwendungsspezifischen Geschäftslogik und den einzelnen Systemfunktionen. So
kann der Anwendungsentwickler sich auf die Entwicklung der Geschäftslogik eines
bestimmten Anwendungsbereiches (EJB) konzentrieren. Die Realisierung von
komplexen Systemfunktionen wie Transaktionsverwaltung, die Persistenz der
Objekte und die Systemsicherheit bleibt außen vor. Die EJB-Architektur führt
automatisch alle nötigen Systemoperationen aus, wovon der Entwickler nichts
mitbekommt. Sie stellt alle Basisfunktionalitäten bereit. Mit dessen Hilfe
lassen sich Komponenten endlich über die Grenzen der Hardware, Betriebssystem und
der Middleware verwenden. Der Entwicklungsaufwand wird gleichzeitig in Grenzen
gehalten und somit die Investitionen gesichert.
Die EJB-Architektur:
Die EJB-Architektur ermöglicht die
Kommunikation mit jeglicher Clientanwendung, da sie protokollunabhängig
implementiert wurde. Der EJB-Server stellt eine Reihe von Diensten bereit, um
die Installation einer EJB-Komponente zu vereinfachen. Unter anderem sind dies
die Systemdienste zur Verwaltung von verteilten Objekten und der Aufruf dieser
EJB-Objekte. Natürlich gibt es auch noch andere Systemdienste. Hierzu ein
Beispiel, welchen Nutzen die EJB-Architektur bietet. Als Beispiel-Szenario
nehmen wir eine Bank-Anwendung. Ein Benutzer will zum Beispiel von zu Hause auf
alle seine Bankkonten zugreifen. Dabei ist es unerheblich, wo die Daten „real“
vorliegen. Die EJB-Architektur greift über eine Schnittstelle auf die reale
Implementierung der Bank zu. Die Finanzanwendung auf dem Client nutzt das
entfernte Objekt. Über den Mechanismus „Introspektive“ ermittelt der Client,
wozu das Objekt in der Lage ist. Dabei agiert die EJB-Komponente
transaktionsorientiert. Der Client kann eine Reihe von Operationen auf das
Konto durch eine einzige Transaktion durchführen lassen. Dabei kann die
Transaktion bestätigt oder auch wieder zurückgenommen werden. In einer
verteilten Welt ist dies ein kritischer Vorgang. Es muss auf jeden Fall
sichergestellt sein, dass die Transaktion wirklich komplett abgeschlossen ist,
bevor eine Auszahlung gewährt wird. Der
Transaktionsmechanismus stellt sicher, dass bei einem Verbindungsfehler ein
Ausnahmefehler ausgelöst und die Transaktion zurückgeschrieben wird. Die
EJB-Architektur erledigt diese Aufgabe ohne unser zutun.
Die EJB-Basics:
Eine EJB-Komponente ist nichts anderes als
ein „serverseitiges Objekt“ mit einer
konkret spezifizierten Aufgabe. Jede EJB läuft innerhalb einer Schutzzone einem
so genannten Container ab. Der Container regelt dabei die Kommunikation mit
anderen EJB-Objekten. Über die portable Schnittstelle wird der Außenwelt der
Zugriff auf die EJB gewährt. Bei der Entwicklung von Internet-Anwendungen wird
häufig eine Multi-Tier-Architektur verwendet. Hierbei übernimmt der Client nur
die Aufgabe der Darstellung und einen kleinen Teil der Verarbeitung der Daten.
Jedoch greift die Client-Anwendung für weitere Funktionalitäten auf einen
Applikationsserver und für Daten auf einen Datenbankserver zu. Innerhalb der
mittleren Schicht werden die EJB-Komponenten bereitgestellt, welche die Verarbeitung der Geschäftslogik durchführt.
Die EJB-Spezifikation engt die Komplexität einer verteilten Systemarchitektur
ein und schafft auf einfachste Weise eine Schnittstelle zwischen EJB Server und
den EJB-Komponenten.
Verschiedene Typen von EJBs:
Die Herausforderung bei der
EJB-Entwicklung stellt die Komplexität der beiden Gruppen von möglichen EJB
Komponenten dar. So genannte „Session Beans“ werden
zur Behandlung von Geschäftslogiken verwendet und
können daher nur einen statuslosen oder einen bestimmten Status besitzen. Die
Session Beans mit einem speziellen Status existieren
nur für die Laufzeit einer Client/Server Sitzung. Eine statuslose Session Bean
hingegen wird in einem Container verwaltet, um mehrere Anfragen von den
unterschiedlichsten Clients zu behandeln. Im Vergleich bestehen so genannte „Entity Beans“ aus individuellen
Einheiten (Entities) und werden innerhalb einer
Anwendung genutzt, um Datenpersistenz und Daten Modellierung zu regeln. Eine Entity Bean kann dabei entweder die Verwaltung der
Persistenz einem Container überlassen oder die Persistenz über eine eigene
Implementierung abwickeln. Daher werden diese entweder „CMP“ oder „BMP“
genannt. Eine CMP Entity Bean lässt die
Datenpersistenz über einen Container verwalten. Eine BMP Entity
Bean verwaltet diese selber.
WebSphere:
Da die EJB-Entwicklung recht
komplex ist, sollte man den Prozess mithilfe von Werkzeugen automatisieren. WebSphere stellt verschiedene Wizards
für die unterschiedlichsten Aufgaben zur Verfügung. Diese unterstützen
konsequent den gesamten Entwicklungsprozess und reichen vom Anlegen der EJB und
geht bis zur Bereitstellung, Austesten
und Zusammenpacken der EJBs.
Zu Demonstrationszwecke legen
wir hier eine Konto-Bean an. Mithilfe dieser Bean lassen sich neue Konten
anlegen oder dessen Konto-Nr, Konto-Inhaber oder
Kontostand abfragen oder setzen. Entsprechende Methoden sind innerhalb der Bean
zu implementieren. Nach dem Start der WebSphere
Entwicklungsoberfläche wird eine individuelle Perspektive anzeigt. Sie bietet
einen Überblick über den jeweiligen Projekttypus (Web, EJB, Server).
Im ersten Entwicklungsschritt
ist ein EJB-Projekt anzulegen.
Der Entwickler ruft den
entsprechenden Wizard (New Project) über den Menüpunkt „File->New->EJB
Project“ auf. Im Folgedialog ist auf der linken Seite der Eintrag „EJB“ zu
selektieren und kann darauf den Eintrag „EJB-Project“ auswählen. Über „Next“
wird die nächste Seite des Wizards angezeigt. Dort
ist lediglich der Projektname (MyProject) einzugeben.
Schon kann der Wizard über „Finish“
wieder beendet werden. Innerhalb der WebSphere IDE
wird jetzt automatisch die J2EE-Perspektive eingeblendet, wodurch eine optimale
EJB-Entwicklung sichergestellt werden soll. Die Verwaltung der EJBs erfolgt
laut J2EE-Spezifikation innerhalb so genannter Module. Das J2EE-Ansichtsfenster
ist in folgende Module unterteilt:
1)
Enterprise Applications
2)
Application Client Modules
3) Web Modules
4) EJB Modules
5)
Server Configurations
6)
Server Instances
7)
Databases
Innerhalb des Ordners „EJB
Modules“ wird unser neues EJB-Projekt abgelegt. WebSphere
legt parallel ein korrespondierendes EAR-Projekt innerhalb des Ordners
„Enterprise Applications“ ab.
Ihre erste Bean:
Anschließend ist die Enterprise
Bean anzulegen. Für diese Aufgabe nimmt man am besten den EJB-Wizard zur Hilfe.
Der Entwickler selektiert das entsprechende EJB-Projekt mit der rechten
Maustaste und kann über den Kontextmenüeintrag „File->New->Enterprise
Bean“ den Wizard starten. Im Dialog ist der Name der Bean einzugeben und der
Typ der Bean (Session, BMP Entity oder CMP Entity) zu bestimmen.
Soll wie bei uns eine CMP Entity Bean erzeugt werden, sind die einzelnen Datenfelder
der Bean anzulegen. Die KontoBean benötigt die Felder
KontoNr, Inhaber und Kontostand. Über die
Schaltfläche „Add“ fügt man die einzelnen Felder der Bean hinzu.
Im Dialog (Create Persistence Field) ist der Feldname (KontoNr)
und der Feldtyp (int) als
erstes zu bestimmen. Daraufhin kann über die Checkbox „KeyField“
bestimmt werden, ob das Feld als Verwaltungsschlüssel dienen soll. Ob
entsprechende Getter und Setter –Methoden für das Feld erzeugt werden, gibt man
über die Checkbox „Access with Getter and Setter methods“ vor. Sollen
diese Methoden ebenfalls in der entfernten
Schnittstellen aufgenommen werden, ist die Checkbox „Promote Getter and Setter methods to remote interface“ anzuklicken.
Auf Basis dieser Konfiguration legt der Wizard die einzelnen Dateibezeichnungen
(Bean Class, Home Interface, Remote Interface)
fest. Nun kann der Wizard
wieder über „Finish“ beendet werden.
Der Wizard generiert daraufhin
automatisch eine Standard-Bean.
Innerhalb der J2EE-Ansicht wird
das Ergebnis der Generierungsprozess deutlich. Ein Doppelklick auf die Bean und
die generierten Dateien werden aufgelistet. Es wurde die Bean und die Home- und
Remote Schnittstellen erzeugt. Selbstverständlich lässt sich die EJB noch
modifizieren. WebSphere stellt für diese Aufgabe den
leistungsstarken EJB-Editor zur Verfügung, welcher die Korrektheit des Codes
automatisch prüft. Per Doppelklick auf ein EJB-Projekt, und der EJB-Editor wird
aufgerufen. Der Editor verfügt über verschiedene Registerreiter (General, Bean,
Security, Transaction, Environment)
zur Konfiguration der
verschiedenen Aspekte einer Bean. Der Registerreiter „Bean“ listet alle Beans eines EJB-Projekts innerhalb der linken Seite auf.
Jetzt ist eine Bean auszuwählen die konfiguriert werden soll. Daraufhin werden
alle Informationen der Bean auf der rechten Seite angezeigt. Dies umfasst die:
1)Bean Klasse
2)Home Schnittstelle
3)Remote Schnittstelle
4)und die Attribute der Bean.
Per Schaltfläche
"Edit" lässt sich jeder Eintrag beliebig editieren. Ebenso kann eine
neue Bean erzeugt oder eine alte Bean gelöscht werden.
Implementierungsdetails:
Für jede EJB-Klasse ist eine
entfernte (remote) und eine lokale (local)
Schnittstelle anzulegen. Zur Arbeitserleichterung generiert der Wizard diese
automatisch für uns. Die entfernte Schnittstelle nutzt die Clientschicht, um
die Geschäftsmethoden der EJB auszuführen. Darüber kann bei der KontoBean erfragt werden, wer der Kontoinhaber ist oder wie
der aktuelle Kontostand ist. Ebenso lassen sich die einzelnen Attribute einer
Bean darüber setzen. Mittels
öffentlicher Methoden set() und get()
greifen wir auf die internen Attribute der Bean-Klasse zu. Die lokale
Schnittstelle definiert für die Clientschicht die Lebensmöglichkeiten der
EJB-Objekte. Dies kann das Anlegen oder Löschen einer EJB sein. Per Default
sind alle Schnittstellenmethoden innerhalb der EJB-Klasse zu implementieren.
Dies betrifft in unserem Fall die Methodensignaturen setKontoNr(),
setKontoInhaber(), setKontoStand()
und getKontoNr(), getKontoInhaber(),
getKontoStand(). Sobald die EJB erschaffen wurde,
übernimmt der Container die Verwaltung. Dies geschieht durch die Generierung
der Implementierungsklasse für die entfernte und lokale Schnittstelle. Standardmäßig
werden solche Schnittstellen innerhalb von Modulen organisiert. Die entfernte
Schnittstelle der KontoBean hat folgenden Aufbau:
#Code1:#
package unixopen;
import java.rmi.RemoteException;
public interface Konto
extends javax.ejb.EJBObject {
public int getKontoNr()
throws RemoteException;
public float getKontostand()
throws RemoteException;
public String getKontoInhaber()
throws RemoteException;
public int setKontoNr()
throws RemoteException;
public float setKontostand()
throws RemoteException;
public String setKontoInhaber()
throws RemoteException; }
Nachdem die entfernte
Schnittstelle definiert ist, definieren wir die Sicht der realen Welt bzw. der
Öffentlichkeit auf diese Entity Bean. Dazu definieren
wir die Home-Schnittstelle für die Bean. Dies gibt an, wie die Bean angelegt
werden kann, diese zu lokalisieren ist und auch wieder zerstört werden kann.
Diese Methoden stellen das mögliche Verhalten einer Bean zur Laufzeit dar. Hier
die Definition der Home-Schnittstelle für die KontoBean
im Detail:
#Code2:#
package unixopen;
import java.rmi.RemoteException;
import java.ejb.CreateException;
import java.ejb.FinderException;
public interface KontoHome extends javax.ejb.EJBHome {
public Konto
create(int id) throws CreateException, RemoteException;
public Konto findByPrimaryKey (KontoPK pk) throws FinderException, RemoteException; }
Die Schnittstelle „KontoHome“ wird von der Schnittstelle „EJBHome“
abgeleitet. Diese gibt eine Methode vor, um Beans zu
löschen, so dass KontoHome diese automatisch erbt.
Die Implementierung von KontoHome ist somit
gezwungen, so eine Methode zu implementieren. Die KontoHome-Schnittstelle
definiert die zwei Methoden create() und findByPrimeryKey(). Durch diese Methoden wird eine Bean
angelegt oder lokalisiert. Damit die Schnittstelle auch gefunden wird, sollte
diese sich im gleichen Projektverzeichnis befinden, wie die gewöhnlichen
Klassen auch.
Die Entity
Bean-Implementierung:
Nun die eigentliche
Implementierung der Bean. Unsere KontoBean ist eine
CMP EntityBean.
Die Persistenz der Datenfelder
wird durch den Container sichergestellt. Somit fällt dessen Implementierung
simpel aus. Zusätzlich zu den Methoden der EJB sind alle Methoden der
entfernten und lokalen Schnittstelle zu implementieren. Hier der interne Aufbau
unserer
KontoBean Klasse:
#Code3:#
package unixopen;
import javax.ejb.EntityContext;
public class KontoBean implements javax.ejb.EntityBean {
public int id;
public int kontonr;
public float kontostand;
public String kontoinhaber;
public void ejbCreate
(int id)
{ this.id = id; }
public void ejbPostCreate
(int id)
{ // hier ist nichts notwendig! }
public int getKontoNr()
{ return kontonr; }
public float getKontostand()
{ return kontostand; }
public String getKontoInhaber()
{ return kontoinhaber; }
public void setKontoNr(int nr)
{ kontonr = nr; }
public void setKontostand(float stand)
{ kontostand = stand; }
public setKontoInhaber(String name)
{ kontoinhaber = name; }
public void setEntityContext (EntityContext ctx)
{ // nicht implementiert!
}
public void unsetEntityContext()
{ // nicht implementiert!
}
public void ejbActivate()
{ // nicht implementiert!
}
public void ejbPassive()
{ // nicht implementiert!
}
public void ejbLoad()
{ // nicht implementiert!
}
public void ejbStore()
{ // nicht implementiert! }
public void ejbRemove()
{ // nicht implementiert! }
Innerhalb des Pakets „unixopen“ wird die Klasse „KontoBean
„abgelegt, wo alle anderen Dateien ebenso liegen. Die Klasse „KontoBean“
wird von der Klasse „EntityBean“ abgeleitet, welche
fünf Methoden vordefiniert. Dies sind im Einzelnen EjbActivate(),
ejbPassivate(), ejbLoad() ejbStore() und ejbRemove(). Der
Container nutzt diese Methoden um die KontoBean über
verschiedene Ereignisse (Events) zur Laufzeit zu informieren. Da diese Methoden
bereits implementiert sind, braucht man diese hier nicht implementieren und
kann diese somit leer lassen. Da die KontoBean
einfach gehalten ist, benötigen wir keine spezielle Prozeßbehandlung
zur Laufzeit.
Im Fall unserer KontoBean gibt es nur eine create()
Methode, so dass es auch nur eine korrespondierende ejbCreate()
Methode und eine ejbPostCreate() geben kann. Wenn ein
Client eine Methode der Home-Schnittstelle aufruft, wird dies an die
betreffende ejbCreate() Methode einer Bean Instanz
delegiert. Die ejbCreate() Methode initialisiert dann
die Felder, in unserem Fall also die KontoBean und
setzt das ID-Feld auf einen übergebenen Integer-Wert. Nachdem die ejbCreate() ausgeführt wurde, wird die ejbPostCreate()
aufgerufen und führt zur Erzeugung der Bean.
Die ejbCreate
und ejbPostCreate Methoden müssen eine Signatur
aufweisen die mit den Parametern und gegebenenfalls mit den Exceptions
der Home-Schnittstellenmethode create()
übereinstimmt. Wie auch immer, die ejbCreate und ejbPostCreate sind nicht nötig, um RemoteException
oder CreateException werfen zu können. Der EJB
Container führt diese Exceptions nämlich automatisch
zur Laufzeit aus, wenn irgendwelche Probleme bei der Kommunikation oder andere
systemspezifischen Probleme auftauchen.
Die entityspezfischen
Methoden sind verantwortlich für das Setzen und Holen von Entity
Contexten. Die EntityContext
ist eine Schnittstelle, welche vom EJB-Container implementiert wird. Dieser
liefert die Bean Informationen über den Container, die Identität des Clients,
Transaktionskontrolle und andere Umgebungsinformationen, wenn die Bean diese
benötigt. Da unserer Bean sehr einfach gehalten ist, benötigen wir diese
Funktion nicht.
Die Datenbankschicht:
Jede Entity
Bean muss die Geschäftsdaten sichern. Die Daten existieren nur solange, wie das
Objekt im Speicher vorhanden ist. Man kommt nicht herum, diese innerhalb einer
Datenbank abzulegen. Eine Konto-Bean muss beispielsweise Daten für die
Kontonummer, den Kontoinhaber und den aktuellen Kontostand sichern. Nur so kann
die Anwendung mit diesen Daten arbeiten. Zum Glück automatisiert WebSphere diese Aufgabe für uns. Es generiert ein
Datenbank-Schema auf Basis der Entity Bean. Für jede Entity Bean wird eine Datenbank-Tabelle angelegt. Jedes
Datenfeld der Bean zeigt auf eine bestimmte Spalte der Tabelle. Der Entwickler
selektiert mit der rechten Maustaste das betreffende EJB-Projekt. Im
Kontextmenü wählt er dann den Eintrag "Generate->EJB to RDB Mapping" aus, was den Wizard startet. Jetzt ist
im Dialog der Eintrag „Top Down“ für den Entwickungsprozess
auszuwählen. Über „Next“ gelangt man dann auf die nächste Seite des Wizards. Dort ist „InstantDB“ als
Ziel-Datenbank auszuwählen. Dann ist der Datenbankname (KontoDB)
einzugeben. Der Eintrag „Schema Name“ ist hier leer zu lassen. Zum Schluss ist
die Checkbox „Generate DDL“ auszuwählen. Nun kann
über „Finish“ der Wizard beendet werden, wodurch der Generierungsprozess
startet. Das EJB-RDB-Mapping Tool zeigt im linken Fensterbereich die CMP-Felder
der Entity Bean und im rechten Bereich die Datenbank
Tabellen mit ihren einzelnen Feldern an.
Der Auslieferungsprozess:
Nun ist der optimale
Projektzeitpunkt, um die Korrektheit des Codes vor der Auslieferung zu prüfen.
Der WebSphere EJB Validator
prüft, ob die Enterprise Java Bean der EJB-Spezifikation entspricht. Dieser
Vorgang ist nur erfolgreich, wenn vorher das komplette Projekt kompiliert
wurde. Der Validator prüft dabei alle Aspekte des
Projektes. Zur Prüfung wählt man ein EJB-Projekt mittels rechter Maustaste aus
und kann über den Kontextmenüeintrag „Run Validation“ den Prozess starten.
Bevor es zur Auslieferung kommt, muss der Deployment-Code
generiert werden. WebSphere führt dies mithilfe des
EJB-Deploy-Tools durch. Innerhalb der Workbench kann über den Menüpunkt "Generate->Deploy Code & RMIC Stub"
der Prozess angestoßen werden. Eine entsprechende JAR-Datei mit dem Deploy-Code wird daraufhin erzeugt. Öffnet man diese Datei,
findet man eine Reihe von Klassendateien vor.
Test the Rest:
Im Anschluss sollte ein Test
gefahren werden, ob die Anwendung auch funktioniert. Der Prozess kann lokal
oder auf einem entfernten Applikationsserver ausgeführt werden. Dazu stellt WebSphere die Single Server Testumgebung bereit. Hierzu
selektiert man ein EJB-Projekt mittels rechter Maustaste und ruft den Kontextmenüeintrag
"Run On Server" auf. Daraufhin wird das EAR-Projekt auf dem Server
veröffentlicht und der Server gestartet. Zu Testzwecken wird ein webbasierter
EJB-Testclient für EJBs zur Verfügung gestellt. Als Erstes muss die Enterprise
Bean erstmal auf dem Server ausfindig gemacht werden.
Der JNDI-Explorer hilft bei dieser Aufgabe. Es ist der JNDI-Name einzutippen
und kann dann über die Lookup-Funktion nach EJBs suchen. Sobald die Bean
gefunden wurde, wird die Home-Schnittstelle der Bean innerhalb der EJB-Seite
angezeigt. Die EJB-Seite ist in drei Teilbereiche untergliedert. Der Erste
enthält alle Referenzen auf EJB-Objekte. Diese sind in Gruppen unterteilt. Der
Zweite listet die Parameter für die aktuell selektierte Methode auf. Der Dritte
zeigt die Ergebnisse aller Methodenaufrufe an.
Schluss:
WebSphere Application Developer
ermöglichen es besonders leicht moderne Multi-Tier-Systeme zu entwickeln.
Entsprechende Wizards begleiten aktiv den Entwicklungsprozess. Die fertigen
Anwendungen sind beliebig skalierbar, sehr sicher, portabel und sehr robust.
Die EJB-Architektur befreit dabei von der Systemprogrammierung und alle
Systemoperationen werden automatisiert ausgeführt. Man braucht kein Experte
mehr zu sein, um solche komplexen Anwendungen zu realisieren. Da die heutigen
Internet-Anwendungen quasi alle auf einer Multi-Tier-Architektur basieren,
kommt den „Enterprise Java Beans“ einen bedeutende Stellung zu. Den Grundstein
hat aber die Firma Sun mit der EJB-Spezifikation gelegt.
Bildunterschriften:
Bild1.tif:
Das ist die Entwicklungszentrale von
WebSphere Application Developer. Dem Einsteiger wird eine umfassende Einführung
geboten.
Bild2.tif:
Beliebige Projekttypen lassen sich mithilfe
eines Wizards anlegen.
Bild3.tif:
Mithilfe des Wizards wird hier eine Standard-EJB
generiert. Diese lässt sich individuell konfigurieren.
Bidl4.tif:
Über den EJB-Editor kann eine Bean flexibel
editiert werden.
Anpassungen lassen sich leicht vornehmen.
Bidl5.tif:
Über die J2EE-Ansicht wird jederzeit der
Überblick über ein Projekt gewahrt.
Bidl6.tif:
Innerhalb der Entwicklungsoberfläche lassen
sich verschiedene Perspektiven einnehmen.
Bild7.tif:
WebSphere verfügt über ein vielseitiges
Hilfesystem.
Fast alle Themengebiete werden umfassend
erläutert.
Bild8.tif:
Das EJB-RDB-Mapping Tool erlaubt die
Datenbankstruktur einzusehen, welche für eine Entity Bean erzeugt wurde.