Vorlesung „Informationssysteme: Neuere Konzepte“
Web & Datenbanken
Komponentenarchitekturen,
Enterprise Java Beans (EJB)
Michael Klein, 23.06.2005
1
Teilweise basierend auf Folien von Daniel Pfeifer, IPD
Motivation für EJB
Große Geschäftsanwendung: z.B. Banksystem
Früher: Großes, monolithisches System
Heute: Verteilte, webbasierte Architektur
Klient
Klient
Server
Server
DB
2
Klient
Um welche Probleme
müssen wir uns
kümmern?
Infrastrukturelle Probleme in verteilten Systemen
3

Entfernte Methodenaufrufe

Lastbalancierung

Transparentes Failover
(Unmerkliche Umleitung eines Klienten auf einen anderen Server
im Fehlerfall)

Festschreibung von Geschäftsdaten

Transaktionsverwaltung

Dynamische Softwareupdates

Logging

Mehrfädrigkeit (Multithreading)

Resource pooling

Sicherheit

Caching
 Middleware
Allg.: Schwierig,
aufwändig zu
programmieren
Idee: Server für Middlewaredienste
4

Server, der diese Middlewaredienste anbietet:
Applicationserver

Applikation = Code, der in der
Laufzeitumgebung des Applicationservers
abläuft

 Divide and conquer: Trenne
infrastrukturelle Aspekte aus dem
Anwendungscode und überlasse sie dem
Applicationserver
Weitere Idee: Komponenten
Idee:
Zerlege Anwendung in wieder verwendbare
Komponenten
Komponente:
Stück Software, welches eine wohldefinierte
Schnittstelle implementiert.
  keine gesamte Anwendung
5
Komponente – Beispiel (1)
Preis-Komponente für Computerhardware
Input: Menge von Produkten
Output: Endpreis
calculate
6
Teilprobleme:
 Basispreis
 Mengenrabatte
 Bundle-Rabatte
 Sonderpreis
 Steuern
 Porto
...
Komponente – Beispiel (2)
Preiskomponente auch für andere Gebiete sinnvoll
Z.B. bei
 Autoherstellern zur Berechnung von Preisanfragen
über das Internet
 Postfilialen zur Berechnung von Preisen am Schalter
 Online-Buchhändlern als ein Teil eines komplexeren
Workflows
 Kapselung der Logik als wieder verwendbare
Komponente
 Entstehung eines Komponentenmarktplatzes
7
Komponentenarchitektur
Komponentenarchitektur:
Satz von Vereinbarungen zwischen Komponente
und Applikationsserver, in dem sie läuft
ApplicationServer
Komponente
8
Vereinbarte Schnittstelle
(spezifiziert durch
Komponentenarchitektur)
EJB als Komponentenarchitektur
Enterprise Java Beans (EJB):
Komponentenarchitektur für serverseitige Javakomponenten
Enterprise Bean:
Eine EJB-Komponente
• „deployable“
• Können in Applikationsserver geladen und ausgeführt werden
Vorteile von EJB:
 Von Industrie standardisiert
 EJB-Spezifikation ist frei erhältlich (650-seitiges PDF-File)
 Schnellere Applikationserstellung
9
Warum Java?

Trennung von Interface und Implementierung

Sicherheit
 Keine Zeiger
 Keine Speicherlöcher
 Threadverwaltung
10

Große Klassenbibliothek

Plattformübergreifend
Andere Komponentenarchitekturen
11

Microsoft .NET

Common Object Request Broker Architecture
(CORBA)

Sun Open Net Environment (ONE)
Aufgaben von EJBs

Ausführung von Geschäftslogik
 Steuerberechnung
 Einkaufwagen
 Testen von Authentifizierung, Autorisierung
 Senden von Bestätigungsmails

Zugriff auf Datenbanken
 Eintragen einer Buchbestellung
 Überweisen von Geld zwischen Konten
 Anfragen einer Fehlerdatenbank

Zugriff auf externe Systeme
 SAP R/3, COBOL-Anwendung etc.
12
Wer ruft EJBs auf?

EJBs sind keine GUI-Komponenten!
Rich Clients
• Java Applet
• Anwendungsprogramm
Komponente
13
Dynamisch erzeugte
Webseiten
• Servlet
• JSP
Als Webservice
• SOAP, UDDI,
WSDL
Rollen beim Einsatz von EJBs
Tools
Tool Provider
EJBs
Application
Assembler
EJ Bean Provider
EJB Server
EJB Server
Provider
14
System
Application
Deployer
System
Administrator
EJB und J2EE (Java 2 Enterprise Edition)
 J2EE ist eine Ansammlung von JavaTechnologien bzw. Standards, die das
Komponentenmodell unterstützen
 Spezifikation, kein Produkt!
 Sun liefert zum Teil Implementierungen oder
definiert Standards, die von anderen Herstellern
zu erfüllen sind
 EJB ist ein Teil von J2EE mit einer
Referenzimplementierung von Sun
 http://java.sun.com/j2ee
15
Ausschnitt aus den J2EE-Technologien (1)
 JSP, Java-Servlet (bekannt)
 JDBC (bekannt)
 Java Transaction API (JTA/JTS) für verteilte
logische Transaktion
 Java Naming and Directory Service (JNDI):
Verzeichnisdienst für Java
 Remote Method Invocation (RMI): entfernter
Methodenaufruf über Prozessgrenzen hinweg,
inzwischen mit CORBA-Integration (RMI-IIOP)
16
Ausschnitt aus den J2EE-Technologien (2)
 EJB
 JavaMail
 Java Messaging Service (JMS): asynchrones,
zuverlässiges Verschicken von Nachrichten in
Objektform
 Java Connector Architecture (JCA)
zur standardisierten Integration von ERP-Systemen
wie SAP
 Java API for XML Parsing (JAXP)
 Java Authentication and Authorization Service
(JAAS)
17
 Zu jeder dieser Technologien gibt es eine API, eine
Spezifikation und mind. eine Implementierung
Grundsätzliche Architektur von EJB (1)
 EJB: Menge von Java-Klassen
(3 oder 5) mit genormter Struktur
 Ausführung dieser Klassen kommen in einem EJBContainern
 EJB-Container: Repräsentation eines ApplikationsServers
 Klienten können über/durch den EJB-Container auf
die EJBs zugreifen und deren Methoden aufrufen
 Die Methodenaufrufe erfolgen üblicherweise über
RMI (Remote Method Invocation)
 Der EJB-Container nimmt den Aufruf entgegen und
delegiert ihn an eine entsprechende EJB
18
Grundsätzliche Architektur (2)
19
Grundsätzliche Architektur (3)
Delegationsprinzip
• der Container erhält Kontrolle über die
EJB-Aufrufe
 transparent zusätzliche Funktionalität
bereitstellbar:
• Sicherheit
• Rechteverwaltung
• Transaktionalität
• Persistenz
• Lebenszyklusverwaltung von EJBs
• Nebenläufigkeit von Beans
20
2 Arten von EJBs
 Session Beans:
 Realisieren Workflows und Dienste
 Können für statische Funktionalität benutzt
werden
 Mit Zustand (stateful) oder zustandslos (stateless)
 Nicht persistierbar
 Bsp: Kreditkartenautorisierer, DNA-Sequenzer
 Entity Beans
 Repräsentieren Zustand und Verhalten realer
Objekte (zum Beispiel eines Artikels)
 Werden persistent in einer Datenbank gespeichert
 Bsp: Bankkonto, Bestellung, Produkt, DNA-Strang
21
Aufgabe: Finden von Session und Entity Beans
Bei der Warenkorbfunktionalität eines Webshobs
soll der Kunde die Möglichkeit haben, seine
aktuellen ausgewählten Artikel sowie alte Aufträge
einsehen zu können. Die Anzeige kann in einer
gewünschten Währung erfolgen und berechnet
automatisch die anfallenden Portokosten. Nach
einem Klick auf „Abschicken“ erhält der Kunde ein
persönliches Bestätigungsschreiben und seine
Bestellung wird in das System aufgenommen. Er
wird anschließend auf eine Seite geleitet, auf der
er weitere passende Angebote erhält.
22
Klienteninteraktion mit Beans
Anwendung von
Geschäftspartnern
Browser
HTML
C++ Client
Java-Applikation
Java-Applet
CORBA/IIOP
RMI
EJB Session
Bean
EJB Entity
Bean
23
SOAP
Servlet
JSP
Webserver
RMI
EJB Session
Bean
ApplicationServer
Eine EJB im Detail (1)
 3 (Java-) Klassen bzw. Interfaces
 Die Bean-Klasse: Funktionalität der Bean
(wichtigste Klasse)
 Das Home-Interface: Schnittstelle zum
Erzeugen, Finden und Löschen von EJBs durch
Klienten
 Das Remote-Interface stellt die „öffentlichen“
Methoden aus der Bean-Klasse den Klienten (für
den Aufruf über RMI) zur Verfügung
 Analog zu Home- und Remote-Interface können noch
zwei weitere Klassen (Local-Home- und LocalRemote-Interface) für nicht-RMI-Zugriffe auf
Beans hinzukommen...
24
Eine EJB im Detail (2)
25
EJB-Object
EJB-Container = Indirektionsstufe zwischen Klient und
Bean
 Aufruf der Bean nie direkt, sondern immer über EJBObject
EJB-Object weiß bescheid über
 Netzwerk
 Transaktionsschutz
 Sicherheit
EJB-Object = Teil des Kontainers, wird automatisch vom
Server-Provider aus der Enterprise Bean erzeugt.
26
Delegation über EJB-Object
27
Klientenzugriff auf eine EJB (1)
28

Die Klient besorgt sich Zugriff auf einen als bekannt
vorausgesetzten JNDI-Server

Über JNDI (dem Java Verzeichnis-Dienst) sucht (und
findet) er das Home-Interface der entsprechenden EJB

Möglich, weil das entsprechende EJB-Home-Interface mit
einem Namen (einem Java-String) im JNDIVerzeichnis registriert sein muss.

Über das Home-Interface kann man dann EJBs mit
speziellen find- und create-Methoden finden bzw.
erzeugen.

Man erhält dann eine RMI-Referenz auf eine Bean. Die
Referenz implementiert das Bean-Remote-Interface
Klientenzugriff auf eine EJB (2)
29
Beispiel EJB: Hello World
30

Komplett lauffähiger Code für EJB und
aufrufenden Klient

Implementiert als stateless Session-Bean
(zustandslos, nicht persistent)

Liefert den String „Hello, World!“ an den
Klienten, dieser gibt in auf der Konsole aus
Hello World: Hello.java
Remote Interface
package hello;
/**
* This is the HelloBean remote interface.
*/
public interface Hello extends javax.ejb.EJBObject
{
/**
* The
*/
one method - hello - returns a greeting to the client.
public String hello() throws java.rmi.RemoteException;
}
31
Hello World: HelloBean.java
Bean
package hello;
import javax.ejb.SessionContext;
// Implemented as stateless session bean.
public class HelloBean implements javax.ejb.SessionBean
{
// EJB-required methods
public void ejbCreate() {}
public void ejbRemove() {}
public void ejbActivate() {}
public void ejbPassivate() {}
public void setSessionContext(SessionContext ctx) {}
// Business methods
public String hello()
{
return "Hello, World!";
}
}
32
Hello World: HelloHome.java
Home Interface
package hello;
/**
* One create() method is in this Home Interface, which
* corresponds to the ejbCreate() method in HelloBean.
*/
public interface HelloHome extends javax.ejb.EJBHome
{
/*
* This method creates the EJB Object.
*
* @return The newly created EJB Object.
*/
Hello create() throws java.rmi.RemoteException,
javax.ejb.CreateException;
}
33
Hello World: HelloClient.java
package hello;
import javax.naming.Context;
import javax.naming.InitialContext;
import java.util.Properties;
public class HelloClient {
public static void main(String[] args) throws Exception {
Properties props = System.getProperties();
// Obtain the JNDI initial context.
Context ctx = new InitialContext(props);
// Get a reference to the hello home object
Object obj = ctx.lookup("ejb/local/examples/HelloWorld");
HelloHome home = (HelloHome)
javax.rmi.PortableRemoteObject.narrow(obj, HelloHome.class);
// Creat an instance of the hello ejb through hello home
Hello hello = home.create();
// Call the hello() method on the EJB object.
System.out.println(hello.hello());
34
} }
// Remove the ejb instance.
home.remove();
Besonderheiten
 Hello, HelloBean und HelloHome erweitern
jeweils Standard-EJB-Schnittstellen (nämlich
EJBObject, SessionBean bzw. EJBHome
 Notwendig damit der EJB-Container die EJB
gemäß der Spezifikation verwalten kann!
 Die Methoden ejbCreate(), ejbRemove(),
ejbActivate(), ejbPassivate() werden vom
EJB-Container als „Callbacks“ beim
Lebenszyklusmanagement aufgerufen
 Die EJB hat dann die Möglichkeit noch
Aktivitäten auszuführen, bevor der Container
in den Lebenszyklus eingreift.
35
Lebenszyklus einer Bean
 Um Ressourcen (wie etwa Hauptspeicher)
zu schonen kann und darf der Container
Beans auslagern (zum Beispiel serialisiert auf
die Festplatte schreiben) und später – wenn
notwendig – wieder einlagern
 Bean-Instanzen können auch in Pools
vorgehalten werden um dann effizient aktiviert
zu werden (instance pooling)
 Die Methoden der vorigen Folien unterstützen
diese Vorgänge von Seiten der Bean
36
Lebenszyklusdiagramm für Stateful Session-Beans
37
Installation von Beans
 Beans sollen installiert (deployed) werden
können, während der EJB-Server arbeitet (hot
deployment)
 Das ist wichtig, wenn der EJB-Server
unternehmenskritische Anwendungen birgt
(Beispiel Bank-Server, Einkaufsportal...)
  Deployment ist eigenständiger Prozess
 Funktionsweise hängt vom EJB-Server-Produkt
ab (bei JBoss: entspr. Dateien in ein besonderes
Verzeichnis kopieren...)
38
Format für Bean-Deployment
 Ist durch den EJB-Standard spezifiziert
 Die kompilierten Klassen einer EJB werden in
ein Java-Archiv gepackt (.jar Datei)
 Zusätzlich: Meta-Informationen über die EJB
in einer XML-Datei – dem Deployment
Descriptor
 .jar und xml Datei werden (mit einigen weiteren
Dateien) zu einem Enterprise Archiv (.ear
Datei ähnlich zu .jar Datei) geschnürt.
 Diese Datei wird dann „deployed“.
39
Deployment Deskriptor
 Enthält viele wichtige Infos für den EJBContainer, damit dieser weiß, wie er eine EJB
behandeln soll
 Geht nicht notwendig aus den Klassen der EJB hervor
 U.a. beschreibt der Deskriptor wie eine Bean zu
behandeln ist bzgl.
 Transaktionalität
 Zugriffrechten und Schutz
 Persistenz
 Failover (Verhalten beim Absturz der EJB-Servers)
 Nebenläufigkeit
 Struktur eines Deskriptors ist Teil des EJB-Standards
40
Der HelloWorld-Deskriptor
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>Hello</ejb-name>
<home>hello.HelloHome</home>
<remote>hello.Hello</remote>
<local-home>hello.HelloLocalHome</local-home>
<local>hello.HelloLocal</local>
<ejb-class>hello.HelloBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
</ejb-jar>
41
EJB und Datenbanken
42
Entity Beans (1)
 Repräsentieren persistente Zustände
 Der Standard für Entity-Beans ist auf ein
(simples) Objekt-Relationales-Mapping
ausgelegt, d.h. Speicherung in relationaler DB
 Andere Persistenztechniken möglich
43
Entity Beans (2)
44

Persistenz kann vom EJB-Container
(transparent) erledigt werden
 CMP – container managed persistence

... oder von Hand in der Entity Bean
programmiert werden
 BMP – bean managed persistence

Im 2. Fall kann man zum Beispiel JDBC
verwenden
Zur Verdeutlichung...
45
CMP versus BMP
 Wie gesehen: bei BMP muss man O/R Mapping für
jede Klasse „von Hand“ programmieren
 Man muss aber nicht JDBC verwenden
 Bei CMP über nimmt der Container die
Implementierung/Umsetzung der ejbLoad(),
ejbStore(), ejbCreate(), ejbRemove() – Methoden
 Detaillierte Mapping-Infos kommen in den
Deployment-Deskriptor und in containerspezifische XML-Dateien
46
Was sind also EJBs?
Was sind Enterprise Java Beans (EJB)?
Serverseitige Komponentenarchitektur zur einfachen
Erstellung von komponentenbasierten
Anwendungen, die
 verteilt
 skalierbar
 zuverlässig
 sicher
sind, ohne die komplexen Infrastrukturaufgaben
selbst programmieren zu müssen.
 Bereitstellung der Infrastruktur durch industrielle
Applicationserver.
47
Zusammenfassung
Komponente
Delegation
EJB-Object
EJB-Kontainer
CMP vs. BMP
Middleware
Home vs. Remote Interface
Komponentenarchitektur
J2EE
Applicationserver
48
Session-Bean vs. Entity Bean
Literatur
Buch
Ed Roman, Scott Ambler, Typer Jewell
Mastering Enterprise Java Beans (2nd Edition)
Wiley
ISBN 0-471-41711-4
Auch kostenlos im Internet herunterladbar
(Anmeldung erforderlich):
http://www.theserverside.com/books/wiley/masteringEJB/
49
ANHANG
(für Interessierte)
50
Entity Bean – Beispiel Code
 Repräsentiert Personen-Objekte mit Namen und
Id (Schlüssel)
 BMP
 Daten über JDBC in rel. Datenbank gespeichert
 Neben Standard Bean-Klassen gibt es noch die
PersonPK (=Primary Key) die den DB-Schlüssel
Id repräsentiert
 DB besteht aus (einziger Tabelle) Person(id,
ownerName)
51
Person.java
Remote Interface
package examples;
import javax.ejb.*;
import java.rmi.RemoteException;
public interface Person extends EJBObject
{
public String getName() throws RemoteException;
public void setName(String name) throws RemoteException;
public String getID() throws RemoteException;
public void setID(String id) throws RemoteException;
}
52
PersonHome.java
Home Interface
package examples;
import javax.ejb.*;
import java.util.Collection;
import java.rmi.RemoteException;
public interface PersonHome extends EJBHome
{
public Person create(String id, String ownerName)
throws CreateException, RemoteException;
public Person findByPrimaryKey(PersonPK key)
throws FinderException, RemoteException;
}
53
PersonPK.java
Bean
package examples;
import java.io.Serializable;
public class PersonPK implements java.io.Serializable
{
public String personID;
public PersonPK(String id) { this.personID = id; }
public PersonPK() {}
public int hashCode() { return personID.hashCode(); }
public boolean equals(Object person) {
return ((PersonPK)person).personID.equals(personID);
}
}
54
PK = Primary Key
PersonBean.java (1)
Bean
package examples;
import
import
import
import
java.sql.*;
javax.naming.*;
javax.ejb.*;
java.util.*;
public class PersonBean implements EntityBean {
protected EntityContext ctx;
private String id;
// PK
private String ownerName;
public AccountBean() {}
public
public
public
public
55
void setOwnerName(String name) { ownerName = name; }
String getOwnerName() { return ownerName; }
String getID() { return id };
void setID(String id) { this.id = id; }
PersonBean.java (2)
public void ejbRemove() throws RemoveException {
PersonPK pk = (PersonPK) ctx.getPrimaryKey();
String id = pk.id;
PreparedStatement pstmt = null;
Connection conn = null;
try {
conn = getConnection();
pstmt =
conn.prepareStatement("delete from persons where id = ?");
pstmt.setString(1, id);
if (pstmt.executeUpdate() == 0) {
throw new RemoveException("Person " + pk + " failed remove.");
}
} catch (Exception ex) {
throw new EJBException(ex.toString()); }
finally { /* ... close JDBC resources... */ } }
56
PersonBean.java (3)
public void ejbLoad() {
PersonPK pk = (PersonPK) ctx.getPrimaryKey();
String id = pk.id;
PreparedStatement pstmt = null;
Connection conn = null;
try {
conn = getConnection();
pstmt =
conn.prepareStatement(
"select ownerName from persons where id = ?");
pstmt.setString(1, id);
ResultSet rs = pstmt.executeQuery();
rs.next();
ownerName = rs.getString("ownerName");
}
catch (Exception ex) {
throw new EJBException("Person " + pk + " failed to load.", ex);
} finally {
// ... close JDBC resources... } }
57
PersonBean.java (4)
public PersonPK ejbFindByPrimaryKey(PersonPK key)
throws FinderException {
PreparedStatement pstmt = null;
Connection conn = null;
try {
conn = getConnection();
pstmt =
conn.prepareStatement("select id from persons where id = ?");
pstmt.setString(1, key.toString());
ResultSet rs = pstmt.executeQuery();
rs.next();
return key;
} catch (Exception e) {
throw new FinderException(e.toString());
} finally {
// ... close JDBC resources...
}
}
58
PersonBean.java (5)
public
public
public
public
public
void
void
void
void
void
ejbActivate() {}
ejbPassivate() {}
setEntityContext(EntityContext ctx) { this.ctx = ctx; }
unsetEntityContext() { this.ctx = null; }
ejbPostCreate(String accountID, String ownerName) {}
public void ejbStore() {
// ... Ähnlich wie ejbLoad ...
}
public PersonPK ejbCreate(String id, String ownerName)
throws CreateException {
// ... Ähnlich wie ejbFindByPrimaryKey ...
}
59
PersonBean.java (6)
public Connection getConnection() throws Exception {
try {
Context ctx = new InitialContext();
javax.sql.DataSource ds =
(javax.sql.DataSource)
ctx.lookup("java:comp/env/jdbc/ejbPool");
return ds.getConnection();
}
catch (Exception e) {
throw e; }
}
60
Ok – eine Menge Code...
 Das meiste sind JDBC Zugriffe die Tabellenzeilen auf
EJB-Felder abbilden
 Noch mehr Callbacks als bei Session Beans:
 PersonBean erweitert javax.ejb.EntityBean und
muß nun
 ejbLoad() zum Laden der Bean aus der DB und
 ejbStore() zum Speichern den Bean in DB
implementieren
 sowie einige weiter Methoden...
 ejbFind...() Methoden dienen zum Finden von
Enitity Beans über Suchkritierien
 Es werden dann (meist) Kollektionen von Schlüsseln
(wie etwa PersonPK) zurückgegeben.
61