218
Enterprise JavaBeans 2.x Enterprise JavaBeans 2.x Enterprise JavaBeans 2.x Enterprise JavaBeans 2.x Autor Stephan Metzler © 2008 Version 3.0

› j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

Enterprise JavaBeans 2.xEnterprise JavaBeans 2.xEnterprise JavaBeans 2.xEnterprise JavaBeans 2.x

Autor Stephan Metzler © 2008 Version 3.0

Page 2: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten

PrologPrologPrologProlog

Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als Applikationsframework zum Erstellen von verteilten Applikationen.

Der Inhalt ist gegliedert in:

A : Java 2 EnterpriseEdition

- Theorieaspekt der verteilten Systeme und Übersicht über das J2EE Applikationsframework

B : Enterprise JavaBeans

- Betrachtungen der einzelnen EJB Ausprägungen

C : Best Practice

- Diskussion einiger J2EE Idioms und weiterführende Beispiele mit dem JBoss AS

D : EJB 3.0

- Ausblick auf die EJB 3.0 Spezifikation

E : Aufsetzen und Konfiguration der Entwicklungsumgebung

- Installationsanleitung für die begleitenden Beispiele

F : Lösungen zu den Übungen

- Lösungen zu den begleitenden Beispielen

G : Glossar

- ein Glossar mit den verwendeten Begriffen der EJB Thematik

H : Referenzen

- Literaturangaben, Online-Quellen sowie die verwendeten Software Versionen

Page 3: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Seite 3 von total 218 Seiten

InhaltsverzeichnisInhaltsverzeichnisInhaltsverzeichnisInhaltsverzeichnis SeiteSeiteSeiteSeite

A Java 2 EnterpriseEdition 8

1111 Java PlattformJava PlattformJava PlattformJava Plattform 8888

1.1 Verteilte Systeme 8

1.2 Technologien für Verteilte Systeme 9

2222 J2EE ApplikationsframeworkJ2EE ApplikationsframeworkJ2EE ApplikationsframeworkJ2EE Applikationsframework 10101010

2.1 Einsatzgebiete 10

2.2 Architektur 10

2.3 Namenskonventionen 11

2.4 Bestandteile einer J2EE-Anwendung 11

2.5 Multi-Tier Application 12

2.5.1 3 Schicht Architektur 12

2.5.2 J2EE Server mit WEB- und BusinessTier 12

2.5.3 J2EE Server mit JavaBean Komponenten als Interface 12

2.5.4 J2EE Server mit WEB-, BusinessTier und EIS Tier 12

B Enterprise JavaBeans 13

3333 EJB DefinitionEJB DefinitionEJB DefinitionEJB Definition 13131313

3.1 EJB Architektur 14

3.2 EJB Typen 14

3.3 Elemente einer EJB Komponente 15

3.3.1 Home Interface 15

3.3.2 Remote Interface 15

3.3.3 Bean Implementierung 15

3.3.4 Deployment Descriptor 15

4444 Hello EJB WorldHello EJB WorldHello EJB WorldHello EJB World 16161616

4.1 Voraussetzungen 16

4.2 Aufgabe 16

4.3 Organisation 16

4.4 Umgebungsvariablen 16

4.5 Ziel 16

4.6 Hello EJB World Java Source Dateien 17

4.7 "Hello EJB World" Bean mit Sun Java™ Deploytool deployen 19

4.7.1 Applikations-Server starten / stoppen 19

4.7.2 Deployment Applikation starten 19

4.8 Deployment 20

4.9 Client Applikation ausführen 20

5555 Inside EJBInside EJBInside EJBInside EJB 24242424

5.1 EJB Klassen Diagramm 24

5.2 EJB Komponenten 25

5.2.1 HOME Interface 25

5.2.2 REMOTE Interface 26

5.2.3 BEAN Implementation 26

5.2.4 Deployment Descriptor 26

5.2.5 Überblick der Elemente einer EJB-Komponente 27

5.2.6 EJB Rollen: 27

5.3 Zugriff auf ein EJB 28

5.3.1 Sequenz Diagramm 29

Page 4: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Seite 4 von total 218 Seiten

5.4 RMI (Remote Method Invocation) 29

5.4.1 RMI Kommunikationsmodell 30

5.5 EJB Kommunikationsmodelle 31

5.5.1 synchrone, entfernte Kommunikation 32

5.5.2 synchrone, lokale Kommunikation 33

5.5.3 asynchron, nachrichtenbasierte Kommunikation 34

5.5.4 Überblick über die Kommunikationsmodelle 34

6666 Stateless Session Bean ( zustandslos)Stateless Session Bean ( zustandslos)Stateless Session Bean ( zustandslos)Stateless Session Bean ( zustandslos) 35353535

6.1 Bean Life Cycle 35

6.2 Übung ee1 : Zinsberechnung 36

7777 Stateful Session Bean ( Stateful Session Bean ( Stateful Session Bean ( Stateful Session Bean ( zustandsbehaftet )zustandsbehaftet )zustandsbehaftet )zustandsbehaftet ) 37373737

7.1 Bean Life Cycle 37

7.2 Übung ee2 : Kontoführung 38

7.2.1 Konsolen Statements 38

7.2.2 Environment Entries als InitialContext 38

8888 Entity Bean ( für die Abbildung von Entity Bean ( für die Abbildung von Entity Bean ( für die Abbildung von Entity Bean ( für die Abbildung von Daten einer DB )Daten einer DB )Daten einer DB )Daten einer DB ) 39393939

8.1 Bean Life Cycle 39

8.1.1 EJB-Container Life-Cycle- Methoden 40

8.1.2 Persistenzoperationen einer Entity Bean 40

8.2 Modellieren von persistenten Geschäftsdaten 41

8.2.1 Übung ee3 : Personenverwaltung mit CMP 1.0 41

8.2.2 CMP/CMR in EJB 2.0 45

8.2.3 Übung ee31 : Triviale Kundenverwaltung mit Entity Bean (CMP 2.0) 45

C Best Practice 50

9999 Design PatternsDesign PatternsDesign PatternsDesign Patterns 50505050

9.1 Einführung 50

9.1.1 Zweck 50

9.1.2 Geschichtliches 50

9.1.3 Referenzen 50

9.2 Singleton Pattern 51

9.2.1 Problem 51

9.2.2 Lösung 51

9.2.3 Implementation 51

9.3 Proxy Pattern 53

9.3.1 Problem 53

9.3.2 Lösung 53

9.3.3 Implementation 54

9.4 Factory Method Pattern 55

9.4.1 Problem 55

9.4.2 Lösung 55

9.4.3 Implementation 56

9.5 J2EE Pattern 57

9.5.1 Service Locator 58

9.5.2 Business Delegate 60

9.5.3 Value Object 61

9.5.4 Session Façade 63

9.6 Weitere Pattern im J2EE Umfeld 64

9.6.1 Value Object Assembler 64

9.6.2 Composite Entity 64

9.6.3 Data Access Objects DAO 65

Page 5: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Seite 5 von total 218 Seiten

9.6.4 Core J2EE Patterns 65

10101010 Programmiereinschränkungen (Regeln)Programmiereinschränkungen (Regeln)Programmiereinschränkungen (Regeln)Programmiereinschränkungen (Regeln) 66666666

11111111 EJB Anwendungsbeispiele mit JBoss ASEJB Anwendungsbeispiele mit JBoss ASEJB Anwendungsbeispiele mit JBoss ASEJB Anwendungsbeispiele mit JBoss AS 67676767

11.1 wiederverwendbare Komponenten 67

11.2 EJB Container 67

11.3 EJB Ausprägungen 68

11.4 EJB Schnittstellen 69

11.5 EJB Bestandteile 69

11.6 EJB Implementation 70

11.7 EJB Deployment Descriptors 71

12121212 Übung ee4 : Datenanbindung mit Stateless Session BeanÜbung ee4 : Datenanbindung mit Stateless Session BeanÜbung ee4 : Datenanbindung mit Stateless Session BeanÜbung ee4 : Datenanbindung mit Stateless Session Bean 74747474

12.1 JDBC API 74

12.2 Währungsrechner mit Session-Beans 74

12.2.1 Datenbankanbindung mit Session-Beans 74

12.2.2 JDBC Connection 75

12.2.3 JNDI lookup Connection 75

13131313 Übung ee5 : Robuste Referenzen auf Stateful Session BeansÜbung ee5 : Robuste Referenzen auf Stateful Session BeansÜbung ee5 : Robuste Referenzen auf Stateful Session BeansÜbung ee5 : Robuste Referenzen auf Stateful Session Beans 76767676

13.1 Handles 76

13.2 Kontoführung mit Stateful Session Bean 77

13.2.1 Bean Identität mit Handle speichern 77

13.2.2 Handle persistent in Datei speichern 78

14141414 Übung ee6 : EJB QL (CMP 2.0)Übung ee6 : EJB QL (CMP 2.0)Übung ee6 : EJB QL (CMP 2.0)Übung ee6 : EJB QL (CMP 2.0) 79797979

14.1 EJB QL 79

14.2 Primary Key Klasse 81

14.3 ProductShop 82

14.3.1 Summe aus allen Produkten 83

15151515 Übung ee62 : PersonBean mittels BMP Entity BeanÜbung ee62 : PersonBean mittels BMP Entity BeanÜbung ee62 : PersonBean mittels BMP Entity BeanÜbung ee62 : PersonBean mittels BMP Entity Bean 84848484

15.1 BMP – Bean Managed Persistence 84

15.2 BMP Person Bean 85

16161616 ServletsServletsServletsServlets 89898989

16.1 Vor- und Nachteile dynamischer Web-Inhalte 89

16.2 Grundlagen 89

16.3 Funktionsweise 89

16.4 Lebenszyklus 90

16.5 Übung ee7 : Servlet – ein Beispiel 91

16.6 Übung ee71 : Web Browser als EJB Client 93

17171717 JSP JavaServer PagesJSP JavaServer PagesJSP JavaServer PagesJSP JavaServer Pages 94949494

17.1 Grundidee 94

17.2 Funktionsweise 94

17.3 Organisation 94

17.4 Aufbau von JavaServer Pages 95

17.5 Kommentare 95

17.6 Ausdrücke / Expressions 95

17.7 Direktiven 96

17.8 Deklarationen 96

17.9 Skriptlets 97

17.10 Aktionen 98

17.11 Fehlerbehandlung 98

17.12 Vordefinierte Variablen 99

17.13 Übung ee8: JSP Währungsrechner mit JDBC, TagLib und EJB 99

Page 6: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Seite 6 von total 218 Seiten

18181818 J2EE SecurityJ2EE SecurityJ2EE SecurityJ2EE Security 101101101101

18.1 EJB-Security 101

18.1.1 Security Roles 103

18.2 Client-Tier Sicherheit 106

18.2.1 ApplicationClients 106

18.2.2 WebClients 106

18.3 JNDI Sicherheit 107

18.4 Realms 107

18.5 Legacy Tier 107

18.6 Declarative vs Programmatic Security 108

18.7 J2EE Security Architecture 108

18.8 Role Mapping 108

18.9 ejb-jar.xml Security Elemente 109

18.10 Übung ee9 : J2EE Security 110

18.10.1 deklarative Security 111

18.10.2 prommatische Security 111

19191919 TransaktionenTransaktionenTransaktionenTransaktionen 112112112112

19.1 Transaktionskonzepte 112

19.1.1 Lokale und verteilte Transaktionen 112

19.1.2 Zwei Phasen Commit 113

19.2 Java Transaction API (JTA) und Java Transaction Service (JTS) 113

19.3 User-Transaktionen 115

19.3.1 Bean Managed Transaction 115

19.3.2 Container-Managed-Transactions 117

19.3.3 JDBC Transaktionen 119

19.4 Übung ee10 : EJB Transaction 120

19.4.1 Transaktionssteuerung 120

20202020 Message Driven BeansMessage Driven BeansMessage Driven BeansMessage Driven Beans 124124124124

20.1 JMS 124

20.2 MDB 126

20.2.1 Bean Life Cycle 126

20.3 Übung ee11 : MDB Wetterstation 127

D EJB 3.0 129

21212121 Alles wird viel einfacher!Alles wird viel einfacher!Alles wird viel einfacher!Alles wird viel einfacher! 129129129129

21.1 EJB 3.0 Spezifikation 129

21.2 EJB 3.0 Features 129

21.3 Meta-Annotationen 130

21.4 JNDI Kapselung 131

21.5 Configuration by Exception 132

21.6 Callback-Annotationen für Lifecycle Events 132

21.7 Interzeptor-Methoden 132

21.8 Stateless Session Bean 133

21.9 Statefull Session Bean 134

21.10 Message Driven Bean 135

21.11 Entity Bean 135

21.12 EJB QL 137

21.13 Zusammenfassung 138

E Aufsetzen und Konfiguration der Entwicklungsumgebung 139

Page 7: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Seite 7 von total 218 Seiten

22222222 Entwicklungstools für J2EEEntwicklungstools für J2EEEntwicklungstools für J2EEEntwicklungstools für J2EE 139139139139

23232323 Java J2SE / J2EE InstallationJava J2SE / J2EE InstallationJava J2SE / J2EE InstallationJava J2SE / J2EE Installation 139139139139

24242424 Eclipse als EntwicklungsumgebungEclipse als EntwicklungsumgebungEclipse als EntwicklungsumgebungEclipse als Entwicklungsumgebung 140140140140

24.1 Installation 140

24.2 Eclipse starten 140

25252525 JBoss ASJBoss ASJBoss ASJBoss AS 141141141141

25.1 Installation 141

25.2 JBoss AS starten / stoppen 141

25.3 JBoss Verzeichnisstruktur 142

25.4 Benutzerspezifischer Server einrichten 142

25.5 Benutzerspezifischer JBoss-Server starten 143

26262626 mySQL Datenbankserver installieren und Datenbank erstellenmySQL Datenbankserver installieren und Datenbank erstellenmySQL Datenbankserver installieren und Datenbank erstellenmySQL Datenbankserver installieren und Datenbank erstellen 144144144144

26.1 Installation 144

26.2 mySQL-Tools 144

26.3 EnterpriseEducation DB anlegen 144

27272727 EJB Applikation mit Eclipse / JBossEJB Applikation mit Eclipse / JBossEJB Applikation mit Eclipse / JBossEJB Applikation mit Eclipse / JBoss 145145145145

28282828 TomcatTomcatTomcatTomcat 149149149149

28.1 Server Architektur 149

28.2 Installation 150

F Lösungen zu den Übungen 151

29292929 Lösungen zu Übungen aus dem SkriptLösungen zu Übungen aus dem SkriptLösungen zu Übungen aus dem SkriptLösungen zu Übungen aus dem Skript 151151151151

29.1 Lösung zu Übung ee1 : Stateless Session Bean – Zinsberechnung 151

29.2 Lösung zu Übung ee2 : Stateful Session Bean – Kontoführung 153

29.3 Lösung zu Übung ee3 : CMP 1.0 Entity Bean – Personenverwaltung 156

29.4 Lösung zu Übung ee3.1 : Entity Bean CMP 2.0 - Kundenverwaltung 160

29.5 Lösung zu Übung ee4 : DB Session Bean - Money Exchange 165

29.6 Lösung zu Übung ee5 : Handle auf Session Bean - AutomaticTeller 169

29.7 Lösung zu Übung ee6 : CMP 2.0 Entity Bean - ProductShop 173

29.8 Lösung zu Übung ee61 : CMP2.0 Local Interface - Summe aller Produkte 177

29.9 Lösung zu Übung ee62: BMP Entity Bean - PersonBean 182

29.10 Lösung zu Übung ee7 : Servlet - WorkingServlet 187

29.11 Lösung zu Übung ee71: Servlet mit EJB Client - Web Shop 189

29.12 Lösung zu Übung ee8 : JSP mit JDBC, Taglib und EJB - Währungsrechner 192

29.13 Lösung zu Übung ee91 : EJB Security 197

29.14 Lösung zu Übung ee10 : EJB Transaction 201

29.15 Lösung zu Übung ee11 : MDB - WetterTopic 207

G Glossar 209

H Referenzen 216

30303030 QuellenangabenQuellenangabenQuellenangabenQuellenangaben 216216216216

30.1 Bücher 216

30.2 Online Quellen 217

31313131 Installierte SoftwareInstallierte SoftwareInstallierte SoftwareInstallierte Software 218218218218

Page 8: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Java Plattform Seite 8 von total 218 Seiten

J2ME Micro Edition

J2EE Enterprise Edition

J2SE Standard Edition

AAAA Java 2 EnterpriseEditionJava 2 EnterpriseEditionJava 2 EnterpriseEditionJava 2 EnterpriseEdition

1111 Java PlattformJava PlattformJava PlattformJava Plattform

Die Java Plattform ist in drei Editionen aufgeteilt:

J2ME definiert eine robuste, robuste, robuste, robuste, flexibleflexibleflexibleflexible Umgebung für Applikationen in:

- consumer devices wie Mobil-Telefone, PDAs

- embedded devices

J2ME beinhaltet eine VM und Standart Java APIs für Kommunikationsprozesse.

Die J2SE definiert zwei Produkte:

- JRE, Runtime Environment beinhaltet APIs, VM, etc.

- JDK, Development Kit beinhaltet JRE sowie Compiler, Debugger, etc.

Stellt die Basis für J2EE dar.

J2EE definiert einen Standart um Multi-Tier Enterprise Applikationen zu entwickeln.

Stellt verschiedene Dienst-leistungen den einzelnen Komponenten zur Verfügung und bietet transparente Lösungen für dessen vielseitiges Verhalten.

1.1 Verteilte Systeme

Ein verteiltes System besteht aus mehreren Prozessen, die mittels Nachrichtenaustausch miteinander kommunizieren. Dabei sind wichtige Kriterien:

Gemeinsame Nutzung von RessourcenGemeinsame Nutzung von RessourcenGemeinsame Nutzung von RessourcenGemeinsame Nutzung von Ressourcen

- Zugriff, Verzögerung und Updates müssen zuverlässig und konsistent sein

OffenheitOffenheitOffenheitOffenheit

- Erweiterbarkeit des Systems (Hardware, Software)

- Standardisierung von Schnittstellen erforderlich

- Interprozesskommunikation muss unterstützt werden

- heterogene HW- und SW- Komponenten sind Bestandteil eines offenen Systems

Client Server Architektur

SkalierbarkeitSkalierbarkeitSkalierbarkeitSkalierbarkeit

- Skalierung des Systems ohne Änderungen der System- oder Anwendungssoftware

FehlertoleranzFehlertoleranzFehlertoleranzFehlertoleranz

- Hardwareredundanz, Softwareredundanz

Peer-to-Peer Architektuer

Page 9: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Java Plattform Seite 9 von total 218 Seiten

1.2 Technologien für Verteilte Systeme

CORBACORBACORBACORBA (Common Object Request Broker Architecture):

- Plattform- und Sprachunabhängig

- nur "basic distribution"

DCOMDCOMDCOMDCOM (Distributed COM) Dienste zur Kommunikation zwischen Prozessen

- fokussiert auf Microsoft

- CORBA-DCOM Bridge

....NETNETNETNET (Microsoft)

- Sprach- und (Plattform-) unabhängiges Framework für Verteilte Systeme

EJBEJBEJBEJB (Enterprise Java Beans)

- nur JAVA

- entwickelt für Geschäftsprozesse

- Sicherheits- und Verbindungslogik ist integriert

Page 10: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 J2EE Applikationsframework Seite 10 von total 218 Seiten

J2EE JDBCJDBCJDBCJDBC

JNDIJNDIJNDIJNDI JTAJTAJTAJTA JMSJMSJMSJMS

ORACLE DB2

COS LDAP

DNS

IBM MQSeries iBus

BEATuxedo

2222 J2EE ApplikationsframeworkJ2EE ApplikationsframeworkJ2EE ApplikationsframeworkJ2EE Applikationsframework

J2EE bezeichnet ein Applikationsframework, ausgelegt auf:

- Performance

- Skalierbarkeit

- Plattformunabhängigkeit

Die Trennung zwischen Client-Tier, Business-Tier und Data-Tier ist sehr sauber implementiert und erlaubt eine weitgehende Unabhängigkeit von den verwendeten Clients und den Systemen zur Datenhaltung im Backend.

J2EE Applikations-Server beinhaltet:

- ComponentsComponentsComponentsComponents Applets, Servlets, Enterprise Java Beans

- ContainersContainersContainersContainers Web Browsers, Servlet Engines, EJB Containers

- ResourcesResourcesResourcesResources SQL Datenquellen, Nachrichtensysteme, Mailsysteme

2.1 Einsatzgebiete

J2EE Applikationen finden in den folgenden Gebieten ihren Schwerpunkt:

- Datenbankzugriff - Dynamische Internetseiten - Enterprise JavaBeans - Middle-Tier Server - Plattformenabhängige Kommunikation - Sicherheit - Trennung der Anwenderschwerpunkte - Verteilte Systeme - Web-Server-Einsatz

2.2 Architektur

Funktionelle Einheiten werden als Komponenten bezeichnet und zu einer Komponenten-Architektur zusammengefasst. Dabei dominieren die folgenden "Core Technologies":

- JNDIJNDIJNDIJNDI (Java Naming and Directory Interface) ermöglicht den Zugriff auf "naming" und "directory" Systeme wie LDAP, COS oder DNS

- JTAJTAJTAJTA (Java Transaktion API) ermöglicht den Zugriff auf Transaction Systeme wie BEA Tuxedo, etc.

- JDBCJDBCJDBCJDBC (Java DataBase Connectivity) ermöglicht Zugriff zu relationalen Datenbanken

- JMSJMSJMSJMS (Java Messaging Service ) ermöglicht den Zugriff zu Message Orientated Middleware, z.B. iBus ,IBM MQSeries

Page 11: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 J2EE Applikationsframework Seite 11 von total 218 Seiten

2.3 Namenskonventionen

ItemItemItemItem SyntaxSyntaxSyntaxSyntax BeispielBeispielBeispielBeispiel

Enterprise Bean Name (DD) <name>Bean HelloWorldBean

EJB JAR Display Name (DD) <name>JAR HelloWorldJAR

Enterprise Bean Class <name>Bean HelloWorldBean

Home Interface <name>Home HelloWorldHome

Remote Interface <name> HelloWorld

Local Home Interface <name>LocalHome HelloWorldLocalHome

Local Remote Interface <name>Local HelloWorldLocal

Abstract Schema (DD) <name> HelloWorld

2.4 Bestandteile einer J2EE-Anwendung

Eine J2EE-Anwendung ist eine J2EE-Komponente, die über einen J2EE-Server verschiedenen Clients zur Verfügung gestellt wird. Die Bestandteile einer J2EE-Anwendung werden in eine *.ear Datei (eeeenterprise ararararchive) gepackt und können aus den folgenden Komponenten bestehen:

- Enterprise BeansEnterprise BeansEnterprise BeansEnterprise Beans eine oder mehrere Enterprise Beans in einem *.jar Datei (java archive)

- WEBWEBWEBWEB----AnwendungenAnwendungenAnwendungenAnwendungen

HTML-Seiten, Servlets, JSP, gif- und jpg-Bilder in einer *.war Datei (web application archive)

- ClientClientClientClient----AnwendungenAnwendungenAnwendungenAnwendungen

Stand-Alone Java Applikation in einer *.jar Datei (java archive)

- Deployment DescriptorsDeployment DescriptorsDeployment DescriptorsDeployment Descriptors

XML-Dokummente zur Integrationsbeschreibung (sind Bestandteil jeder EAR Komponente)

Das Enterprise Archive folgt nebenstehender Struktur die dem Applikationsserver das Entpacken der Komponenten und das Deployen der J2EE Applikation ermöglicht:

HelloWorld.ear

HelloWorld.jar

HelloWorldClient.jar

HelloWorldWeb.war

Page 12: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 J2EE Applikationsframework Seite 12 von total 218 Seiten

2.5 Multi-Tier Application

Das Verteilen einer Applikation richtet sich meistens nach dem "seperation of concern" Aspekt der OOA.

2.5.1 3 Schicht Architektur RMI RMI RMI RMI = Remote Method Invocation IIOPIIOPIIOPIIOP = Internet Inter ORB Protocol

HTTPHTTPHTTPHTTP

RMIRMIRMIRMI----IIOPIIOPIIOPIIOP

IIOPIIOPIIOPIIOP

CLIENT-Tier LOGIK-Tier DATA-Tier

2.5.2 J2EE Server mit WEB- und BusinessTier

2.5.3 J2EE Server mit JavaBean Komponenten als Interface

2.5.4 J2EE Server mit WEB-, BusinessTier und EIS Tier

WEB BrowserWEB BrowserWEB BrowserWEB Browser HTML, Applets

J2EE Client ContainerJ2EE Client ContainerJ2EE Client ContainerJ2EE Client Container J2EE Client

stand alone Java Clientstand alone Java Clientstand alone Java Clientstand alone Java Client

C++ ClientC++ ClientC++ ClientC++ Client

WEB ServerWEB ServerWEB ServerWEB Server Java Servlets JSP

Applikation ServerApplikation ServerApplikation ServerApplikation Server EJB

DATADATADATADATA

Page 13: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 EJB Definition Seite 13 von total 218 Seiten

BBBB Enterprise JavaBeansEnterprise JavaBeansEnterprise JavaBeansEnterprise JavaBeans

3333 EJB DefinitionEJB DefinitionEJB DefinitionEJB Definition

DevelopmentDevelopmentDevelopmentDevelopment, EntwicklungEntwicklungEntwicklungEntwicklung, DistributionDistributionDistributionDistribution and

VerteilungVerteilungVerteilungVerteilung und

DeploymentDeploymentDeploymentDeployment of

UmsetzungUmsetzungUmsetzungUmsetzung (von Modellen) Militär: Truppenbereitstellung / Installation

JavaJavaJavaJava----BasBasBasBasedededed Java basiertenJava basiertenJava basiertenJava basierten ServerServerServerServer----SideSideSideSide serverseitigenserverseitigenserverseitigenserverseitigen Software ComponentsSoftware ComponentsSoftware ComponentsSoftware Components Software KomponentenSoftware KomponentenSoftware KomponentenSoftware Komponenten

EJB Technologie definiertEJB Technologie definiertEJB Technologie definiertEJB Technologie definiert

- Interfaces

- Patterns

- Richtlinien

für komponenten-orientierte, verteilte Systeme.

EJB KomponenteEJB KomponenteEJB KomponenteEJB Komponente

- definiert Funktionalität

- Black Box

- Zugriff nur über Schnittstelle

- Wiederverwendbarkeit

EJB ZieleEJB ZieleEJB ZieleEJB Ziele

- Entwicklung von Geschäftsprozessen ( keine Systemprozesse )

- Standard für Komponenten basierte Entwicklung

- Wiederverwendbarkeit

http://www.ejip.net/images/ejb.jpg

Page 14: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 EJB Definition Seite 14 von total 218 Seiten

Applikation Server

Services

EJB CONTAINER

EJB EJB EJB

Transaction Security Distribution

Persistance Naming

Client

Client

Client

3.1 EJB Architektur

- EJBs existieren innerhalb von Containern

- Applikations-Server stellt Dienste zur Verfügung

3.2 EJB Typen

Session BeanSession BeanSession BeanSession Bean Entity BeanEntity BeanEntity BeanEntity Bean Message Driven BeanMessage Driven BeanMessage Driven BeanMessage Driven Bean

Zweck Stellt einen Prozess für einen Client dar, z.B. Geldautomat

Stellt Daten dar. Entitäten oder Objekte im persistenten Speicher (DB)

Stellt einen Nachrichten-empfänger dar.

Ausprägung StatelessStatelessStatelessStateless Session Bean StatefullStatefullStatefullStatefull SessionBean

BeanBeanBeanBean Managed Persistence ContainerContainerContainerContainer Managed Persistence

Message Driven Bean

Gemeinsame Nutzung

StatefullStatefullStatefullStatefull Session Bean dedizierte Client Zuordnung StatelessStatelessStatelessStateless Session Bean hat keine Client Zuordnung

Gemeinsame Nutzung durch mehrere Clients möglich

keine direkte Client-zuordnung, "horcht" auf einem JMs-Kanal

Persistenz TransientTransientTransientTransient Lebenszyklus typischerweise durch Clientprozess bestimmt

PersistentPersistentPersistentPersistent Zustand bleibt im persistenten Speicher (DB) auch nach Container Terminierung erhalten

TransientTransientTransientTransient "stirbt" bei Container Terminisierung

Enterprise-Bean interface javax.ejb.EnterpriseBean

Entity Bean interface javax.ejb.EntityBean

Session Bean interface javax.ejb.SessionBean

Session Bean stateless

Session Bean statefull

Entity Bean Bean Managed Pesistence Entity Bean

Container Managed Pesistence

Message Bean

Message Driven Bean interface javax.ejb.MessageDrivenBean

Page 15: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 EJB Definition Seite 15 von total 218 Seiten

EJB Container

Home Interface

Remote Interface

EJB Implementation

Deployment Descriptor

Client

3.3 Elemente einer EJB Komponente

Die EJB besteht aus mindestens vier Komponenten:

3.3.1 Home Interface

- definiert Schnittstelle (Sichtbarkeit) was sieht der Client von dieser Komponente

Datei:Datei:Datei:Datei: ejb/HelloWorldHome.class

3.3.2 Remote Interface

- definiert Dienste (Business Methoden), die dem Client zur Verfügung stehen

Datei:Datei:Datei:Datei: ejb/HelloWorld.class

3.3.3 Bean Implementierung

- definiert und implementiert alle Methoden, die im Home- und Remote Interface deklariert sind

Datei:Datei:Datei:Datei: ejb/HelloWorldBean.class

3.3.4 Deployment Descriptor

- XML Datei zur Beschreibung der Komponente (Dateiangaben, Pfadangaben, Datenbankverbindungen und das Verhalten, z.B: Zugriffskontrolle, Transaktionsverhalten)

Datei: Datei: Datei: Datei: ejb-jar.xml

JJJJava ARARARARchive (Datei mit der Endung .jar)

Remote Interface Home Interface Bean Implementation Deployment Descriptor

ejb-jar.xml

HelloWorld.jar

ejb / HelloWorld.class

ejb / HelloWorldHome.class

ejb / HelloWorldBean.class

Page 16: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Hello EJB World Seite 16 von total 218 Seiten

4444 Hello EJB WorldHello EJB WorldHello EJB WorldHello EJB World

4.1 Voraussetzungen

- J2SDK: Java Software Development Kit

- J2EE: Java Application Server (<INSTALL_DIR>\lib\j2ee.jar als Library für die Entwicklungsumgebung)

- Entwicklingsumgebung: Eclipse, Java Editor Tool, etc

4.2 Aufgabe

Aufbau, Installieren und Betreiben einer J2EE Applikation

4.3 Organisation

/bin generierte Class Dateien

/deployment generierte WAR Dateien generierte JAR Dateien Bibliotheks-Klassen

/src/client Source Dateien der Client Applikation

/src/ejb Source Dateien der Middle Tier Applikation (EJBs, Servlets und HelperClasses)

4.4 Umgebungsvariablen

Benutzer- oder Systemvariablen definieren/ergänzen:

4.5 Ziel

Sun Java™ System Application Server Plattform

2. HelloWorld.jar 3. deployen

4. HelloWorldClient.class

1.1.1.1.

Page 17: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Hello EJB World Seite 17 von total 218 Seiten

4.6 Hello EJB World Java Source Dateien

- das Home InterfaceHome InterfaceHome InterfaceHome Interface HelloWorldHome.java - im Verzeichnis ...\ee0\src\ejb

package ejb; import java.rmi.RemoteException; import javax.ejb.CreateException; import javax.ejb.EJBHome; public interface HelloWorldHome extends EJBHome { HelloWorld create() throws RemoteException, CreateException; }

- das Remote InterfaceRemote InterfaceRemote InterfaceRemote Interface HelloWorld.java - im Verzeichnis ...\ee0\src\ejb

package ejb; import javax.ejb.EJBObject; import java.rmi.RemoteException; public interface HelloWorld extends EJBObject { public String sayHello() throws RemoteException; }

- die Enterprise BEAN KlasseEnterprise BEAN KlasseEnterprise BEAN KlasseEnterprise BEAN Klasse HelloWorldBean.java - im Verzeichnis ...\ee0\src\ejb

package ejb; import javax.ejb.SessionBean; import javax.ejb.SessionContext; public class HelloWorldBean implements SessionBean { public String sayHello() { return "Hello EJB World"; } public void ejbCreate() {} public void ejbRemove() {} public void ejbActivate() {} public void ejbPassivate() {} public void setSessionContext(SessionContext sc) {} }

Page 18: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Hello EJB World Seite 18 von total 218 Seiten

- die ClientClientClientClient Applikations-Klasse HelloWorldClient.java - im Verzeichnis ...\ee0\src\client

package client; import java.util.Properties; import javax.naming.Context; import javax.naming.InitialContext; import javax.rmi.PortableRemoteObject; import ejb.HelloWorld; import ejb.HelloWorldHome; /* VM Arguments: * * -Dorg.omg.CORBA.ORBInitalHost=$localshost * -Dorg.omg.CORBA.ORBInitalPort=$3700 */ /* System Properties: * * System.setProperty("org.omg.CORBA.ORBInitalHost","localhost"); * System.setProperty("org.omg.CORBA.ORBInitalPort","3700"); */ /* Environment Properties: * * Properties env = new Properties(); * env.put(Context.INITIAL_CONTEXT_FACTORY, * "com.sun.jndi.cosnaming.CNCtxFactory"); * env.put(Context.PROVIDER_URL, "iiop://localhost:3700"); */ public class HelloWorldClient { public static void main(String[] args) { try { Context initial = new InitialContext(); Object objref = initial.lookup("HelloWorldBean"); HelloWorldHome home = (HelloWorldHome) PortableRemoteObject.narrow( objref, HelloWorldHome.class); HelloWorld helloWorld = home.create(); System.out.println(helloWorld.sayHello()); } catch (Exception ex) { System.err.println("unexpected exception!"); ex.printStackTrace(); } } }

Page 19: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Hello EJB World Seite 19 von total 218 Seiten

4.7 "Hello EJB World" Bean mit Sun Java™ Deploytool deployen

Mit dem Sun™ Deploytool die notwendigen Deployment Descriptoren menügeführt erstellen und die EJB Komponenten im Sun AS™ deployen.

4.7.1 Applikations-Server starten / stoppen

- � Start > Sun Microsystems > Application Server PE > Start / [Stop] Default Server - Testen ob der Server läuft mit: http://localhost:8080

4.7.2 Deployment Applikation starten

- � Start > Sun Microsystems > Application Server PE > Deploytool

JAR Datei definieren ( Packaging the Application ):

- File > New > Application … - Application File Name …\ee0\deployment\HelloWorld.ear - Application Display Name HelloWorld

- File > New > Enterprise Bean … - JAR Name HelloWorldJar

- Edit Contents …

- Bean Klasse …\ee0\bin\ejb\HelloWorldBean.class

- Home Interface …\ee0\bin\ejb\HelloWorldHome.class

- Remote Interface …\ee0\bin\ejb\HelloWorld.class

- Enterprise Bean Class ejb/HelloWorldBean - Enterprise Bean Type Stateless Session - [Remote] Home Interface ejb/HelloWorldHome - [Remote] Remote Interface ejb/HelloWorld

J2EE Applikation "deployen":

- Tools > Deploy ... - Return Client JAR …\ee0\deployment

# Archive HelloWorld.ear META-INF\sun-j2ee-ri.project META-INF\application.xml META-INF\sun-application.xml META-INF\MANIFEST.MF ejb-jar-ic.jar ejb-jar-ic.jar\ejb\HelloWorld.class ejb-jar-ic.jar\ejb\HelloWorldHome.class ejb-jar-ic.jar\ejb\HelloWorldBean.class ejb-jar-ic.jar\META-INF\sun-j2ee-ri.project ejb-jar-ic.jar\META-INF\ejb-jar.xml ejb-jar-ic.jar\META-INF\sun-ejb-jar.xml ejb-jar-ic.jar\META-INF\MANIFEST.MF #

Page 20: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Hello EJB World Seite 20 von total 218 Seiten

4.8 Deployment

Das Deployment definiert das serverseitige Bereitstellen der J2EE Komponenten. Dazu werden neben den Javakomponenten die Deployment Descriptoren ejb-jar.xml (und weitere) erstellt und gemeinsam in einer EAR Datei dem Applikationsserver übergeben.

Alternativen zum Bereitstellen dieser Komponenten mittels Deploytool sind:

- manuelles Bereitstellen JAR Datei erstellen und dem Applikationsserver übergeben (Deployment Descriptoren müssen vorhanden und in Jar Datei verpackt sein!) copy HelloWorld.jar <J2EE_HOME> \domains\domain1\autodeploy

- ANT Script mit dem Skript Tool von Jacarta Ant™ ( http://ant.apache.org ) das Packen der Applikation und das Deployen der Komponenten durchführen: z.B: asant deploy asadmin deploy --user <user-name> --password <password> --host <hostname> --port <admin-port> HelloWorld.jar

4.9 Client Applikation ausführen

mit Eclipsemit Eclipsemit Eclipsemit Eclipse

Java Build Path (Eclipse) HelloWorldClient.jar enthält keine Stub Klassenenthält keine Stub Klassenenthält keine Stub Klassenenthält keine Stub Klassen

HelloWorldClient.jar enthält Stub Klassenenthält Stub Klassenenthält Stub Klassenenthält Stub Klassen

j2ee.jar ���� ����

appserv-rt.jar ����

generierte Client JAR Dateigenerierte Client JAR Dateigenerierte Client JAR Dateigenerierte Client JAR Datei HelloWorldClient.jar ����

- ohne Stub Klassen

Page 21: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Hello EJB World Seite 21 von total 218 Seiten

- Stubklassen generieren

HelloWorldClient.jarHelloWorldClient.jarHelloWorldClient.jarHelloWorldClient.jar

# Archive HelloWorldClient.jar ejb\_HelloWorld_Stub.class ejb\_HelloWorldHome_Stub.class ejb\HelloWorld.class ejb\HelloWorldBean.class ejb\HelloWorldHome.class META-INF\sun-j2ee-ri.project META-INF\MANIFEST.MF META-INF\application.xml META-INF\sun-application.xml ejb-jar-ic.jar ejb-jar-ic.jar\META-INF\ejb-jar.xml ejb-jar-ic.jar\META-INF\sun-ejb-jar.xml ejb-jar-ic.jar\META-INF\MANIFEST.MF #

Page 22: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Hello EJB World Seite 22 von total 218 Seiten

Konsole [cmd]:Konsole [cmd]:Konsole [cmd]:Konsole [cmd]:

Das folgende Batch Programm führt die "Hello EJB World" HelloWorldClient.class Applikation ohne Entwicklungsumgebung aus:

ohne Stub-Files und ohne Environment Properties:

- cd …\ee0\bin wechselt zum Projekt \bin Verzeichnis

- java –cp CLASSPATH Settings <J2EE_HOME>\lib\j2ee.jar; J2EE Library <J2EE_HOME>\lib\appserv-rt.jar; für RMI-IIOP . aktuelles Verzeichnis client.HelloWorldClient Client Applikation

mit Stub-Files und mit Environment Properties:

- cd …\ee0\bin wechselt zum Projekt \bin Verzeichnis

- java –cp CLASSPATH Settings <J2EE_HOME>\lib\j2ee.jar; J2EE Library <J2EE_HOME>\lib\appserv-rt.jar; für RMI-IIOP ..\deployment\HelloWorldClient.jar; generiertes ClientJargeneriertes ClientJargeneriertes ClientJargeneriertes ClientJar . aktuelles Verzeichnis client.HelloWorldClient Client Applikation

ApplicationClient (HelloWorldAppClient.jar) mit Deploytool erstellen und ausführen mit:

- appclient -client HelloWorldAppClient.jar im Verzeichnis wo sich das JAR befindet

HelloWorldAppClient.jar:

# Archive HelloWorldAppClient.jar client\HelloWorldClient.class ejb\HelloWorld.class ejb\HelloWorldHome.class META-INF\sun-j2ee-ri.project META-INF\application-client.xml META-INF\sun-application-client.xml META-INF\MANIFEST.MF #

Page 23: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Hello EJB World Seite 23 von total 218 Seiten

HelloWorldAppClient generieren:

Page 24: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Inside EJB Seite 24 von total 218 Seiten

Interfaces of:

java.ejb

package

Beans Provider's Classes

java.rmi.Remote

java.ejb.EJBObject

getEJBHome() getHandle() getPrimaryKey() isIdentical() remove()

javax.ejb.EJBHome

getEJBMetaData() getHomeHandle() remove()

javax.ejb.EnterpriseBean

javax.ejb. - SessionBean - EntityBean

Container generated Classes

<guard> EJBObject

<factory> EJBHome

<enterprise bean> HelloWorldBean

<context> real context object

javax.ejb. EntityContext getEJBObject() getEJBLocalObject() getPrimaryKey()

javax.ejb.EJBContext getEJBHome() getEJBLocalHome() getCallerPrincipal() isCallerinRole() setRollbackOnly() getRollbackOnly() getUserTransaction()

HelloWorld

business methods

HelloWorldHome

create() findByPrimaryKey() findx()

javax.ejb. SessionContext getEJBObject() getEJBLocalObject

javax.ejb.EJBMetaData

getEJBHome() getHomeInterfaceClass() getPrimaryKeyClass() getRemoteInterfaceClass() isSession() isStatelessSession()

5555 Inside EJBInside EJBInside EJBInside EJB

5.1 EJB Klassen Diagramm

rmi = Remote Method Invocation

Remote Interface Home Interface

Runtime ClassesRuntime ClassesRuntime ClassesRuntime Classes

Page 25: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Inside EJB Seite 25 von total 218 Seiten

java.rmi.Remote

javax.ejb.EJBHome

getEJBMetaData() getHomeHandle()

remove()

HelloWorldHome

create() findByPrimaryKey()

findXXX()

5.2 EJB Komponenten

5.2.1 HOME Interface

Das HOME Interface definiert die Methoden der BEAN Komponenten zum:

- Erstellen

- Finden

- Löschen

- Zugreifen auf META Informationen - (Remote Interface Class Name, etc.)

Die Implementierung erfolgt durch die Implementation der "FACTORY Design Pattern" :

FACTORY Design Pattern:FACTORY Design Pattern:FACTORY Design Pattern:FACTORY Design Pattern: Erzeugen einer neuen Instanz durch einen MethodenErzeugen einer neuen Instanz durch einen MethodenErzeugen einer neuen Instanz durch einen MethodenErzeugen einer neuen Instanz durch einen Methodenaufruf eines aufruf eines aufruf eines aufruf eines Factory Objektes anstelle der Verwendung des "neFactory Objektes anstelle der Verwendung des "neFactory Objektes anstelle der Verwendung des "neFactory Objektes anstelle der Verwendung des "new" w" w" w" Konstruktors.Konstruktors.Konstruktors.Konstruktors.

- Client, der das Bean erzeugt, hat keine direkte Referenz zur implementierten Klasse, sondern die Referenz eines Proxy Objektes (EJBObject)

- Der EJB Kontainer kann auch eine bereits bestehende Instanz einer EJB Komponente zurückgeben (pooling), anstatt eine neue Instanz zu bilden

- Das Erzeugen von Instanzen der EJB Komponenten ist vom EJB Container kontrolliert und nicht vom Client (Clients haben verschiedene Zugriffsrechte)

Klassendiagramm des EJB HOME InterfaceKlassendiagramm des EJB HOME InterfaceKlassendiagramm des EJB HOME InterfaceKlassendiagramm des EJB HOME Interface

beschreibt die Netzwerkfähigkeit eines Objektes

erzeugt eine Instanz von EJBMetaData erzeugt eine dauerhafte Instanz für einen späteren Zugriff entfernt (löscht) das Enterprise Java Bean

erzeugt ein EJB (mehrere create Methoden sind möglich) nur für ENTITY Beans mehrere finder Methoden sind möglich

Page 26: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Inside EJB Seite 26 von total 218 Seiten

5.2.2 REMOTE Interface

Das REMOTE Interface erlaubt dem Client den Zugriff auf:

- die Business Methoden

- das Home Interface (und dessen Methoden)

Implementierung erfolgt durch die Implementation der "GUARD Design Pattern"

GUARD DesignGUARD DesignGUARD DesignGUARD Design Pattern: Pattern: Pattern: Pattern: Alle Methodenaufrufe eines Client werden auf die entsprechenden Alle Methodenaufrufe eines Client werden auf die entsprechenden Alle Methodenaufrufe eines Client werden auf die entsprechenden Alle Methodenaufrufe eines Client werden auf die entsprechenden Zugriffsrechte überprüft.Zugriffsrechte überprüft.Zugriffsrechte überprüft.Zugriffsrechte überprüft.

Klassendiagramm des EJB REMOTE InterfaceKlassendiagramm des EJB REMOTE InterfaceKlassendiagramm des EJB REMOTE InterfaceKlassendiagramm des EJB REMOTE Interface

beschreibt die Netzwerkfähigkeit eines Objektes

erzeugt eine Referenz zur Instanz des HOME Interface robuste Referenz zur Netzwerkfähigkeit der Instanz löscht eine EJB Instanz gibt den PrimaryKey des EJB (throws RemoteException) vergleicht zwei REMOTE Interfaces

beschreibt den Geschäftsprozess (Business Methoden)

5.2.3 BEAN Implementation

Stellt die Funktionalität des Bean zur Verfügung, d.h. eine Java Klasse (das HOME- und REMOTE Interface sind "nur" Java Interfaces.)

- Business Methoden des REMOTE Interface

- Implementation der "Methoden des HOME Interface"

Kein Client und auch keine andere Bean kann direkt auf dieses Objekt zugreifen.

5.2.4 Deployment Descriptor

Der Deployment Descriptor ist eine XML (eXXXXtensible MMMMarkup LLLLanguage) Datei und beschreibt die Deploymenteigenschaften. Der Deployment Descriptor beeinflusst verschiedene Entwicklungslevel (Rollen).

java.rmi.Remote

javax.ejb.EJBObject

getEJBHome() getHandle() remove() getPrimaryKey() isIdentical()

HelloWorld Business Methods

Page 27: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Inside EJB Seite 27 von total 218 Seiten

Deployment DescrDeployment DescrDeployment DescrDeployment Descriptor Beschreibungskriterien (Ausschnitt):iptor Beschreibungskriterien (Ausschnitt):iptor Beschreibungskriterien (Ausschnitt):iptor Beschreibungskriterien (Ausschnitt):

- wie das Bean installiert werden muss

- das Deployment (Installieren / Bereitstellen)

- die EJB Implementation / das HOME Interface / das REMOTE Interface

- Verbindungen zu anderen Quellen (EJB, DB, ...)

- die Umgebung des Beans (damit ist das Bean nicht an eine bestimmte Umgebung gebunden, lediglich die Konfiguration muss angepasst werden für eine andere Umgebung)

- Transaktionsvariablen (Transactions Attributes)

- Sicherheitsvariablen (Access Control Lists)

5.2.5 Überblick der Elemente einer EJB-Komponente

Die folgende Tabelle stellt alle möglichen Elemente einer EJB-Komponente im Überblick dar und zeigt welche Elemente bei welchen EJB-Typen zur Anwendung kommen.

Session BeanSession BeanSession BeanSession Bean Entity BeanEntity BeanEntity BeanEntity Bean ElementElementElementElement

locallocallocallocal remoteremoteremoteremote llllocalocalocalocal remoteremoteremoteremote

MessageMessageMessageMessage Driven Driven Driven Driven BeanBeanBeanBean

Remote Home InterfaceRemote Home InterfaceRemote Home InterfaceRemote Home Interface ���� ���� Local Home InterfaceLocal Home InterfaceLocal Home InterfaceLocal Home Interface ���� ���� Remote InterfaceRemote InterfaceRemote InterfaceRemote Interface ���� ���� Local InterfaceLocal InterfaceLocal InterfaceLocal Interface ���� ���� Bean KlasseBean KlasseBean KlasseBean Klasse ���� ���� ���� Primary Key KlassePrimary Key KlassePrimary Key KlassePrimary Key Klasse ���� Deployment DescriptorDeployment DescriptorDeployment DescriptorDeployment Descriptor ���� ���� ����

5.2.6 EJB Rollen:

Durch die Trennung der verschiedenen Schichten ergibt sich neben der daraus resultierenden Robustheit noch die Möglichkeit des parallelen Entwicklungsprozesses. Dieser Aufgabenteilung sind die folgenden Rollen zugeordnet:

- Enterprise Bean Provider (beschreibt die verwendeten Ressourcen)

- Service Provider (Hersteller eines J2EE Servers, z.B. Sun, BEA, IBM, Borland, etc.)

- Container Provider (stellt die Laufzeitumgebung für EJBs zur Verfügung)

- Application Assembler (verbindet die EJBs und Datenquellen untereinander)

- Deployer (installiert die Applikation in den Kontainer)

- Systemadministrator (administriert Gesamtsystem, OS, J2EE-Server, etc.)

http://www.javaworld.com/javaworld/jw-07-1998/step/ejb-roles.gif

In der Praxis kann eine Person mehrere oder sogar alle Rollen übernehmen. Bei grösseren Projekten werden die Rollen jedoch häufig auf Teams aufgeteilt.

Page 28: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Inside EJB Seite 28 von total 218 Seiten

5.3 Zugriff auf ein EJB

Ein EJB erlaubt den Remote Zugriff nur über sein HOME Interface:

Der Client ermittelt zunächst per JNDI eine Referenz auf die Bean, welche unter dem Namen HelloWorldBean im Verzeichnisdienst (JNDI) registriert ist.

// Connection to JNDI Services InitialContext ic = new (InitialContext(Protokollparameter)); // Lookup Home Interface Object obj = ic.lookup("HelloWorldBean");

Die erhaltene generische Referenz wird durch Aufruf der statischen Methode narrow der Klasse PortableRemoteObject typsicher in eine Ausprägung der Home-Schnittstelle (HelloWorldHome)konvertiert.

// Typecasting due to RMI over IIOP HelloWorldHome home = (HelloWorldHome)PortableRemoteObject.narrow( obj,HelloWorldHome.class);

Der Aufruf der in dieser Schnittstelle durch den Anwender definierten create-Methode sorgt für die serverseitige Instanziierung der EJB, die als Ausprägung der Remote-Schnittstelle geliefert wird. Tatsächlich wird nicht das EJB-Objekt selbst durch den Methodenaufruf retourniert, sondern lediglich ein netzwerktransparenter Verweis darauf, der jedoch clientseitig einer lokalen Objektreferenz gleichgestellt verwendet werden kann.

Ferner wird serverseitig zur Kommunikation mit der EJB ein Home-Objekt erzeugt, welchem eine Stellvertreterrolle für den anfragenden Client zukommt. Der Aufruf der durch die EJB zur Verfügung gestellten Methode erfolgt identisch zu dem einer Lokalen.

// Create new Bean HelloWorld helloworld = home.create();

Die benötigten Business Methoden lassen sich nun über die erzeugte Objektinstanz aufrufen.

// Call Business Method(s) String result = helloworld.sayHello();

EJB EJB EJB EJB ---- Kontainer Kontainer Kontainer Kontainer

Remote Remote Interface Objekt

Home Home Interface Objekt

Enterprise Java Beans

ClientClientClientClient

objobjobjobj

objobjobjobj

objobjobjobj

1.1.1.1. Anfrage nach Referenz 2.2.2.2. Erzeuge

EJB-Object

5.5.5.5. Aufruf 4.4.4.4. Aufruf

3.3.3.3. Referenz auf EJB Object

Page 29: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Inside EJB Seite 29 von total 218 Seiten

5.3.1 Sequenz Diagramm

lookup

reference to EJBHome

create / find reference to EJBObject business methods

5.4 RMI (Remote Method Invocation)

Remote Method Invocation (RMI, deutsch etwa "Aufruf entfernter Methoden"), ist der Aufruf einer Methode eines entfernten Java-Objekts und realisiert die Java-eigene Art eines sog. RPC (Remote Procedure Call). "Entfernt" bedeutet dabei, dass sich das Objekt in einer anderen virtuellen Maschine befinden kann (die ihrerseits auf einem entfernten Rechner oder auf dem lokalen Rechner laufen kann). Dabei sieht der Aufruf für das aufrufende Objekt (bzw. dessen Programmierer) genauso aus, wie ein lokaler Aufruf, es müssen jedoch besondere Ausnahmen abgefangen werden, die zum Beispiel einen Verbindungsabbruch signalisieren können.

Auf der Client-Seite kümmert sich der sogenannte Stub – eine mit dem RMI-Compiler rmic erzeugte Klasse – um den Netzwerktransport. Der Stub muss entweder lokal oder über das Netz für den Client verfügbar sein.

Entfernte Objekte können zwar auch von einem bereits im Programm bekannten entfernten Objekt bereitgestellt werden, für die erste Verbindungsaufnahme werden aber die Adresse des Servers und ein Bezeichner (ein RMI-URL) benötigt. Für den Bezeichner liefert ein Namensdienst auf dem Server eine Referenz auf das entfernte Objekt zurück. Damit dies funktioniert, muss das entfernte Objekt im Server sich unter diesem Namen zuvor beim Namensdienst registriert haben. Der RMI-Namensdienst wird über statische Methoden der Klasse java.rmi.Naming angesprochen. Der Namensdienst ist als eigenständiges Programm implementiert und wird RMI Registry genannt.

KommunikationsprotokollKommunikationsprotokollKommunikationsprotokollKommunikationsprotokoll

RMI bezeichnet ausserdem ein Kommunikationsprotokoll, das für entfernte Aufrufe zwischen Java-Objekten verwendet wird, und eine Java-Standard-Klassenbibliothek, mit der diese Aufrufe realisiert werden können. Diese Klassenbibliothek ist Teil der Java 2 Standard Edition (J2SE). Alternativ kann auch IIOP als Kommunikationsprotokoll eingesetzt werden. Für RMI sind zwei Ports reserviert. Port 1099 ist für die RMI-Registry reserviert, also den Namensdienst. Port 1098 für den Activator reserviert.

Client JNDI Service EJBHome EJBObject

Page 30: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Inside EJB Seite 30 von total 218 Seiten

Client

Stub

Remote Reference

Layer

Server

Skeleton

Remote Reference

Layer

Netzwerkverbindung

5.4.1 RMI Kommunikationsmodell

virtuelle Kommunikation

reelle Kommunikation

AblaufAblaufAblaufAblauf

1. Der Server registriert ein Remote Object bei der RMI-Registry unter einem eindeutigen Namen.

2. Der Client schaut bei der RMI-Registry unter diesem Namen nach und bekommt eine Objektreferenz, die seinem Remote Interface entsprechen muss.

3. Der Client ruft eine Methode aus der Objektreferenz auf (dass diese Methode existiert, wird durch das Remote Interface garantiert).

4. Der Server gibt dem Client die Rückgabewerte dieses Aufrufes, oder der Client bekommt eine Fehlermeldung (z. B. bei einem Verbindungsabbruch).

ActivationActivationActivationActivation

Als Ergänzung von RMI steht die sogenannte Activation ("Aktivierung") zur Verfügung. Ähnlich der RMI-Registry ist auch dies eine zentrale Anlaufstelle für RMI-Clients. Jedoch kann der Activator auch RMI-Server-Objekte erzeugen und neue Virtuelle Maschinen starten.

AnwendungAnwendungAnwendungAnwendung

Bei der Kommunikation mit RMI hat der Client den Eindruck, Methoden von Objekten aufzurufen, die auf dem Server liegen. Folgende Kriterien sind Bestandteile von RMI:

- Nahtlose Unterstützung entfernter Aufrufe von Objekten in verschiedenen VM - Callback-Unterstützung von Server zu Applet

- Integrierung des verteilten Objekt-Modells in Java unter Beibehaltung der Java-Semantik

- Unterschiede zwischen dem verteilten Objekt Modell und dem lokalen Java Objekt Modell sollen transparent gemacht werden

- Schreiben zuverlässiger Anwendungen so einfach wie möglich machen

- Bewahrung der Sicherheitsaspekte der JRE

Jeder Client benötigt zur Benutzung von Serverobjekten, die auf dem Server existieren, eine Beschreibung über die Fähigkeiten eines entfernten Objektes. Deshalb implementiert jedes Interface für entfernte Objekte, direkt oder indirekt, das Interface java.rmi.remote, damit wird das Objekt als ein "Remote-Objekt" gekennzeichnet. In diesem Interface sind keine Methoden definiert. Klassen, die das Interface implementieren, erlauben Clients deren Methoden entfernt (remote) aufzurufen.

Page 31: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Inside EJB Seite 31 von total 218 Seiten

Der Client erhält dann vom Broker-Tool (RMI-Registry) lediglich ein Stub-Objekt, das Remote-Objekt bleibt auf dem Server. Ein Stub ist eine Klasse, die das Remote-Interface implementiert und daher für den Client als Platzhalter für den Zugriff auf das Remote-Objekt dient.

Suche Registrierung Remote

Objekte

virtueller Aufruf

Der Stub kommuniziert über eine TCP-Verbindung mit dem als Skeleton bezeichneten Gegenstück auf der Server-Seite. Das Skeleton kennt das tatsächliche Applikationsobjekt, leitet die Anfragen des Stubs an dieses weiter und gibt den Rückgabewert an ihn zurück. Stub und Skeleton werden während der Entwicklung mit Hilfe eines Tools generiert und verbergen die komplizierten Details der Kommunikation zwischen Server und Client.

RMI verfolgt mit der Verteilung von Objekten im Netz einen ähnlichen Ansatz wie CORBA (Common Object Request Broker Architecture, siehe beispielsweise http://www.omg.org).

5.5 EJB Kommunikationsmodelle

An Prozesse beteiligte EJBs kommunizieren:

- synchron, entfernt

- synchron, lokal

- asynchron, nachrichtenbasiert

RMI - Registry

Server

Client

Page 32: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Inside EJB Seite 32 von total 218 Seiten

5.5.1 synchrone, entfernte Kommunikation

Aufrufe erfolgen in diesem Model als synchrone Methodenaufrufe mittels RMI-IIOP in einem verteilten System. Die Übertragung der Daten erfolgt mittels "by-Value" Semantik, also als Kopie der Originaldaten. Änderungen der Daten wirken sich somit nur auf die Originaldaten und nicht auf die Kopie aus.

Ablauf:Ablauf:Ablauf:Ablauf:

1. EJB-Container erzeugt EJBHomeObject

2. EJB-Container registriert Home-Object beim Namensdienst

3. Client fordert vom Namensdienst Referenz auf Home-Object

4. Namensdienst liefert Referenz auf das Home-Object

5. Client fordert über das Home Interface ein EJB von Home-Object an

6. EJBHome-Object erzeugt EJBObject

7. Home-Object liefert Referenz auf EJBObject

8. Client ruft über das Remote Interface die Geschäftsmethoden der EJB auf

9. EJBObject delegiert Methodenaufruf an die EJB-Instanz

Page 33: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Inside EJB Seite 33 von total 218 Seiten

5.5.2 synchrone, lokale Kommunikation

Aufrufe von Diensten einer EJB-Komponente erfolgen durch synchrone Methodenaufrufe. Die Übertragung der Daten erfolgt mittels "by-Referenz" Semantik. Bei der Verwendung dieses Kommunikations-Modells werden somit keine Kopien von Parametern an die empfangende Komponente übergeben, sondern Adresszeiger auf die Originaldaten im Speicher. Ändern sich die übergebenen Daten, so werden die Originaldaten überschrieben:

Ablauf:Ablauf:Ablauf:Ablauf:

1. EJB-Container erzeugt EJBHomeObject

2. EJB-Container registriert Home-Object beim Namensdienst

3. Client fordert vom Namensdienst Referenz auf Home-Object

4. Namensdienst liefert Referenz auf das Home-Object

5. Client fordert über das Local Home Interface ein EJB von Home-Object an

6. EJBLocalHome-Object erzeugt EJBLocalObject

7. LocalHome-Object liefert Referenz auf EJBObject

8. Client ruft über das Local Remote Interface die Geschäftsmethoden der EJB auf

9. EJBLocalObject delegiert Methodenaufruf an die EJB-Instanz

Page 34: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Inside EJB Seite 34 von total 218 Seiten

5.5.3 asynchron, nachrichtenbasierte Kommunikation

Dient als Schnittstelle zwischen objektorientierten und nicht-objektorientierten Prozessen in verteilten Systemen.

Ablauf:Ablauf:Ablauf:Ablauf:

1. Aplikationsserver registriert Nachrichtenempfänger beim Namensdienst

2. EJB-Container registriert sich als Listener für Nachrichten

3. Client fordert vom Namensdienst Referenz des Nachrichtenempfängers

4. Namensdienst liefert Referenz auf Nachrichtenempfänger

5. Client sendet Nachrichten an Nachrichtenempfänger

6. Nachrichtenempfänger übermittelt Listener eingegangene Nachricht

7. Listener delegiert Nachricht an BeanInstanz

5.5.4 Überblick über die Kommunikationsmodelle

Die folgende Tabelle weist die Aufrufmodelle den verschiedenen EJB-Typen zu:

AufrufmodellAufrufmodellAufrufmodellAufrufmodell

EJB TypenEJB TypenEJB TypenEJB Typen synchronsynchronsynchronsynchron entferntentferntentferntentfernt

synchronsynchronsynchronsynchron lokallokallokallokal

asynchronyasynchronyasynchronyasynchrony nachrichtenbasiertnachrichtenbasiertnachrichtenbasiertnachrichtenbasiert

Stateless Session BeanStateless Session BeanStateless Session BeanStateless Session Bean ���� ���� Statefull Session BeanStatefull Session BeanStatefull Session BeanStatefull Session Bean ���� ���� Entity BeanEntity BeanEntity BeanEntity Bean ���� ���� Message Driven BeanMessage Driven BeanMessage Driven BeanMessage Driven Bean ����

Page 35: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Stateless Session Bean ( zustandslos) Seite 35 von total 218 Seiten

6666 Stateless Session Bean ( zustStateless Session Bean ( zustStateless Session Bean ( zustStateless Session Bean ( zustandslos)andslos)andslos)andslos)

modelliert einfacher Geschäftsprozess (z.B. Zinsberechnung)

kann keine Daten speichern

haben keine Identität

Aufgabe muss mit einem Methodenaufruf erledigt sein, zweimaliger Aufruf des Beans garantiert nicht dieselbe Instanz auf dem Server

eine create() Methode, parameterlos

nutzt nicht alle Methoden

pooling:

- mehrere Clients rufen dasselbe Bean auf

- gemeinsame Nutzung von Sourcen

- weniger Objekte im Einsatz

- ABER: Bean ist single-threaded, ein Bean kann nur ein Client behandeln

6.1 Bean Life Cycle

Container initiated:Container initiated:Container initiated:Container initiated: Container initiated:Container initiated:Container initiated:Container initiated:

ejbRemove() Class.newInstance() setSessionContext(sc) ejbCreate()

Client initiated:Client initiated:Client initiated:Client initiated: business methods

setSessionContextsetSessionContextsetSessionContextsetSessionContext

Wird unmittelbar nach der Instanzierung der Bean durch den Container aufgerufen um der Bean ihren SessionContext mitzuteilen. Das übergebene Objekt vom Typ SessionContext definiert die Umgebung der Bean-Instanz. Darüber erhält die Bean z.B. Informationen über den aufrufenden Client (Sicherheitsaspekte).

ejbCreateejbCreateejbCreateejbCreate Wird nach der Methode setSessionContext durch den Container aufgerufen, um die Bean zu initialisieren, z.B. Verbindungen zu anderen Objekten und Datenbanken.

ejbRemoveejbRemoveejbRemoveejbRemove

Wird durch den Container aufgerufen, nachdem der Client die Methode remove des Remote Objektes aufgerufen hat. In dieser Methode sollten die für die Bean reservierten Ressourcen wieder freigegeben werden. Danach löscht der Container die Bean-Instanz.

java.io.Serializable

javax.ejb.SessionBean

ejbActivate()

ejbPassivate() ejbRemove() setSessionContext()

mySessionBean

ejbCreate() business methods

javax.ejb.EnterpriseBean

Methode-Ready-Pool

does not exist

Page 36: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Stateless Session Bean ( zustandslos) Seite 36 von total 218 Seiten

6.2 Übung ee1 : Zinsberechnung

Erstellen und deployen Sie ein Stateless Session Bean, das als Businessmethode die Zinsberechnung eines Geldbetrages amount über eine definierte Laufzeit years zu einem gegebenen Zinssatz rate mehreren Klienten zur Verfügung stellt. Die Attribute amount und years müssen clientspezifisch definiert werden. Der Zinssatz rate kann als ein Attribut der EJB oder clientspezifisch definiert werden.

Ansatz:Ansatz:Ansatz:Ansatz:

Entwicklung einer Geldanlage durch Zins und Zinseszins:

Page 37: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Stateful Session Bean ( zustandsbehaftet ) Seite 37 von total 218 Seiten

does not exist

Methode-Ready-Pool

Passive

7777 Stateful Session Bean ( zustandsbehaftet )Stateful Session Bean ( zustandsbehaftet )Stateful Session Bean ( zustandsbehaftet )Stateful Session Bean ( zustandsbehaftet )

modelliert Geschäftsprozess (z.B. Shopping Cart)

kann Daten speichern

Zustandsbehaftet (kann den Zustand eines best. Client speichern)

mehrmaliger Aufruf des Beans für einen Geschäftsablauf möglich

mehrere create() Methoden (mit unterschiedlichen Signaturen)

kein pooling

passivated:

- wenig Ressourcen und Memory vorhanden - bessere Performance

7.1 Bean Life Cycle

Container initiated:Container initiated:Container initiated:Container initiated: Container initiated:Container initiated:Container initiated:Container initiated: Class.newInstance() ejbRemove() timeout setSessionContext(sc) ejbCreate() Client initiated:Client initiated:Client initiated:Client initiated: Client initiated:Client initiated:Client initiated:Client initiated:

remove() create()

Client initiated:Client initiated:Client initiated:Client initiated: Container initiated:Container initiated:Container initiated:Container initiated:

business methods ejbActivate() ejbPassivate()

ejbPassivateejbPassivateejbPassivateejbPassivate

Wird vom Container aufgerufen, bevor die Bean zeitweilig aus dem Speicher entfernt wird. Die Bean kann die von ihr in Anspruch genommenen Ressourcen freigeben. Die Bean bleibt aber weiterhin dem Client zugeordnet. Für den Client ist der Aufruf dieser Methode transparent.

ejbActivateejbActivateejbActivateejbActivate

Wird vom Container aufgerufen, nachdem der Client eine Methode des Remote-Interface aufgerufen hat. Der Container holt die passivierte Instanz der Bean in den Arbeitsspeicher zurück und ruft danach die Methode ejbActivate auf, um Zustand der Bean erneut zu initialisieren.

ejbRemoveejbRemoveejbRemoveejbRemove

Wird durch den Container aufgerufen, nachdem der Client die Methode remove des Remote Objektes aufgerufen hat. In dieser Methode sollten die für die Bean reservierten Ressourcen wieder freigegeben werden. Danach löscht der Container die Bean-Instanz.

javax.ejb.SessionBean

ejbActivate() ejbPassivate() ejbRemove() setSessionContext()

mySessionBean

ejbCreate() business methods

javax.ejb.EnterpriseBean

java.io.Serializable

Page 38: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Stateful Session Bean ( zustandsbehaftet ) Seite 38 von total 218 Seiten

7.2 Übung ee2 : Kontoführung

Erstellen und deployen Sie ein Stateful Session Bean zur Kontoführung. Benützen Sie dazu die Variable private float accountBalance:

- Betrag deponieren (als Float)

- Betrag abheben (als Float)

- Saldo ausgeben (auf Konsole)

7.2.1 Konsolen Statements

Ergänzen Sie die Bean Methoden mit Konsolen Statements zur Überwachung der Aktivitäten des Applikations-Servers.

7.2.2 Environment Entries als InitialContext

Erweitern Sie die Business Logik und führen Sie auf allen Konten einen Zinssatz. Dabei ist es sinnvoll für alle Konten denselben Zinssatz zu definieren. Benützen Sie dazu die Variable private float rate:

- Zins (im Deployment Descriptor) als Environment Entry festlegen

- Suchen Sie nachdem das Bean deployed ist den entsprechenden Eintrag im DD und ändern Sie diesen ohne das Bean neu zu deployen.

Ansatz / Fragmente:Ansatz / Fragmente:Ansatz / Fragmente:Ansatz / Fragmente:

public void setSessionContext(SessionContext sc) { try { InitialContext ic = new InitialContext(); Context local = (Context) ic.lookup("java:comp/env"); Float interestrate = (Float) local.lookup("Zins"); rate = interestrate.floatValue(); System.out.println("TellerBean context set!"); System.out.println("NEW RATE SET TO: " + rate); } catch (javax.naming.NamingException e) { e.printStackTrace(); } System.out.println("TellerBean context set!"); }

Setzen des Environment Entry für "Zins" im Deploymenttool:

Generierter Eintrag im DD ( ejbGenerierter Eintrag im DD ( ejbGenerierter Eintrag im DD ( ejbGenerierter Eintrag im DD ( ejb----jar.xml )jar.xml )jar.xml )jar.xml )

<env-entry> <env-entry-name>Zins</env-entry-name> <env-entry-type>java.lang.Float</env-entry-type> <env-entry-value>1.0</env-entry-value> </env-entry>

Page 39: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Entity Bean ( für die Abbildung von Daten einer DB ) Seite 39 von total 218 Seiten

does not exist

Pooled

Ready

8888 Entity Bean ( für die Abbildung von Daten einer DB )Entity Bean ( für die Abbildung von Daten einer DB )Entity Bean ( für die Abbildung von Daten einer DB )Entity Bean ( für die Abbildung von Daten einer DB )

modelliert Abbildungen von persistenten Geschäftsdaten (DB) mehrere Clients können auf diese Entities zugreifen verwendet identifizierbare Daten (primary key) CMPCMPCMPCMP - Container Managed Persistence:

- Container speichert Bean in DB

- Bean-Provider muss sich nicht kümmern

- exakter Mechanismus ist nicht definiert !

- jedes Objekt hat einen Primary Key BMPBMPBMPBMP - Bean Managed Persistence:

- Bean-Provider ist verantwortlich, dass die Daten in der DB gespeichert werden

- Realisation mittels SQL, ...

- höherer Aufwand als CMP

- mehr Flexibilität als CMP

8.1 Bean Life Cycle

ContainerContainerContainerContainer initiated: initiated: initiated: initiated: Container initiated:Container initiated:Container initiated:Container initiated: unsetEntityContext() Class.newInstance() Object.finalize() setEntityContext()

Container initiated:Container initiated:Container initiated:Container initiated: Container initiated:Container initiated:Container initiated:Container initiated: ejbPassivate() ejbActivate() ejbRemove() ejbCreate(),ejbPostCreate() Client initiated: Client initiated: remove() create() Container initiated:Container initiated:Container initiated:Container initiated: Client initiated:Client initiated:Client initiated:Client initiated: ejbLoad(), ejbStore() getter / setter

PooledPooledPooledPooled Die Instanz existiert, aber sie besitzt keine Indentität. Wenn der Client eine find- oder create-Methode des Home Interface aufruft, wird einer Bean Instanz aus dem Pool vom Kontainer eine Identität (Primärschlüssel) zugewiesen.

ReadyReadyReadyReady Die Instanz existiert, besitzt eine Identität und kann vom Client benutzt werden.

java.io.Serializable

javax.ejb.EntityBean

ejbActivate() ejbPassivate() setEntityContext() unsetEntityContext() ejbLoad() ejbStore()

myEntityBean

ejbCreate() ejbPostCreate() ejbFindXXX() business methods

javax.ejb.EnterpriseBean

Page 40: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Entity Bean ( für die Abbildung von Daten einer DB ) Seite 40 von total 218 Seiten

8.1.1 EJB-Container Life-Cycle- Methoden

Life Cycle MethodeLife Cycle MethodeLife Cycle MethodeLife Cycle Methode BeschreibungBeschreibungBeschreibungBeschreibung

setEntityContext() unsetEntityContext() wird aufgerufen nach erstellen / vor entfernen der Entity Bean

ejbLoad() ejbStore() ladet / speichert die Entity Bean

ejbRemove() entfernt die Entity Bean

ejbActivate() ejbPassivate() aktiviert / passiviert die Entity Bean

8.1.2 Persistenzoperationen einer Entity Bean

Operation:

ejbCreate

SQL Alias:

INSERT

Wird nach dem Erzeugen eines Java-Objektes (EJB) aufgerufen um dieses in der Datenbank abzulegen.

Diese Operation ist nicht Bestandteil der Schnittstelle, da ihre Parameter, die den Übergabeparametern des Objektkonstruktors entsprechen, zum Schnittstellenerzeugungszeitpunkt nicht feststehen.

Operation:

ejbFindByPrimaryKey

SQL Alias:

SELECT

Liefert den Wert des Primärschlüssels zurück, sofern ein Datenbankeintrag existiert, der durch diesen Primärschlüssel identifiziert wird.

Diese Operation ist nicht Bestandteil der Schnittstelle, da ihre Parameter, die in Typ, Name und Reihenfolge der Zusammensetzung des Primärschlüssels entsprechen, zum Schnittstellenerzeugungszeitpunkt nicht feststehen.

Diese Methode wird nicht durch den Anwender direkt aufgerufen, sondern (stattdessen auf einer Ausprägung der Home-Schnittstelle) das zur Verfügung stehende Analog findByPrimaryKey, welches das durch den Primärschlüssel identifizierte EJB-Objekt zurückliefert.

Diese Methode greift intern auf ausschliesslich den Schlüssel liefernde Methode der Bean zu.

Operation:

ejbRemove

SQL Alias:

DELETE

Entfernt das EJB-Objekt aus der Datenbank.

Operation:

ejbStore

SQL Alias:

UPDATE

Synchronisiert das Java-Objekt mit dem EJB-Objekt und aktualisiert so die Datenbankinhalte.

Diese Methode wird nach jedem Zugriff mittels einer in der Remote-Schnittstelle aufgeführten Operation auf das EJB-Objekt ausgeführt.

Page 41: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Entity Bean ( für die Abbildung von Daten einer DB ) Seite 41 von total 218 Seiten

DB: EnterpriseEducation PERSONBEAN

ID FNAME NAME

SUN ™ Applikationsserver CMP (1.x) Entity Bean

public id public name public fname

8.2 Modellieren von persistenten Geschäftsdaten

8.2.1 Übung ee3 : Personenverwaltung mit CMP 1.0

HOME Interface einer Entity BeanHOME Interface einer Entity BeanHOME Interface einer Entity BeanHOME Interface einer Entity Bean

- Deklariert die Bean-Lifecycle-Methoden

- Erweitert javax.ejb.EJBHome (das wiederum java.rmi.Remote erweitert)

- Klasse, die dieses Interface implementiert (EJB Home) wird automatisch generiert

public interface PersonHome extends EJBHome {

// create und finder Methoden deklarieren public Person create(String id, String name, String fname) throws CreateException, RemoteException;

// entsprechender Return Type festlegen ( [0..1] -> Person ) public Person findByPrimaryKey(String key) throws FinderException, RemoteException;

// entsprechender Return Type festlegen ([0..*] -> Collection ) public Collection findAll() throws FinderException, RemoteException; }

REMOTE Interface einer Entity BeanREMOTE Interface einer Entity BeanREMOTE Interface einer Entity BeanREMOTE Interface einer Entity Bean

- Deklariert die Bean-Business-Methoden

- Erweitert javax.ejb.EJBObject (das wiederum java.rmi.Remote erweitert)

- Klasse, die dieses Interface implementiert (EJB Object) wird automatisch generiert

- Wrapper des eigentlichen Beans

public interface Person extends EJBObject { // public setter und getter Methoden der Entitäten deklarieren public void setId(String id) throws RemoteException; public void setName(String name) throws RemoteException; public void setFname(String fname) throws RemoteException; public String getName() throws RemoteException; public String getFname() throws RemoteException; public String getId() throws RemoteException; }

Page 42: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Entity Bean ( für die Abbildung von Daten einer DB ) Seite 42 von total 218 Seiten

BEAN Implementation einer Entity BeanBEAN Implementation einer Entity BeanBEAN Implementation einer Entity BeanBEAN Implementation einer Entity Bean

- Implementiert alle Methoden, die für den Lebenszyklus benötigt werden

- Signatur muss identisch sein mit der des Remote & Home Interfaces

- Implementiert javax.ejb.EntityBean ( das wiederum javax.ejb.EnterpriseBean erweitert)

public class PersonBean implements EntityBean {

// DB Felder als public Attribute definieren public String id = ""; public String name = ""; public String fname = "";

// public setter und getter Methoden der Entitäten definieren public String getId() {return id;} public void setId(String id) {this.id = id;} ...

// Für jede create() Methode des Home Interfaces muss es eine // entsprechende ejbCreate() Methode mit derselben Signatur geben public String ejbCreate(String id, String name, String fname) { // Belegen der Bean Attribute mit den Übergabeparameter this.id = id; this.name = name; this.fname = fname; // Rückgabewertes ist Primary_Key Attribute return id; }

// Für jede create() Methode des Home Interfaces muss es eine // entsprechende ejbPostCreate() Methode mit derselben Signatur // geben public void ejbPostCreate(String id, String name, String fname) { }

// sämtliche Kontainer Life Cycle Methoden müssen definiert werden public void setEntityContext(EntityContext arg0) throws EJBException, RemoteException { }

public void unsetEntityContext() throws EJBException, RemoteException { }

... }

DeploymentDeploymentDeploymentDeployment

Die Persistenz-Einstellungen im Deploytool sind im Entity TAB untergebracht:

- Persistente Felder bestimmen

- Primary Key Class Feld bestimmen

- CMP Database definieren

Page 43: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Entity Bean ( für die Abbildung von Daten einer DB ) Seite 43 von total 218 Seiten

mySQL Datasource anbinden mit:

- Connection Pool (im Sun AS™ definieren)

- JDBC Datasource (im Sun AS™ über JNDI definiert)

- CMP Database Mapping (in Deployment Tool)

Mit der admin Konsole des Sun AS™ ( http://localhost:4848 ) eine neue JDBC Resource und ein entsprechender Connection Pool erstellen:

Die notwendige MySQLDriver.class ist vom entsprechenden DataSource-Vendor zu beziehen und dem Sun AS™ zur Verfügung zu stellen:

Page 44: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Entity Bean ( für die Abbildung von Daten einer DB ) Seite 44 von total 218 Seiten

CMP Database Mapping per JNDI "jdbc/ee" (entsprechend Sun AS™ JDBC Ressource):

Das Deploymenttool erstellt dann die entsprechenden xml Dateien wie auch ein Database-Schema (Person_ejb-jar-ic.dbschema ) für das Erstellen der entsprechenden Tabelle:

Deployment Descriptor ejbDeployment Descriptor ejbDeployment Descriptor ejbDeployment Descriptor ejb----jar.xml (Ausschnitt)jar.xml (Ausschnitt)jar.xml (Ausschnitt)jar.xml (Ausschnitt)

<enterprise-beans> <entity> <ejb-name>PersonBean</ejb-name> <home>ejb.PersonHome</home> <remote>ejb.Person</remote> <ejb-class>ejb.PersonBean</ejb-class> <persistence-type>Container</persistence-type> <prim-key-class>java.lang.String</prim-key-class> <reentrant>false</reentrant> <cmp-version>1.x</cmp-version> <cmp-field><field-name>fname</field-name></cmp-field> <cmp-field><field-name>name</field-name> </cmp-field> <cmp-field><field-name>id</field-name></cmp-field> <primkey-field>id</primkey-field> </entity>

Deployment Descriptor sunDeployment Descriptor sunDeployment Descriptor sunDeployment Descriptor sun----cmpcmpcmpcmp----mappings.xml (Ausschnitt)mappings.xml (Ausschnitt)mappings.xml (Ausschnitt)mappings.xml (Ausschnitt)

<sun-cmp-mappings> <sun-cmp-mapping> <schema>Person_ejb-jar-ic</schema> <entity-mapping> <ejb-name>PersonBean</ejb-name> <table-name>PERSONBEAN</table-name> <cmp-field-mapping> <field-name>fname</field-name> <column-name>PERSONBEAN.FNAME</column-name> </cmp-field-mapping> <cmp-field-mapping> <field-name>id</field-name> <column-name>PERSONBEAN.ID</column-name> </cmp-field-mapping> <cmp-field-mapping> <field-name>name</field-name> <column-name>PERSONBEAN.NAME</column-name> </cmp-field-mapping> </entity-mapping> </sun-cmp-mapping> </sun-cmp-mappings>

Page 45: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Entity Bean ( für die Abbildung von Daten einer DB ) Seite 45 von total 218 Seiten

8.2.2 CMP/CMR in EJB 2.0

Enterprise JavaBeans (EJB) 2.0 erweitern die frühere Version 1.x mit folgenden Eigenschaften:

- erweiterte Funktionalität für Container-Managed Persistence für Entity Beans

- unterstützt CMR (Container-Managed Relationships)

- definiert EJB-Query Language (EJB-QL) für select und find Query Methoden

- unterstützt zusätzlich Locale Remote and Locale Home Interfaces um den Zugriff zwischen Beans im gleichen Container zu ermöglichen

Die Funktionsweise und die wesentlichen Unterschiede zu CMP 1.0 sind an einer trivialen EJB Kundenverwaltung erläutert. Ein Kunde besteht aus einem Namen und einer Adresse. Dafür werden zwei Entitäten geführt, realisiert durch zwei Entity Beans (CMP 2.0). Die Relation dieser beiden Entitäten wird in EJB's definiert.

8.2.3 Übung ee31 : Triviale Kundenverwaltung mit Entity Bean (CMP 2.0)

Das Besipiel definiert zwei CMP Entity Beans, die zwei Tabellen "Name" (Name, Vorname) und "Adresse" (Strasse, Ort) persistiert. Die 1:1 Relation zwischen den beiden Entitäten wird durch den EJB Kontainer realisiert:

Local HomeLocal HomeLocal HomeLocal Home----Interface der Address Bean Interface der Address Bean Interface der Address Bean Interface der Address Bean (Entity Bean)(Entity Bean)(Entity Bean)(Entity Bean)

Es werden im Gegensatz zum Remote-Interface keine java.rmi.RemoteException geschmissen.

public interface AddressLocalHome extends EJBLocalHome {

public AddressLocal create(String street, String location) throws CreateException;

// Methode findByPrimaryKey(...) muss deklariert werden public AddressLocal findByPrimaryKey(String id) throws FinderException; // optionale finder-Methoden können folgen }

DB: EnterpriseEducation NAMEBEAN

ID NAME FNAME

ADDRESSBEAN

ID STREET LOCATION

Applikationsserver CMP (2.x) EntityBean:Name

get / set id get / set name get / set fname get / set address

1 : 1

CMP (2.x) EntityBean:Address Relation

get / set id get / set street get / set location

Page 46: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Entity Bean ( für die Abbildung von Daten einer DB ) Seite 46 von total 218 Seiten

LocalLocalLocalLocal----Interface zur Definition der Geschäftsmethoden der Address Bean (Entity Interface zur Definition der Geschäftsmethoden der Address Bean (Entity Interface zur Definition der Geschäftsmethoden der Address Bean (Entity Interface zur Definition der Geschäftsmethoden der Address Bean (Entity Bean).Bean).Bean).Bean).

Die Geschäftsmethoden umfassen nur getter/setter-Methoden für die Attribute der Entity Bean. Die getter/setter-Methoden schmeissen im Gegensatz zum Remote-Interface keine RemoteException.

public interface AddressLocal extends EJBLocalObject { public String getStreet(); public String getLocation(); }

BeanBeanBeanBean----Klasse der Entity Bean (mit CMP 2.0) Address.Klasse der Entity Bean (mit CMP 2.0) Address.Klasse der Entity Bean (mit CMP 2.0) Address.Klasse der Entity Bean (mit CMP 2.0) Address.

Es werden alle im Local-Interface (AddressLocal.java) definierten Geschäftsmethoden und auch bestimmte callback-Methoden implementiert. Wesentliche Unterschiede zu CMP 1.0: - Attribute einer Addresse sind nicht mehr als Felder in der Java-Klasse deklariert - getter/setter-Methoden als abstrakte Methoden deklariert (werden vom Container implementiert) - die Bean-Klasse ist folglich auch abstrakt

public abstract class AddressBean implements EntityBean {

private EntityContext context;

// abstrakte getter/setter-Methoden - PERSISTENTE FELDER public abstract String getId(); public abstract void setId(String id);

public abstract String getStreet(); public abstract void setStreet(String street);

public abstract String getLocation(); public abstract void setLocation(String location);

// Callback-Methoden (werden bei Bedarf vom Container aufgerufen) // Diese Methoden sind grösstenteils leer implementiert, da // Container-Managed Persistence verwendet wird // ejbCreate(...) legt eine neue Adresse an // Diese Methode wird vom Container automatisch aufgerufen, sobald // create(.) auf dem Home-Object aufgerufen wird. // Die Signature von create(...) und ejbCreate(...) muss übereinstimmen // @return null public String ejbCreate(String street, String location) throws CreateException { System.out.println("AddressEJB: ejbCreate called"); setId(street + location); setStreet(street); setLocation(location); return null; } // Lifecycle Methoden und Default Kunstruktor public void ejbPostCreate(String street, String location) { System.out.println("AddressEJB: ejbPostCreate called"); } public void ejbRemove() { System.out.println("AddressEJB: ejbRemove called"); } ...

public AddressBean() { } }

Page 47: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Entity Bean ( für die Abbildung von Daten einer DB ) Seite 47 von total 218 Seiten

Local HomeLocal HomeLocal HomeLocal Home----Interface der Name Bean (Entity Bean)Interface der Name Bean (Entity Bean)Interface der Name Bean (Entity Bean)Interface der Name Bean (Entity Bean)

Es werden im Gegensatz zum Remote-Interface keine java.rmi.RemoteException geschmissen.

public interface NameLocalHome extends EJBLocalHome {

public NameLocal create(String id, String street, String location) throws CreateException;

// Methode findByPrimaryKey(...) muss deklariert werden public NameLocal findByPrimaryKey(String id) throws FinderException; // optionale finder-Methoden können folgen }

LocalLocalLocalLocal----Interface zur Definition der Geschäftsmethoden der Name Bean (Entity Bean).Interface zur Definition der Geschäftsmethoden der Name Bean (Entity Bean).Interface zur Definition der Geschäftsmethoden der Name Bean (Entity Bean).Interface zur Definition der Geschäftsmethoden der Name Bean (Entity Bean).

Die Geschäftsmethoden umfassen nur getter/setter-Methoden für die Attribute der Entity Bean. Die getter/setter-Methoden schmeissen im Gegensatz zum Remote-Interface keine RemoteException.

public interface NameLocal extends EJBLocalObject {

public AddressLocal getAddress(); public void setAddress(AddressLocal address); }

(Remote) Home Interface der Name Bean (ermöglicht einen Client(Remote) Home Interface der Name Bean (ermöglicht einen Client(Remote) Home Interface der Name Bean (ermöglicht einen Client(Remote) Home Interface der Name Bean (ermöglicht einen Client----ZugrifZugrifZugrifZugriff via RMIf via RMIf via RMIf via RMI----IIOP)IIOP)IIOP)IIOP)

public interface NameHome extends EJBHome {

public Name create(String id, String name, String fname, String street, String location) throws CreateException, RemoteException;

// Methode findByPrimaryKey(...) muss deklariert werden public Name findByPrimaryKey(String id) throws FinderException, RemoteException; // optionale finder-Methoden können folgen }

(Remote) Interface der Business Logik der Name Bean (ermöglicht Zugriff via RMI(Remote) Interface der Business Logik der Name Bean (ermöglicht Zugriff via RMI(Remote) Interface der Business Logik der Name Bean (ermöglicht Zugriff via RMI(Remote) Interface der Business Logik der Name Bean (ermöglicht Zugriff via RMI----IIOP)IIOP)IIOP)IIOP)

public interface Name extends EJBObject { public String getFullName() throws RemoteException; public String getFullAddress() throws RemoteException; }

BeanBeanBeanBean----Klasse der Entity Bean (mit CMP 2.0) Name.Klasse der Entity Bean (mit CMP 2.0) Name.Klasse der Entity Bean (mit CMP 2.0) Name.Klasse der Entity Bean (mit CMP 2.0) Name.

Es werden alle im Local-Interface (NameLocal.java) und im Remote-Interface (Name.java) definierten Geschäftsmethoden und auch bestimmte callback-Methoden implementiert. Unterschiede zu CMP 1.0: - Attribute einer Addresse sind nicht mehr als Felder in der Java-Klasse deklariert - getter/setter-Methoden als abstrakte Methoden deklariert (werden vom Container implementiert) - die Bean-Klasse ist folglich auch abstrakt

public abstract class NameBean implements EntityBean {

public NameBean() { }

Page 48: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Entity Bean ( für die Abbildung von Daten einer DB ) Seite 48 von total 218 Seiten

// Nicht PERSISTENTE FELDER private EntityContext context; private AddressLocalHome addressLocalHome;

// abstrakte getter/setter-Methoden - PERSISTENTE FELDER public abstract String getId(); public abstract void setId(String id);

public abstract String getName(); public abstract void setName(String name); ...

//abstrakte getter/setter-Methoden - RELATIONEN public abstract AddressLocal getAddress(); public abstract void setAddress(AddressLocal address);

// Callback-Methoden (werden bei Bedarf vom Container aufgerufen) // Diese Methoden sind grösstenteils leer implementiert, da wir // Container-Managed Persistence verwenden

// ejbCreate(...) legt ein neues Produkt an // Diese Methode wird vom Container automatisch aufgerufen, sobald // create(.) auf dem Home-Object aufgerufen wird. Die Argumente (Typen) // von create(.) und ejbCreate(.) müssen übereinstimmen. // @return null public String ejbCreate(String id, String name, String fname, String street, String location) throws CreateException { System.out.println("ejbCreate called"); setId(id); setName(name); setFname(fname); return null; }

public void ejbPostCreate(String id, String name, String fname, String street, String location) throws CreateException {

System.out.println("ejbPostCreate called"); AddressLocal address = addressLocalHome.create(street, location); setAddress(address); }

// Business Methoden des REMOTE INTERFACE public String getFullName() { return getName() + ", " + getFname(); }

public String getFullAddress() { return getAddress().getStreet() + ", " + getAddress().getLocation(); }

// LIFECYCLE METHODEN public void setEntityContext(EntityContext context) { System.out.println("setEntityContextCalled"); this.context = context; try { Context ctx = new InitialContext(); Context localCtx = (Context) ctx.lookup("java:comp/env"); Object obj = localCtx.lookup("ejb/address"); addressLocalHome = (AddressLocalHome) PortableRemoteObject .narrow(obj, AddressLocalHome.class); } catch (NamingException e) {throw new EJBException(e); } }

... }

Page 49: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Entity Bean ( für die Abbildung von Daten einer DB ) Seite 49 von total 218 Seiten

Deployment:Deployment:Deployment:Deployment:

Relevante Einstellung im Deploytool:

- EJB Referenz

- Relationship

Diese Einstellungen resultieren in folgendem Eintrag im Deployment Descriptor ejb-jar.xml (Ausschnitt)

Im weiteren bildet das Deploytool sämtliche Interface Methoden der Remote und Locale Interfaces ab und definiert die benutzerspezifischen Parameter wie Transaction, Security, etc.

Deployment Descriptor: ejbDeployment Descriptor: ejbDeployment Descriptor: ejbDeployment Descriptor: ejb----jar.xml (Ausschnitt)jar.xml (Ausschnitt)jar.xml (Ausschnitt)jar.xml (Ausschnitt)

… <relationships> <ejb-relation> <ejb-relationship-role> <multiplicity>One</multiplicity> <relationship-role-source> <ejb-name>NameBean</ejb-name> </relationship-role-source> <cmr-field> <cmr-field-name>address</cmr-field-name> </cmr-field> </ejb-relationship-role> <ejb-relationship-role> <multiplicity>One</multiplicity> <cascade-delete/> <relationship-role-source> <ejb-name>AddressBean</ejb-name> </relationship-role-source> </ejb-relationship-role> </ejb-relation> </relationships>

Page 50: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Design Patterns Seite 50 von total 218 Seiten

CCCC Best PracticeBest PracticeBest PracticeBest Practice

9999 Design PaDesign PaDesign PaDesign Patternstternstternstterns

9.1 Einführung

Dieses Dokument gibt einen ersten Einblick in die Software Design Patterns und erläutert deren Sinn und Zweck. Die Einführung in die Welt der Software Design Patterns wird dabei anhand von drei der häufig verwendeten Patterns gemacht, dem Proxy-, dem Singleton- und dem Factory Method Pattern.

9.1.1 Zweck

Pattern heisst auf Deutsch übersetzt Muster oder Beispiel. Design Patterns stellen wiederverwendbare Lösungen zu häufig auftretenden Problemen in der Software Entwicklung dar. Sie kommen aus der Praxis und wiederspiegeln die Erfahrung von Experten. Die Verwendung solcher Muster erhöht die Qualität der Software und erleichtert die Kommunikation zwischen den einzelnen Entwicklern.

9.1.2 Geschichtliches

Die Idee für die Verwendung von Patterns (Mustern) stammt ursprünglich aus der Architektur. Im Jahre 1977 hat Christopher Alexander ein Buch über die Verwendung von Mustern in der Architektur geschrieben.

Ward Cunningham und Kent Beck nahmen 1987 die Idee von Alexander auf und entwarfen fünf Patterns für die User-Interface Programmierung.

Der endgültige Durchbruch der Software Patterns gelang jedoch erst in den 90er Jahren. Im Jahr 1994 wurde das Buch Design Patterns von den Autoren Erich Gamma, Richard Helm, John Vlissides und Ralph Johnson geschrieben. Design Patterns entwickelte sich zu einem der Einflussreichsten Computer Bücher überhaupt und ist auch unter dem Begriff Gang of Four bekannt.

Die drei ersten in diesem Dokument vorgestellten Patterns (Proxy-, Singleton- und Factory Method Pattern) stammen aus dem Design Patterns Buch.

9.1.3 Referenzen

- GamelanGamelanGamelanGamelan http://www.developer.com/java/

- Gamma E., Helm R., Johnson R., Vlissides J.Gamma E., Helm R., Johnson R., Vlissides J.Gamma E., Helm R., Johnson R., Vlissides J.Gamma E., Helm R., Johnson R., Vlissides J. (1994), Design Patterns, Reading, Addison-Wesley

- Grand M.Grand M.Grand M.Grand M. (1998), Patterns in Java Volume 1, New York, Wiley Computer Publishing

- JavJavJavJavaworldaworldaworldaworld http://www.javaworld.com

- Bien, AdamBien, AdamBien, AdamBien, Adam ( 2003 ), J2EE Patterns, Addison-Wesley

Page 51: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Design Patterns Seite 51 von total 218 Seiten

9.2 Singleton Pattern

[Deutsch: Einzelfall, Einzelkarte]

Das Singleton Pattern gehört zur Kategorie der creational patterns. Die creational patterns werden immer dann angewendet, wenn bei der Erzeugung von Objekten eine Entscheidung verlangt wird. Das Singleton Pattern stellt sicher, dass nur eine Instanz einer Klasse erzeugt wird und ein geeigneter Zugriffsmechanismus zur Verfügung steht.

9.2.1 Problem

Es ist oft notwendig, dass es von einer Klasse exakt eine Instanz gibt. Beispiele hierfür sind: Print-Spoolers, Datenbank-Manager oder Zugriffe auf das Dateisystem. Ein solches Problem wird typischerweise mit dem Singleton Pattern gelöst. Das Singleton Pattern weist die folgenden Eigenschaften auf:

- Es garantiert, dass nur eine Instanz einer Klasse erzeugt wird.

- Es stellt einen globalen Zugriffsmechanismus auf das Objekt zu Verfügung.

9.2.2 Lösung

Wie ersichtlich ist, besteht das Singleton Pattern aus nur einer Klasse und ist daher relativ einfach. Die Singleton Klasse hat eine statische Variable, welche auf die einzige Instanz der Klasse zeigt. Mittels der statischen Methode getInstance() wird eine Referenz auf die Instanz der Klasse zurückgegeben.

Singleton

instance

Singleton getInstance()

operations

9.2.3 Implementation

In diesem Unterkapitel wird die Umsetzung des Patterns in Java aufgezeigt.

Der "Klassische Singleton"Der "Klassische Singleton"Der "Klassische Singleton"Der "Klassische Singleton"

Als erstes wird die klassische Umsetzung des Singleton Pattern in Java angeschaut:

public class ClassicSingleton {

private static ClassicSingleton instance = null;

private ClassicSingleton() { // Exists only to defeat instantiation. } public static ClassicSingleton getInstance() { if(instance == null) { instance = new ClassicSingleton(); } return instance; } }

Der "Klassische Singleton" hat eine statische Referenz auf die einzige Singleton Instanz und diese wird über die statische Methode getInstance() zurückgegeben. Dabei sind folgende Betrachtungen zur Klasse ClassicSingleton zu bemerken:

Page 52: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Design Patterns Seite 52 von total 218 Seiten

1. Die ClassicSingleton Klasse verwendet für die Erstellung der Instanz eine Technik welche als "lazy instantiation" bekannt ist, d.h. dass die Instanz der Klasse (Objekt) erst erstellt wird, wenn diese zum ersten mal gebraucht wird.

2. Der Konstruktor des ClassicSingleton ist als private deklariert. Damit wird sichergestellt, dass nicht mehrere Instanzen der Klasse erzeugt werden können.

3. Leider ist die ClassicSingleton Klasse nicht Thread-Safe! Wenn zwei Threads gleichzeitig die Methode getInstance() aufrufen ist es möglich, dass während der 1. Thread eine Instanz der Klasse erzeugt, der 2. Thread gerade in diesem Moment in den If-Block eintritt. Die Prüfung auf null ist zu diesem Zeitpunkt noch wahr und es wird somit eine zweite Instanz der Klasse ClassicSingleton erzeugt.

Der ThreadDer ThreadDer ThreadDer Thread----Safe Singleton:Safe Singleton:Safe Singleton:Safe Singleton:

Eine einfache Lösung, um das Singleton Pattern Thread-Safe zu programmieren, ist die Methode getInstance() mit dem Schlüsselwort synchronized zu versehen:

public synchronized static ClassicSingleton getInstance()

Diese Lösung funktioniert ausgezeichnet. Die Synchronisation der Methode wird aber nur beim aller ersten Mal benötigt. Da die Synchronisation bezüglich Performance eine sehr teure Operation ist (synchronisierte Methoden können bis zu 100 Mal langsamer sein), ist somit auch diese Lösung nicht optimal.

Eine bessere Lösung um das Singleton Pattern Thread-Safe zu programmieren, ist die statische Variable instance gleich bei der Deklaration zu initialisieren:

public class ThreadSafeSingleton { private static ThreadSafeSingleton instance = new ThreadSafeSingleton(); private ThreadSafeSingleton() { // Exists only to defeat instantiation. } public static ThreadSafeSingleton getInstance() { return instance; } }

Wie ersichtlich, wird die statische Member-Variable instance nun gleich bei der Deklaration initialisiert. Die Java Spezifikation stellt sicher, dass jeder Compiler die Initialisierung von statischen Membern-Variabeln nur einmal und immer beim ersten Zugriff vornimmt. Die ThreadSafeSingleton Klasse ist somit Thread-Safe und hat eine "lazy instantiation".

ZugrZugrZugrZugriff:iff:iff:iff:

Der Zugriff auf ein Singleton Objekt erfolgt folgendermassen:

ThreadSafeSingleton singleton = ThreadSafeSingleton.getInstance(); singleton.doThis(); singleton.doThat();

Page 53: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Design Patterns Seite 53 von total 218 Seiten

9.3 Proxy Pattern

[Deutsch: Stellvertreter, Bevollmächtigter]

Das Proxy Pattern gehört zu den fundamental patterns. Bei dieser Kategorie von Patterns handelt es sich um eine Ansammlung von grundlegenden und sehr wichtigen Patterns, wie zum Beispiel die Delegation oder das Konzept der Interfaces. Die fundamental patterns dienen oft als Grundlage für andere Patterns.

Das Proxy Pattern ermöglicht die Ersetzung eines Objektes durch einen Stellvertreter. Jeder Aufruf an das Objekt erfolgt indirekt über dessen Stellvertreter.

9.3.1 Problem

Es ist oft notwendig, dass bei einem Methodenaufruf eines Objektes, zusätzliche Funktionen ausgeführt werden müssen. Das Ausführen dieser Management-Funktion soll jedoch im Hintergrund geschehen, so dass der Benutzer nichts davon erfährt. Es gibt eine Vielzahl solcher Proxy Pattern Anwendungen.

Nachfolgend sind einige aufgelistet:

- Cache ProxyCache ProxyCache ProxyCache Proxy: Ein Proxy ermöglicht die temporäre Speicherung von Resultaten einer teuren Operation. Andere Benutzer können dann auch auf das Resultat zugreifen.

- Remote ProxyRemote ProxyRemote ProxyRemote Proxy: Ein Proxy erzeugt die Illusion, dass ein Objekt, welches auf einem anderen Server existiert, ein normales lokales Objekt sei. Ein bekanntes Java-Beispiel ist die Remote Method Invocation (RMI).

- Access ProxyAccess ProxyAccess ProxyAccess Proxy: Ein Proxy kontrolliert den Zugriff auf ein Objekt und kann an verschiedene Benutzer unterschiedliche Zugriffsrechte vergeben.

- Synchronization ProxySynchronization ProxySynchronization ProxySynchronization Proxy: Ein Proxy ermöglicht den gleichzeitigen Zugriff von mehreren Benutzern auf ein Objekt.

9.3.2 Lösung

Das Proxy Pattern besteht im wesentlichen aus einer Superklasse oder einem Interface, welche von der Proxy-Klasse wie auch der eigentlichen Service-Klasse verwendet werden. Durch diese Abstraktion wird sichergestellt, dass die Proxy-Klasse und die Service-Klasse dem Benutzer dieselben Methoden zur Verfügung stellen.

Der Benutzer ruft nun demnach eine Methode nicht auf dem eigentlichen Service-Objekt, sondern auf dem Proxy-Objekt auf. Auf dem Proxy-Objekt werden die definierten Management-Funktionen ausgeführt und der Aufruf wird an das eigentliche Service-Objekt weitergeleitet. Eine Antwort des Service-Objektes wird ebenfalls über das Proxy-Objekt dem Benutzer mitgeteilt.

<<interface>>IFService

doIt()

<<interface>>IFService

doIt()

AbstractServ ice

doIt()

....

AbstractServ ice

doIt()

....

ServiceProxy

doIt()

ServiceProxy

doIt()

ServiceProxy

doIt()

Service

doIt()

Service

doIt()

Service

doIt()

10..*

ServiceProxy

doIt()

ServiceProxy

doIt()

ServiceProxy

doIt()

Service

doIt()

Service

doIt()

Service

doIt()

10..*

Page 54: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Design Patterns Seite 54 von total 218 Seiten

9.3.3 Implementation

Ohne spezifische Management-Funktionen verwendet das Proxy Pattern nur eine Superklasse oder ein Interface. Der Schwerpunkt bei diesem Pattern liegt deshalb auch in der Umsetzung dieser Management-Funktionen in der Proxy Klasse.

Für die bessere Veranschaulichung des Proxy Patterns soll die Synchronisation einer Tabelle durch einen Proxy realisiert werden. Es gilt folgende Ausgangslage:

Eine Klassenbibliothek stellt für den Zugriff auf eine Tabelle die Klasse Table zur Verfügung, welche das Interface IFTable implementiert. Leider ist der Zugriff auf die Tabelle nicht synchronisiert. Die Aufgabe lautet die Klasse Table zu synchronisieren, ohne den Source Code zu verändern.

public interface IFTable {

public Object getElementAt(int row, int column);

public void setElementAt(Object element, int row, int column);

public int getNumberOfRows(); }

Die einfachste Lösung für die Implementierung einer Synchronisation ist die Verwendung des Proxy Patterns. Das Beispiel zeigt die Klasse RowLockTableProxy, welche diese Synchronisation vornimmt.

public class RowLockTableProxy implements IFTable {

Table realTable = null; Integer[] locks = null;

public RowLockTableProxy(Table aRealTable) { realTable = aRealTable; locks = new Integer[realTable.getNumberOfRows()]; for(int row = 0; row < locks.length; row++;) { locks[row] = new Integer(row); } }

public Object getElementAt(int row, int column) { synchronized (locks[rows]) { return realTable.getElementAt(row,column); } }

public Object setElementAt(Object element, int row, int column) { synchronized (locks[rows]) { return realTable.setElementAt(element,row,column); } }

public int getNumberOfRows(){ return realTable.getNumberOfRows(); } }

Page 55: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Design Patterns Seite 55 von total 218 Seiten

9.4 Factory Method Pattern

[Deutsch: Fabrik]

Das Factory Method Pattern gehört zur Kategorie der creational patterns. Das Factory Method Pattern definiert ein Interface für die Erzeugung von Objekten, überlässt jedoch die Entscheidung wie die Klasse instanziiert werden soll den Unterklassen.

9.4.1 Problem

Eine Applikation (oder ein Framework) kann manchmal die Klasse eines zu erzeugenden Objektes zur Laufzeit nicht antizipieren (vorwegnehmen). Die Applikation kennt vielleicht nur die abstrakte Klasse oder das Interface, diese lassen sich aber bekanntlich nicht instanziieren. Sie weiss also nur wann sie ein neues Objekt erzeugen muss, nicht aber was für eine Klasse das Objekt hat.

Ein Beispiel hierfür sind Textverarbeitungsprogramme. Ein Textverarbeitungsprogramm muss mit einer Vielzahl von verschiedenen Dokumenttypen umgehen können. Für jeden Dokumenttyp müssen Highlevel Methoden wie Öffnen oder Speichern ausgeführt werden können. Die Umsetzung für jede dieser Methoden muss separat im entsprechenden Dokumententyp implementiert werden. Ein zweites Bespiel für das Factory Method Pattern ist der Mechanismus für das Erzeugen von Enterprise JavaBeans (EJBs).

9.4.2 Lösung

UML-Klassendiagramm des Factory Method Pattern.

Klasse Beschreibung

Product Die abstrakte Superklasse (oder das Interface) der Klassen, welche durch das Factory Method Pattern instanziiert wird.

ConcreteProduct Die konkrete Klasse. Objekte dieses Typs werden durch das Factory Method Pattern erzeugt.

CreationRequestor Die applikationsunabhängige Klasse, welche die instanziierten Objekte der Factory benützt.

IFFactory Das applikationsunabhängige Interface, das die Methode deklariert, welche zum Erzeugen der konkreten Objekte benötigt wird.

Factory Die applikationsspezifische Klasse implementiert das passende Factory Interface und besitzt die Methode zum Erzeugen der konkreten Objekte.

CreationRequestor

newProduct

.....

CreationRequestor

newProduct

.....

ConcreteProduct

operation1operation2.....

ConcreteProduct

operation1operation2.....

<<interface>>IFFactory

createProduct(discriminator):Product

<<interface>>IFFactory

createProduct(discriminator):Product

Factory

createProduct(discriminator):Product

Factory

createProduct(discriminator):Product

1* Uses

Product

operation1operation2.....

Product

operation1operation2.....

1

*

Creates

1

*

Requests- Creation

requestor

creator

Page 56: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Design Patterns Seite 56 von total 218 Seiten

9.4.3 Implementation

Die zentrale Klasse des Factory Method Pattern ist die Klasse Factory. Diese beinhaltet die Methode createProduct(), welche die "Factory Methode" ist und dem Pattern den Namen gibt. Damit verschiedene konkrete Produkte erzeugt werden können, benötigt die Methode createProduct()einen Parameter zur Unterscheidung.

Das nachfolgende Beispiel zeigt eine Factory zur Erzeugung von Dokumenten. Der Methode createProduct() wird als Parameter die Extension des Dokumentes mitgegeben. Anhand der Extension wird das konkrete Dokument (ConcreteProduct) erzeugt und zurückgegeben. Der Rückgabewert der Methode ist eine Referenz der abstrakten Superklasse (Product) des konkreten Dokumentes. Diese Referenz erhält der CreationRequester und kann so mit dem gewünschten Dokument arbeiten.

public class DocumentFactory implements IFDocumentFactory { public Document createDocument(String ext) { if (ext.equals("doc")) return new WordDocument(); if (ext.equals("html")) return new HTMLDocument(); } }

Das nachfolgende Beispiel zeigt eine Factory, welche überhaupt keine Angaben über bestehende Klassen zur Kompilierungszeit benötigt.

public class DynDocumentFactory implements IFDocumentFactory { public Document createDocument(String docClassName) throws Exceptions { Class docClass = Class.forName(docClassName); return (Document)docClass.newInstance(); } }

Ein Beispiel für die Verwendung des Factory Method Pattern ist die Erzeugung von EJBs. Dabei ist das Home Interface EJBHome (und deren Containerspezifische Implementierung) die Factory. Die Methoden create() bei einem Session Bean oder find() bei einem Entity Bean sind die entsprechenden Factory Methoden, welche das gewünschte Bean erzeugen.

// get the JNDI naming context and lookup the EJB Home interface Context initialCtx = new InitialContext() HelloWorldHome home =(HelloWorldHome)initialCtx.lookup("HelloWorld"); // use the Home Interface to create a bean object --> Factory Method // Pattern HelloWorld helloworld = home.create(); // invoke the business methods through the interface reference helloworld.sayHello();

Page 57: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Design Patterns Seite 57 von total 218 Seiten

9.5 J2EE Pattern

Im Zusammenhang mit J2EE Applikationen sind spezielle Anforderungen erwünscht wie:

- Transparenz

- Stabilität

- Performance

Auch hierzu existieren Entwurfsmuster, die jedoch im Gegensatz zu den Strandart Pattern, die weitgehend von der eingestzten Programmiersprache und der verwendeten Plattform unabhängig sind, meist Idioms darstellen (also programmiersprache- und oft auch releaseabhängige Lösungen).

Auch das MVC Muster kann im J2EE implementiert werden:

Die folgenden vier Idioms sind aus dem Buch "J2EE Patterns" von Adam Bien (ISBN: 3-8273-2124-7) zusammengetragen und stellen ein Ausschnitt der darin vorgestellten Pattern dar:

- Service Locator zur Kapselung der Technologie

- Business Delegate zur Vereinfachung der Schnittstelle

- Value Object zur Minimierung der Remote Aufrufe

- Session Fassade zur Kapselung, Caching, Transaktionssteuerung

Page 58: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Design Patterns Seite 58 von total 218 Seiten

DBMSDBMSDBMSDBMS

ClientClientClientClient Applikation ServerApplikation ServerApplikation ServerApplikation Server

EJB DATA

Service LocatorService LocatorService LocatorService Locator - Zugriff auf JNDI - CACHE für ServerObjekte

9.5.1 Service Locator

Die Suche und Erzeugung von EJB ist zeitintensiv und fehleranfällig aufgrund von Namensdiensten (JNDI), Komponentenverteilung (RMI-IIOP) und Factorycaching (Home Interface). Der Service Locator stellt ein Entwurfsmuster zur Kapselung der Technologie und eine Performancesteigerung zur Verfügung.

Problem:Problem:Problem:Problem:

Bei einem Zugriff auf eine EJB muss zuerst ein Namensdienst initialisiert und die Verbindung zum Server hergestellt werden. Dazu werden produktspezifische Informationen benötigt. Die meisten JNDI Implementierungen basieren auf CORBA-Technologie, die eine Interpretation des Servers verlangt (z.B: "iiop://localhost:3700"). Dies kann bis zu mehreren Sekunden in Anspruch nehmen, da der Name zuerst von einem DNS aufgelöst werden muss.

Lösung:Lösung:Lösung:Lösung:

Das Ermitteln von Dienstleistungen (z.B. JNDI Context) wird in den Locator verlagert. Dadurch verschwindet das sich wiederholende Downcasting über die narrow Methode von PortableRemoteObject im Service Locator.

Die folgenden Anforderungen werden an den Service Locator gestellt:

- bereits instanzierte Instanz des Home Objektes und Ressourcen werden gecached

- Handels (robuste Referenzen) werden gecached

- JNDI Technologie ist transparent für den Client

Implementation:Implementation:Implementation:Implementation:

Der Service Locator kapselt die Zugriffe auf das JNDI und stellt ein Cache für die Serverschnittstellenobjekte zur Verfügung. Der Service Locator wird meist als Singelton implementiert, damit auch nur tatsächlich eine Instanz des InitialContext pro VM existiert.

Page 59: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Design Patterns Seite 59 von total 218 Seiten

ServiceLocator to cache HomeObject (Ausschnitt)ServiceLocator to cache HomeObject (Ausschnitt)ServiceLocator to cache HomeObject (Ausschnitt)ServiceLocator to cache HomeObject (Ausschnitt)

public EJBHome getHome(String name,boolean cached) throws Exception{ Object temp = null; if(cached) temp = this.homeCache.get(name); EJBHome home = null;

if(temp !=null && temp instanceof EJBHome){ return (EJBHome)temp; }else{ Object ref = context.lookup(name); EJBMetaData meta = ((EJBHome)ref).getEJBMetaData(); home = (EJBHome) PortableRemoteObject.narrow( ref,meta.getHomeInterfaceClass()); if(!meta.isSession() || meta.isStatelessSession()) this.homeCache.put(name,home); } return home; }

public static ServiceLocator getInstance() throws Exception{ if(instance==null) instance = new ServiceLocator(); return instance; }

public EJBHome getHome(String name) throws Exception{ return getHome(name,true); }

public static void main(String[] args) throws Exception{ Hashtable hash = new Hashtable(); hash.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory"); hash.put("java.naming.provider.url","iiop://localhost:3700"); } }

ServiceLocatorClientServiceLocatorClientServiceLocatorClientServiceLocatorClient

public class ServiceLocatorClient {

public static void main(String args[]) throws Exception{

HomeFinder finder = ServiceLocator.getInstance(); EJBHome home = finder.getHome("Test"); System.out.println("HomeClass " + home.getClass().getName());

TestHome testHome = (TestHome)home; Test test = testHome.create(); } }

Page 60: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Design Patterns Seite 60 von total 218 Seiten

DBMSDBMSDBMSDBMS

Client Applikation ServerApplikation ServerApplikation ServerApplikation Server

EJB DATA

Business DelegateBusiness DelegateBusiness DelegateBusiness Delegate - Kapselung der BusinessLogik

9.5.2 Business Delegate

Der Remotezugriff auf einen Server erfordert die Implementation einer entsprechenden Tech-nologie (z.B. RMI-IIOP). Ein Client ist aber nicht an der Technologie sondern vielmehr an der Geschäftslogik interessiert. Das Idiom des Business Delegate ermöglicht eine Kapselung der Technologie und somit eine Vereinfachung der Schnittstelle zur Geschäftslogik.

Problem:Problem:Problem:Problem:

Bei einem Zugriff auf die Geschäftslogik in einem EJB-Kontainer ist oft ein Remotezugriff not-wendig. Ein Remotezugriff ist jedoch viel komplexer und zeitintensiver als ein Lokalzugriff. Zusätzlich müssen noch Exceptions (HostNotFoundException, StubNotFoundException, etc.) abgefangen werden.

Lösung:Lösung:Lösung:Lösung:

Die einzelnen Beans werden über eine zentrale Session Bean angesprochen. Diese hält die Instanzen der verschiedenen Beans und stellt diese dem Client in einer Schnittstelle zur Verfügung und kann auch Informationen an die anderen Beans weitergeben. Der Client produziert "Events" die vom Business Delegate Idiom "verteilt" werden und hat einen einfachen Zugriff auf die Geschäftslogik zur Verfügung.

Implementation:Implementation:Implementation:Implementation:

Das Business Delegate stellt die Schnittstelle zwischen Client und Geschäftslogik zur Ver-fügung. Dabei kapselt dieses Idiom die Zugriffslogik. Das Business Delegate wird vom Client instanziert und benutzt, die notwendigen Services werden durch den Service Locator beschafft.

Business Delegate Interface (wird dem Client zur Verfügung gestellt)Business Delegate Interface (wird dem Client zur Verfügung gestellt)Business Delegate Interface (wird dem Client zur Verfügung gestellt)Business Delegate Interface (wird dem Client zur Verfügung gestellt)

public interface BusinessDelegateIF { public CustomerVO getCustomer(String id); public CustomersVO[] getAllCustomerForZip(String zipPrefix); public CustomersVO[] getAllCustomers(); ... }

Page 61: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Design Patterns Seite 61 von total 218 Seiten

DBMSDBMSDBMSDBMS ClientClientClientClient Applikation ServerApplikation ServerApplikation ServerApplikation Server

EJB DATA

Business DelegateBusiness DelegateBusiness DelegateBusiness Delegate

ValueObject

Business Delegate (Kapselung der BusinessMethoden)Business Delegate (Kapselung der BusinessMethoden)Business Delegate (Kapselung der BusinessMethoden)Business Delegate (Kapselung der BusinessMethoden)

public CustomerVO getCustomer(String id){ CustomerVO customer = null; try{ customer = this.customer.findByPrimaryKey(id); }catch(RemoteException e){ throws new ProblemWithBusinessMethodeException(this.e); } return customer: } ...

9.5.3 Value Object

Die Datenübertragung über das Netzwerk, die meistens von der Data Tier bis zur Client Tier und umgekehrt erfolgt, ist oft limitierender Faktor in J2EE Applikationen. Das Value Object Idiom verbessert die Performance und minimiert die Remote Methodenaufrufe.

Problem:Problem:Problem:Problem:

Der Zugriff auf ein EJB erfolgt oft über Remote Methodenaufrufe. Oft wird jedoch nur eine Teilmenge der benötigten Daten übermittelt (z.B: getter / setter Methoden). Sinnvoller ist es die gesammte benötigte Datenmenge (Datensatz) in einem Methodenaufruf zu übermitteln.

Enterprise Beans haben in der Regel ganze Gruppen von Attributen, die vom Client in der Gruppe gebündelt abgerufen und gesetzt werden können. Auf diese Weise muss nicht für jedes Attribut einzeln eine Methode zum Setzen und Abfragen aufgerufen werden. Der Client erhält die Attribute in einem Value Object gebündelt.

Lösung:Lösung:Lösung:Lösung:

Die vielen "get"-Aufrufe werden bereits im EJB Container zusammengefasst und dem Client als Objekt übermittelt. Dieses Kontainer-Objekt besteht nur aus Zugriffslogik und keiner Geschäftslogik, ist somit ein Value Objekt und entspricht folgenden Anforderungen:

- minimieren der Remote Methodenaufrufe an den Server

- Die Geschäftsdaten werden als Objekt (Value Object) an den Client übergeben

- das Auslesen der Objekt Attribute findet clientseitig statt

Page 62: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Design Patterns Seite 62 von total 218 Seiten

Implementation:Implementation:Implementation:Implementation:

Das Value Objekt wird durch eine serialisierbare Klasse repräsentiert, die lediglich zu Datenhaltungszwecken dient. Das Value Object wird auf der entfernten Maschine erzeugt und gefüllt, über das Netzwerk transferiert und lokal ausgelesen.

Value Object als serialisierbare KlasseValue Object als serialisierbare KlasseValue Object als serialisierbare KlasseValue Object als serialisierbare Klasse

public class PersonVO implements Serializable{ public String id = null; public String fname = null; public String name = null;

public PersonVO(){}

public PersonVO(String id, String fname, String name) { this.init(id,fname,name); }

protected void init(String id, String fname, String name); this.id = id; this.fname = fname; this.name = name; }

public PersonVO(PersonVO person){ this.init(person.getId(),person.getFname(),person.getName()); }

public String getId(){ return this.id; } public String getFname(){ return this.fname; } public String getName(){ return this.name; }

public void setId(String id){this.id = id;} public void setFname(String fname){this.fname = fname;} public void setName(String name){this.name = name;} }

Grundsätzlich können Value Objects von folgenden Komponenten erzeugt werden:

- Data Access Objects

- Session Façade (einer Session Bean, die den Zugriff auf ein Entity Bean managed)

- Business Delegate

- Session Bean

- Entity Bean

- Komponente der Präsentationsschicht

Es handelt sich also grundsätzlich um Komponenten, die in der Geschäftslogik oder in der Integrationsschicht liegen und in der Lage sind, benötigte Daten zu beschaffen. Meistens werden jedoch die Value Objects von den Entity Beans erzeugt, da diese die notwendige "Persistence Schicht" repräsentieren.

Die CMP Entity Bean der EJB 2.0 ist ein "Value Object"!Die CMP Entity Bean der EJB 2.0 ist ein "Value Object"!Die CMP Entity Bean der EJB 2.0 ist ein "Value Object"!Die CMP Entity Bean der EJB 2.0 ist ein "Value Object"!

Page 63: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Design Patterns Seite 63 von total 218 Seiten

Beispiel für eine EJB 2.0 CMP Persistenz:Beispiel für eine EJB 2.0 CMP Persistenz:Beispiel für eine EJB 2.0 CMP Persistenz:Beispiel für eine EJB 2.0 CMP Persistenz:

public abstract class AddressBean implements EntityBean {

public abstract String getId(); public abstract void setId(String id); public abstract String getStreet(); public abstract void setStreet(String street); public abstract String getLocation(); public abstract void setLocation(String location);

public String ejbCreate(String street, String location) throws CreateException { setId(street + location); setStreet(street); setLocation(location); return null; } public AddressVO getAddressVO(){ return new AddressVO(getId(),getStreet(),getLocation()); } ... }

9.5.4 Session Façade

Die Geschäftslogik liegt typischerweise im EJB Container; diese wird durch Komponenten (EJBs) abgebildet. Ein Client, der diese Logik verwenden möchte muss den Zusammenhang der einzelnen Komponenten im Container kennen.

Problem:Problem:Problem:Problem:

Entity Beans bilden persistente Objekte ab, repräsentieren aber lediglich den Zustand der darunterliegenden Datenbank. Die EJBs sind in Bezug auf Wiederverwendbarkeit, Transaktionssteuerung sowie Zustandserhaltung nicht, oder nur mit sehr hohem Aufwand verbunden, vom Client trennbar.

Wenn ein Client auf verschiedene Entity Beans zugreift und verschiedene Methoden der Entity Beans aufruft, um eine Aufgabe zu erledigen, kann dies verschiedene Probleme mit sich bringen. Zum einen erhöht sich der Netzwerk Traffic, des weiteren wird die Workflow Logik auf den Client verlagert, zum anderen sind die Methodenaufrufe durch die client-seitige Inszenierung möglicherweise nicht in einen notwendigen Transaktionszusammenhang gestellt.

Die Entity Beans mit weiterer Processing Logik aufzublähen, ist nicht der richtige Lösungsansatz. Da die Entity Bean Schicht von der langfristigen Perspektive her aus verschiedenen Sichten und Aufgaben gesehen wird, wird der Einbau von Anwendungslogik zu Zwecken der Performance Verbesserung eher zu Wartungsproblemen führen.

Deshalb sollte die Anwendungslogik, die eine Kette von Aufrufen von Entity Bean Methoden widerspiegelt, in einer Session Bean implementiert werden. Der Client ruft dann eine eine eine eine Methode der Session Bean auf, um seine Aufgabe zu erledigen. Die Methode der Session Bean übernimmt die Aufrufe der Methoden der verschiedenen Entity Beans.

Lösung:Lösung:Lösung:Lösung:

Was der Client möchte ist eine Schnittstelle, die ein Use Case abbildet. Dem Client kann es egal sein, wieviele Entity oder Session Beans diese Schnittstelle implementiert. Für den Client ist nur die korrekte Abbildung des Anwendungsfalles wichtig. Das Session Façade definiert eine neue "Schicht", die als Session Bean implementiert ist und folgende Anfgorderungen erfüllt:

Page 64: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Design Patterns Seite 64 von total 218 Seiten

DBMSDBMSDBMSDBMS

ClientClientClientClient Applikation ServerApplikation ServerApplikation ServerApplikation Server

EJB

EJB

DATA

Session Façade

- Abschirmung und Entkoppelung des Client vor Subsystemen ( Entity Bean, etc. )

- Erhalt der Unabhängigkeit der Subsysteme

- Vereinfachung der Business Schnittstelle

- Implementierung von allgemeinen Diensten wie Caching, Authorisierung, etc.

- Zustandsverwaltung des Client

- Transaktionssteuerung

Implementation:Implementation:Implementation:Implementation:

In einer zusätzlichen Schicht, implementiert mit einer Session Bean, werden diese An-forderungen untergebracht. Falls ein Caching gefordert ist, muss die Session Bean statefull sein. Diese EJB entspricht in ihrer Funktionalität dem klassischen GoF Façade Pattern. Sie bietet eine einfache Schnittstelle und verbirgt die Komplexität der Subsysteme vor dem Client.

Session Façade um einen Datensatz zu ändern;Session Façade um einen Datensatz zu ändern;Session Façade um einen Datensatz zu ändern;Session Façade um einen Datensatz zu ändern; eine Transaktion wird gestartet (Ausschnitt) eine Transaktion wird gestartet (Ausschnitt) eine Transaktion wird gestartet (Ausschnitt) eine Transaktion wird gestartet (Ausschnitt)

public void updatePerson (PersonVO person) throws Exception{ try{ getPerson(person.getId()).remove(); this.createPerson(person); }catch(Exception e){ throw new Exception("PersonBean.updatePerson " + e); } }

9.6 Weitere Pattern im J2EE Umfeld

9.6.1 Value Object Assembler

Der Value Object Assembler stellt Value Objects und Schichten dynamisch in Session Beans zusammen und kommuniziert diese an den Presentation Layer. Er reichert Value Objects um Attribute an, die nur in der Bearbeitungsschicht benötigt werden, aber nicht in den Business Objects.

9.6.2 Composite Entity

Business Objekte sind oft nicht einfache Strukturen, sondern Graphen von Attribut Knoten. Ein Beleg hat Belegzeilen, und jede Belegzeile kann wieder mehrere Kostenrechnungs-informationen enthalten. Um der Modellschicht eine grössere Konsistenz zu geben, ist es besser, wenn für die abhängigen Objekte eine zentrale Entity Bean geschaffen wird, über die

Page 65: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Design Patterns Seite 65 von total 218 Seiten

eine Session Bean mit den abhängigen Objekten umgeht. Das zentrale Business Objekt steuert seine abhängigen Objekte – die meist selbst wieder Entity Beans sind.

9.6.3 Data Access Objects DAO

Das Data Access Object Pattern trennt das Interface für eine System Ressource von der tatsächlichen Zugriffsstrategie. Jede Enterprise Bean, die auf eine Backend Ressource wie eine Datenbanktabelle zugreift, kann/sollte eine zugehörige DAO Klasse für diese Ressource haben.

Dass das Laden und Speichern über JDBC und SQL geschieht, bleibt für die Anwendungs-schicht verborgen. Wenn ein anderer Persistenz Mechanismus gewählt wird, kann der Code im DAO ausgetauscht werden, ohne dass die restliche Anwendung davon betroffen ist.

9.6.4 Core J2EE Patterns

http://java.sun.com/blueprints/corej2eepatterns/Patterns/index.html

Page 66: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Programmiereinschränkungen (Regeln) Seite 66 von total 218 Seiten

10101010 Programmiereinschränkungen (Regeln)Programmiereinschränkungen (Regeln)Programmiereinschränkungen (Regeln)Programmiereinschränkungen (Regeln)

1

kein Threads Management oder Synchronisation in (EJB) Beanskein Threads Management oder Synchronisation in (EJB) Beanskein Threads Management oder Synchronisation in (EJB) Beanskein Threads Management oder Synchronisation in (EJB) Beans

- ist Aufgabe des Applikationsservers

- Bean = einzelner Thread, keine Kongruenz

2

keine Klassenvariablen / keine Klassenvariablen / keine Klassenvariablen / keine Klassenvariablen / ----methoden verwendenmethoden verwendenmethoden verwendenmethoden verwenden

- verschiedene Prozesse bei Cluster-Deployment

3

kein stdin / kein stdin / kein stdin / kein stdin / ----out verwenden out verwenden out verwenden out verwenden

- Ausgabe- / Eingabestream sind nicht definiert

4

kein direkter Zugriff auf Dateien oder Directorieskein direkter Zugriff auf Dateien oder Directorieskein direkter Zugriff auf Dateien oder Directorieskein direkter Zugriff auf Dateien oder Directories

- nicht definierter Speicherort bei Cluster-Deployment

5

keine native Librarieskeine native Librarieskeine native Librarieskeine native Libraries

- nicht definierter Speicherort bei Cluster-Deployment

6

keine keine keine keine this –––– Referenz Referenz Referenz Referenz

- SessionContext.getEJBObject();

- EntityContext.getEJBObject();

Der EJB Context javax.ejb.SessionContext und javax.ejb.EntityContext erlaubt den Zugriff auf das REMOTE Interface des aktuellen Beans. Dies ergibt eine Referenz auf das Bean selbst, die weitergegeben werden kann.

Page 67: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 EJB Anwendungsbeispiele mit JBoss AS Seite 67 von total 218 Seiten

11111111 EJB Anwendungsbeispiele mit JBoss ASEJB Anwendungsbeispiele mit JBoss ASEJB Anwendungsbeispiele mit JBoss ASEJB Anwendungsbeispiele mit JBoss AS

JBoss™ als Open Source Applikationsserver hat einen potentiellen Markt im J2EE Umfeld. Für das Testen und Kennenlernen von J2EE Applikationen bietet JBoss zusammen mit dem Eclipse Entwicklungstool eine ready-to-use Plattform.

Entsprechende Installationsinformationen sind im Anhang aufgeführt. Die nachfolgenden Erläuterungen und Beispiele dienen zur Repetition der behandelten EJB Theorie und geben einen Einblick in das Aufsetzen von J2EE Applikationen mit dem JBoss AS (http.//www.jboss.org)

11.1 wiederverwendbare Komponenten

EJBs sind als wiederverwendbare, verteilte Komponenten konzipiert, welche relativ lose gekoppelt und in einer verteilten Umgebung einsetzbar sind.

Der Verteilungsaspekt dieser Komponenten ermöglicht die Trennung der Anwendung (Geschäftslogik), der Bedienerführung (Darstellungslogik) und der Datenerhaltung (Persistenz), denn ohne dem Deployen dieser Komponenten :

- kann jeder Fehler in irgendeinem der Client-Programme den Datenbankinhalt beschädigen

- kann ein Benutzer versuchen, die Geschäftslogik zu umgehen und direkt auf die Datenbank zuzugreifen

- muss eine neue Version der Geschäftslogik auf allen PCs installiert werden

- wird die Modularisierung nicht gefördert

- ist die Art der Darstellung ebenso festgelegt wie die Art der Verarbeitung

Daher trennt man die Geschäftslogik von der Darstellung und installiert sie auf einem zentralen Server, der zwischen den Clients und dem Datenbankserver vermittelt. Das ist die klassische 3-Schicht-Architektur (3-Tier Architecture).

EJB bilden Suns Ansatz, um die gewünschte Flexibilität zu erreichen. Die mittlere Schicht wird in Komponenten zerlegt, was auch die Änder- und Erweiterbarkeit unterstützt (und der Wiederverwendung, um den Aufwand zur Erstellung zu kompensieren). Zur Kommunikation zwischen den Komponenten dient gebräuchliche Middleware, vor allem RMI, aber auch (zum Client) CORBA oder Webdienste.

11.2 EJB Container

Ein EJB-Container in Verbindung mit einem Application Server nimmt den Programmierern erhebliche Arbeit ab:

- die Verteilung der Objekte:

- die Anbindung eines Webservers (lokal oder über RMI-IIOP), der die Kommunikation mit den Clients übernimmt

- die Anbindung der Clients oder anderer Enterprise Beans über RMI-IIOP

- den lokalen Zugriff auf andere Enterprise Beans

- die Anbindung von Clients oder anderen Anwendungen über SOAP (und WSDL)

- den Datenbankzugriff (über JDBC)

- die Thread-Verwaltung und Synchronisation - EJBs müssen nicht thread-sicher sein

- die Prozessverwaltung um die Last optimal bewältigen zu können

- Zuverlässigkeit und eventuell sogar Lastverteilung auf mehrere Server

Page 68: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 EJB Anwendungsbeispiele mit JBoss AS Seite 68 von total 218 Seiten

- Zustandsverwaltung - Objekte werden bei Bedarf aktiviert und deaktiviert

- Pooling von z.B. Datenbankverbindungen

- Transaktionen und Wiederherstellung

- auf Wunsch den Datenaustausch mit der Datenbank ohne (sichtbares) SQL

- Sicherheit

- Werkzeuge zur Systemadministration

11.3 EJB Ausprägungen

Entity BeansEntity BeansEntity BeansEntity Beans

- besitzen einen dauerhaften (persistenten) Zustand

- modellieren Objekte im Anwendungsbereich

- stellen Datenbehälter mit Regeln zur Sicherung eines konsistenten Zustands dar

- bilden Datensätze in einer Datenbank-Tabelle ab

SessionSessionSessionSession----BeanBeanBeanBean

- zustandsbehaftet, werden sie bei Bedarf erzeugt und sind einem bestimmten Client zugeordnet, dessen Sitzung sie verwalten, ihr Zustand wird nicht gespeichert und geht nach Gebrauch verloren

- zustandslos, verwalten sie Sitzungen, sind aber austauschbar und können daher in einem Pool gehalten werden. Das macht sie wesentlich leistungsfähiger als die Beans mit Zustand. Sie können eine Webdienst-Schnittstelle haben (neu in EJB 2.1)

- modellieren Geschäftsvorgänge (Tätigkeiten, Anwendungsfälle) im Anwendungsbereich

- dient zur Kommunikation mit dem Client

- nehmen oft die Dienste von Entity-Beans und anderen Session-Beans in Anspruch

MessageDrivenMessageDrivenMessageDrivenMessageDriven----Bean (ab EJB 2.0) Bean (ab EJB 2.0) Bean (ab EJB 2.0) Bean (ab EJB 2.0)

- sind zustandslos

- dienen zur asynchronen Kommunikation, d.h. für Anfragen, auf die keine unmittelbare Antwort erwartet wird

- sind nicht über eine Schnittstelle, sondern über eine Topic- oder Queue-Destination ansprechbar

- werden durch ein Ereignis aktiviert

- Verwendung gleicht der von zustandslosen Session-Beans

Page 69: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 EJB Anwendungsbeispiele mit JBoss AS Seite 69 von total 218 Seiten

11.4 EJB Schnittstellen

Jede Enterprise Bean kann eine oder mehrere der folgenden Schnittstellen implementieren:

- remote Interfaces erlauben den Zugriff über RMI-IIOP, sei es von aussen oder lokal

- local Interfaces (neu in EJB 2.0) erlauben den Zugriff nur innerhalb des gleichen Application Servers (in den auch ein Webserver integriert sein kann). Diese Zugriffe sind effizienter und haben die normale Java-Semantik und die gleichen Parameter wie Remote Interfaces

Sowohl von local wie auch von remote Schnittstellen gibt es je zwei Ausprägungen:

- Remote Interface, enthält die Methoden der Anwendung

- Home Interface, dient zur Verwaltung der Enterprise Bean

- Webdienst-Schnittstellen für die Stateless Session-Bean (neu in EJB 2.1), dabei ist nur die Remote Schnittstelle implementiert

11.5 EJB Bestandteile

Eine Enterprise Bean besteht aus mehreren Teilen:

BeanBeanBeanBean----KlasseKlasseKlasseKlasse

class AnwendungBean implements EntityBean/SessionBean/MessageDrivenBean { ... }

InterfacesInterfacesInterfacesInterfaces

interface Anwendung extends EJBLocalObject/EJBObject/Remote { ... }

interface AnwendungHome extends EJBLocalHome/EJBHome { ... }

DeploymentDeploymentDeploymentDeployment----Descriptor Descriptor Descriptor Descriptor

... <enterprise-beans> <entity> <ejb-name>Anwendung1EJB</ejb-name> <home>Anwendung1Home</home> <remote>Anwendung1</remote> <ejb-class>Anwendung1Bean</ejb-class> ... </entity> <session> <ejb-name>Anwendung2EJB</ejb-name> <home>Anwendung2Home</home> <remote>Anwendung2</remote> <ejb-class>Anwendung2Bean</ejb-class> ... </session> ... </enterprise-beans>

Page 70: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 EJB Anwendungsbeispiele mit JBoss AS Seite 70 von total 218 Seiten

Verpackt in eine jarVerpackt in eine jarVerpackt in eine jarVerpackt in eine jar----Datei (EJB 2.0)Datei (EJB 2.0)Datei (EJB 2.0)Datei (EJB 2.0)

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD

EnterpriseJavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd"> <ejb-jar> ... </ejb-jar>

Verpackt in eine jarVerpackt in eine jarVerpackt in eine jarVerpackt in eine jar----Datei (EJB 2.1)Datei (EJB 2.1)Datei (EJB 2.1)Datei (EJB 2.1)

<?xml version="1.0" encoding="UTF-8"?> <ejb-jar xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd" version="2.1"> ... </ejb-jar>

Zwischen den Versionen ist man von DTDs auf XML-Schema umgestiegen.

Die Schnittstellen und der Deployment-Descriptor können von Werkzeugen aus der Bean-Klasse erzeugt werden, etwa durch XDoclet (http://sourceforge.net/projects/xdoclet). Dabei werden die entsprechenden javadoc-Kommentare ausgewertet. Den Deployment-Descriptor erfassen viele Application Server auch per Formular.

11.6 EJB Implementation

- die Bean-Klasse muss einen parameterlosen Konstruktor besitzen

- die Schnittstelle EnterpriseBean erweitert die Schnittstelle Serializable, damit handelt es sich um eine echte Bean

- die Bean-Klasse muss die Methoden aus allen im Deployment-Descriptor angesprochenen Schnittstellen implementieren - allerdings nicht unmittelbar. Diese Schnittstellen zeigen an, was man von ausserhalb des Application Servers sieht. Beim Deployment werden Klassen erzeugt, die sie implementieren. Die Bean-Klasse muss entsprechende Methoden bereitstellen, die die eigentlichen Aktionen enthalten:

- bei Entity-Beans müssen zu jeder createXYZ-Methode aus dem Home-Interface zwei Methoden ejbCreateXYZ und ejbPostCreateXYZ mit der gleichen Signatur implementiert werden

- bei Session-Beans muss zu jeder createXYZ-Methode aus dem Home-Interface die Methoden ejbCreateXYZ mit der gleichen Signatur implementiert werden

- bei MessageDriven-Beans muss eine Methode ejbCreate implementiert werden

- bei Entity-Beans muss zu jeder findXYZ-Methode aus dem Home-Interfcae eine Methode ejbFindXYZ mit der gleichen Signatur implementiert werden

- bei Entity-Beans muss zu jeder Methode XYZ des Home-Interface eine Methode ejbHomeXYZ mit der gleichen Signatur implementiert werden

- zusätzlich muss jede Methode der Anwendung aus dem Remote-Interace mit der gleichen Signatur implementiert werden

Page 71: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 EJB Anwendungsbeispiele mit JBoss AS Seite 71 von total 218 Seiten

11.7 EJB Deployment Descriptors

Die für den Deployprozess notwendigen Deployment Descriptoren, die wir bis anhin mit dem Deploytool erstellt haben möchten wir näher betrachten:

- ejb-jar.xml

- jboss.xml

- application.xml

- application-client.xml

- jboss-client.jar

- jbosscmp-jdbc.xml

ejbejbejbejb----jar.xml : beschreibt Bean auf logischer Ebenejar.xml : beschreibt Bean auf logischer Ebenejar.xml : beschreibt Bean auf logischer Ebenejar.xml : beschreibt Bean auf logischer Ebene

- Namen der Java-Klassen

- Namen der Attribute

- Transaktionsverhalten

- Security Mapping

- Spezifikation der Query-Methoden

- Resource Referenzen ejb-jar.xml ENC Elements

(ENC = Enterprise Naming Context)

jboss.xml : bescheibt Informationen für den jboss.xml : bescheibt Informationen für den jboss.xml : bescheibt Informationen für den jboss.xml : bescheibt Informationen für den Application ServerApplication ServerApplication ServerApplication Server

- JNDI-Mapping: Name unter dem das Home-Interface gefunden wird

- Resource Referenzen

jboss.xml ENC Elements

(ENC = Enterprise Naming Context)

<jboss> <enterprise-beans> <session> <ejb-name>moneyexchange</ejb-name> <jndi-name>ejb/moneyexchange</jndi-name> <resource-ref> <res-ref-name>jdbc/ExchangeTable</res-ref-name> <jndi-name>java:/mySQLDS</jndi-name> </resource-ref> </session> </enterprise-beans> </jboss>

Page 72: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 EJB Anwendungsbeispiele mit JBoss AS Seite 72 von total 218 Seiten

application.xml : beschreibt eine ganze Enterprise Applikationapplication.xml : beschreibt eine ganze Enterprise Applikationapplication.xml : beschreibt eine ganze Enterprise Applikationapplication.xml : beschreibt eine ganze Enterprise Applikation

Die graphische Representation zeigt die Struktur des J2EE application.XML Schema.

<application> <display-name> MoneyExchange </display-name> <module> <ejb> MoneyExchange.jar </ejb> </module> </application>

applicationapplicationapplicationapplication----client.xml : beschreibt client.xml : beschreibt client.xml : beschreibt client.xml : beschreibt First Tier CliFirst Tier CliFirst Tier CliFirst Tier Client Programent Programent Programent Program

Alle gültigen application-client.xml Deployment Descriptoren müssen dem abgebildeten XML Schema oder einer entsprechenden DTD Definition folgen und beschreiben:

- Client Beschreibung

- Environment Entries

- EJB Referenzen

- Resource Referenzen

- Resource Environment Referenzen

<application-client> <display-name> MoneyExchangeClient </display-name> <ejb-ref> <ejb-ref-name> ejb/MoneyExchange </ejb-ref-name> <ejb-ref-type> Session </ejb-ref-type> <home> beans.MoneyExchangeHome </home> <remote> beans.MoneyExchange </remote> </ejb-ref> </application-client>

Page 73: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 EJB Anwendungsbeispiele mit JBoss AS Seite 73 von total 218 Seiten

jbossjbossjbossjboss----client.xml : bescheibt Informationen für den Application Serverclient.xml : bescheibt Informationen für den Application Serverclient.xml : bescheibt Informationen für den Application Serverclient.xml : bescheibt Informationen für den Application Server

- Versionsnummern,....

- JNDI-Mapping: Name unter dem das Home-Interface gefunden wird

- Resource Referenzen

<jboss-client> <jndi-name>MoneyExchangeClient</jndi-name> <ejb-ref> <ejb-ref-name>ejb/MoneyExchange</ejb-ref-name> <jndi-name>moneyexchange</jndi-name> </ejb-ref> </jboss-client>

jbosscmpjbosscmpjbosscmpjbosscmp----jdbc.xml : beschreibt O/Rjdbc.xml : beschreibt O/Rjdbc.xml : beschreibt O/Rjdbc.xml : beschreibt O/R----Mapping fMapping fMapping fMapping für die Datenbank (applikationsserverspezifisch)ür die Datenbank (applikationsserverspezifisch)ür die Datenbank (applikationsserverspezifisch)ür die Datenbank (applikationsserverspezifisch)

Datasource: Information für den DB-Connect im Application Server

- jndi-Name: Name unter dem das Home-Interface gefunden wird

<jbosscmp-jdbc> <defaults> <datasource> java:/DefaultDS </datasource> <datasource-mapping> MySQL </datasource-mapping> <create-table>true</create-table> <remove-table>true</remove-table> </defaults> <enterprise-beans> <entity> <ejb-name>Product</ejb-name> <table-name>ProductTable</table-name> </entity> </enterprise-beans> </jbosscmp-jdbc>

Page 74: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Übung ee4 : Datenanbindung mit Stateless Session Bean Seite 74 von total 218 Seiten

12121212 Übung ee4 : Datenanbindung mit Stateless Session BeanÜbung ee4 : Datenanbindung mit Stateless Session BeanÜbung ee4 : Datenanbindung mit Stateless Session BeanÜbung ee4 : Datenanbindung mit Stateless Session Bean

In diesem Beispiel soll eine Datenquelle von einer Session Bean aus angesprochen werden. Während der erste Lösungsansatz einer standart JDBC Verbindung beschreibt, konzentriert sich der zweite Lösungsansatz auf den Lookup des Datasource Objektes per JNDI.

12.1 JDBC API

Klassen und Schnittstellen der:

java.sql

JDBC API

12.2 Währungsrechner mit Session-Beans

Erstellen Sie ein Stateless Session Bean zum Umrechnen von Währungskursen ( z.B. CHF > EUR), die Währungskurse sollen durch eine DB-Tabelle persistent gehalten werden und durch das EJB repräsentiert werden.

Client Attribute : final int amount = 250; final String changeTo = "EUR";

Die Basiswährung ist "CHF"

12.2.1 Datenbankanbindung mit Session-Beans

Lesen Sie den Umrechnungskurs aus der mySQL Datenbank "ee" und erweitern Sie Ihre Applikation mit mehreren möglichen Währungseinheiten, z.B. USD, GBP, etc.

Erstellen Sie eine entsprechende Tabelle "rates" in der mySQL DB und definieren Sie die Kurse:

CREATE TABLE RATES( ID VARCHAR(10) PRIMARY KEY, BASECUR VARCHAR(3), RATE VARCHAR(10) ); INSERT INTO RATES VALUES('1', 'USD', '1.25'); INSERT INTO RATES VALUES('2', 'EUR', '1.52'); INSERT INTO RATES VALUES('3', 'CHF', '1.00');

Alternative: Benutzen Sie das entsprechende Jakarta-Ant Target "run-sql-script" das in der build.xml Datei vorbereitet ist.

Für die Datenbank Anbindung fokussieren wir zwei Varianten: "JDBC" und "JNDI Lookup"

Page 75: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Übung ee4 : Datenanbindung mit Stateless Session Bean Seite 75 von total 218 Seiten

12.2.2 JDBC Connection

Ergänzen Sie den Source der Bean mit den notwendigen Statements um die JDBC Datenquelle localhost:ExchangeTable.rates abzufragen und übergeben Sie die Währungseinheit als Parameter der Business-Methode :

Source CodSource CodSource CodSource Code Ansatz: JDBC Connection in MoneyExchangeBean.javae Ansatz: JDBC Connection in MoneyExchangeBean.javae Ansatz: JDBC Connection in MoneyExchangeBean.javae Ansatz: JDBC Connection in MoneyExchangeBean.java

String SQLQuery = "SELECT rate FROM rates WHERE ... final String user = "..."; final String pass = "..."; final String url = "jdbc:mysql://localhost/ee"; Class.forName("com.mysql.jdbc.Driver"); Connection con = DriverManager.getConnection(url, user, pass); Statement stm = con.createStatement(); Resultset rs = stm.executeQuery(SQLQuery);

12.2.3 JNDI lookup Connection

Benutzen Sie den Namingservice um über einen lookup die Datenquelle an das Bean anzubinden. Der für den JNDI lookup massgebende Name wird im Deployment Descriptor definiert:

ejbejbejbejb----jar.xmljar.xmljar.xmljar.xml (Ausschnitt)

<resource-ref> <res-ref-name>jdbc/ExchangeTable</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref>

jboss.xmljboss.xmljboss.xmljboss.xml (Ausschnitt)

<resource-ref> <res-ref-name>jdbc/ExchangeTable</res-ref-name> <jndi-name>java:/mySQLDS</jndi-name> </resource-ref>

[JBoss_Home]/server/ee/deploy/mysql[JBoss_Home]/server/ee/deploy/mysql[JBoss_Home]/server/ee/deploy/mysql[JBoss_Home]/server/ee/deploy/mysql----ds.xml ds.xml ds.xml ds.xml (Ausschnitt)

<datasources> <local-tx-datasource> <jndi-name>mySQLDS</jndi-name> <connection-url> jdbc:mysql://localhost:3306/ee </connection-url>

Source Code Ansatz: Source Code Ansatz: Source Code Ansatz: Source Code Ansatz: JNDI lookup Datenbank Connection in MoneyExchangeBean.java

InitialContext ic = new InitialContext(); DataSource ds = (DataSource) ic.lookup("java:comp/env/jdbc/ExchangeTable");

Page 76: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Übung ee5 : Robuste Referenzen auf Stateful Session Beans Seite 76 von total 218 Seiten

13131313 Übung ee5 : Robuste Referenzen auf Stateful Session BeansÜbung ee5 : Robuste Referenzen auf Stateful Session BeansÜbung ee5 : Robuste Referenzen auf Stateful Session BeansÜbung ee5 : Robuste Referenzen auf Stateful Session Beans

13.1 Handles

Handles definieren robuste Referenzen auf Instanzen, die man zwischen Maschinen (netzwerkfähig) austauschen kann :

- persistent (dauerhaft)

- transferable (verschiebbar)

- serializable (in nachfolgende Packete zerlegbar)

- provided by the container (vom Kontainer des Applikationservers zur Verfügung gestellt)

- consists of just one method, that returns the Home / Remote Interface (enthält nur eine einzige Methode mit dem Home / Remote Interface als Returnwert)

- guaranteed to work across client JVM's and server (Plattformunabhängig)

Class DefinitionClass DefinitionClass DefinitionClass Definition

package javax.ejb;

public interface Handle extends Serializable { public EJBObject getEJBObject() throws RemoteException; }

package javax.ejb;

public interface HomeHandle extends Serializable { public EJBHome getEJBHome() throws RemoteException; }

Creating / Storing a Handle am Beispiel eines HomeHandleCreating / Storing a Handle am Beispiel eines HomeHandleCreating / Storing a Handle am Beispiel eines HomeHandleCreating / Storing a Handle am Beispiel eines HomeHandle

Home home = ... HomeHandle home_handle = home.getHomeHandle();

ObjectOutputStream oos = new ObjectOutptStream( new FileOutputStream ( new File("myHomeHandle.ser")));

oos.writeObject(home_handle); oos.close();

Using a Handle am Beispiel eines HomeHandleUsing a Handle am Beispiel eines HomeHandleUsing a Handle am Beispiel eines HomeHandleUsing a Handle am Beispiel eines HomeHandle

ObjectInputStream ois = new ObjectInputStream( new FileInputStream("myHomeHandle.ser")); ois.close();

HomeHandle home_handle = (HomeHandle)ois.readObject();

Object obj = home_handle.getEJBHome(); Home home = (Home)PortableRemoteObject.narrow( obj, Home.class);

Für den Handle des Remote Objectes ist die Anwendung analog, anstelle des HomeHandle tritt das Object Handle. Ob der Handle oder HomeHandle für späteren Beanzugriff persistiert wird ist von der Applikations und der Zugriffslogik abhängig.

Page 77: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Übung ee5 : Robuste Referenzen auf Stateful Session Beans Seite 77 von total 218 Seiten

13.2 Kontoführung mit Stateful Session Bean

Entwickeln Sie eine triviale Kontoführung realisiert mit einer Stateful Session Bean. Um mehrere Konten parallel führen zu können sollen die entsprechenden Handels der EJB-Referenzen dienen.

Führen Sie für mehrere "Kunden" individuelle Konten, die es erlauben einen :

- Betrag zu deponieren (als Float)

- Betrag abzuheben (als Float)

- Saldo auszugeben (auf der Konsole)

1. Deklarieren Sie die verschiedenen Business-Methoden im Remote Interface und definieren

Sie diese in der Bean Klasse.

2. Konzipieren Sie ein Client-Testprogramm um Ihre Applikation zu testen.

3. Ergänzen Sie die Bean Methoden mit Konsolen Statements System.out.println zur Überwachung der Aktivitäten des AS. Überprüfen Sie die entsprechende LOG-Datei.

4. Definieren Sie einen Zinssatz für alle Ihre "Kunden". Der Zinssatz ist für alle Konten gleich. Suchen Sie nach einer geeigneten Möglichkeit um den Zinssatz ändern zu können. Implementieren und Überprüfen Sie Ihre Wahl.

13.2.1 Bean Identität mit Handle speichern

Um in der Client-Applikation mehrere Konten parallel zu führen kann die getHandle Methode benützt werden.

Definieren Sie individuelle Konten der Klasse Handle:Definieren Sie individuelle Konten der Klasse Handle:Definieren Sie individuelle Konten der Klasse Handle:Definieren Sie individuelle Konten der Klasse Handle:

private static Handle handle_1; private static Handle handle_2; private static Handle handle_3;

Erzeugen Sie das Home ObjeErzeugen Sie das Home ObjeErzeugen Sie das Home ObjeErzeugen Sie das Home Objekt:kt:kt:kt:

private static AutomaticTellerHome erzeugeHomeObjekt() throws NamingException { InitialContext ctx = new InitialContext(getInitialProperties()); Object ref = ctx.lookup("account"); home = (AutomaticTellerHome) PortableRemoteObject.narrow( ref,AutomaticTellerHome.class); return home; }

Erzeugen Sie für jeden Account eine eigene Bean-Instanz mit der create Methode. Benützen Sie die getHandle Methode des Remote Interfaces um die Bean Instanzen zu "sichern":

BeanBeanBeanBean----Insanz:Insanz:Insanz:Insanz:

public static Handle erstelleAccount(AutomaticTellerHome home) throws CreateException, RemoteException { AutomaticTeller at = home.create(); return at.getHandle(); }

Page 78: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Übung ee5 : Robuste Referenzen auf Stateful Session Beans Seite 78 von total 218 Seiten

Um die Business-Methoden auf den individuellen Accounts ausführen zu können, brauchen Sie den richtigen "Handle"; diesen bekommen Sie, indem Sie auf dem entsprechenden Handle Objekt die getEJBObjekt Methode aufrufen.

Erstellen Sie ein Methode getRemoteObjekt, die das für Sie erledigt.

getRemoteObjektgetRemoteObjektgetRemoteObjektgetRemoteObjekt

private static AutomaticTeller getRemoteObjekt(Handle handle) throws RemoteException { return (AutomaticTeller) javax.rmi.PortableRemoteObject .narrow(handle.getEJBObject(), AutomaticTeller.class); }

Testen Sie nun Ihre "Bank", indem Sie auf den bereitgestellten Konten individuelle Beträge buchen und abheben.

13.2.2 Handle persistent in Datei speichern

Speichern Sie die Handle mit Hilfe eines FileOutputStream Objektes in eine Datei und lesen Sie diese in einer anderen Client-Applikation wieder aus. Testen Sie Ihre Applikation.

Page 79: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Übung ee6 : EJB QL (CMP 2.0) Seite 79 von total 218 Seiten

14141414 Übung ee6 : EJBÜbung ee6 : EJBÜbung ee6 : EJBÜbung ee6 : EJB QL (CMP 2.0) QL (CMP 2.0) QL (CMP 2.0) QL (CMP 2.0)

Um die Funktionsweise der Suchmethoden des Home-Inteface zu erläutern ist eine kurze Betrachtung der EJB Querry Language erforderlich.

14.1 EJB QL

findXYZ: findXYZ: findXYZ: findXYZ:

Bei CMP muss die Methode findByPrimaryKey immer deklariert werden, jedoch wird sie durch die Bean-Klasse nicht implementiert. Weitere Methoden findBy... (das By ist eine Namenskonvention) dürfen deklariert werden und werden ebenfalls nicht implementiert. Ihr Ergebnistyp ist das (local oder remote) Remote-Interface oder eine java.util.Collection davon.

public Name findByPrimaryKey(String id) throws FinderException, RemoteException;

public Collection findByName(String name) throws FinderException, RemoteException;

Zu jeder findBy...-Methode (ausgenommen findByPrimaryKey) muss es einen entsprechenden Eintrag im Deployment-Descriptor geben:

ejbejbejbejb----jar.xml (Ausschnitt Finder QL)jar.xml (Ausschnitt Finder QL)jar.xml (Ausschnitt Finder QL)jar.xml (Ausschnitt Finder QL)

<entity> ... <persistence-type>Container</persistence-type> ... <abstract-schema-name>...</abstract-schema-name> ... <primkey-field>...</primkey-field> <query> <query-method> <method-name>findBy...</method-name> <method-params> <method-param>Type</method-param> ... </method-params> </query-method> <ejb-ql> SELECT ... FROM ... WHERE ... </ejb-ql> </query> ... </entity>

Zu jedem Parameter wird die entsprechende Java-Klasse/Schnittstelle angegeben. Wenn es keine Parameter gibt, gibt es keine method-param Tags. Der Eintrag (Tag) method-params bleibt jedoch erhalten.

Page 80: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Übung ee6 : EJB QL (CMP 2.0) Seite 80 von total 218 Seiten

selectXYZ: selectXYZ: selectXYZ: selectXYZ:

Solche Methoden sind nur bei CMP zulässig. Sie werden nicht deklariert (der Name selectXYZ taucht auch nirgendwo auf) und durch abstrakte Methoden in der Entity-Bean implementiert:

CMP Bean KlasseCMP Bean KlasseCMP Bean KlasseCMP Bean Klasse

public abstract AnwendungBean implements EntityBean { ... public abstract Type ejbSelectXYZ(...) throws FinderException; ... }

Type ist hier deutlich flexibler als bei den findXYZ-Methoden: Neben dem Remote-Interface ist jeder beliebige (serialisierbare) Java-Typ zulässig, so dass man auch Attributwerte zurückliefern kann, und neben java.util.Collection ist auch java.util.Set möglich. Die ejbSelectXYZ-Methoden ihrerseits werden durch einen Eintrag query im Deployment-Descriptor beschrieben, genau wie die findXYZ-Methoden.

Die EJB QL selbst ist eine kleine Untermenge von SQL. Eine Abfrage SELECT ... FROM ... WHERE ... besteht aus folgenden Teilen:

SELECT: : : :

Optional darf DISTINCT folgen. Hier steht ein Ausdruck, der keine Operatoren enthalten darf. Abgesehen von Aggregatfunktionen (seit EJB 2.1) COUNT, SUM, AVG, MIN, MAX besteht der Ausdruck aus einem Pfad der Form a, b, c, der einen einzelnen Wert liefert und dessen Bestandteile einzelne Objekte sind. Steht hier eine einzelne Tabelle t aus der FROM-Klausel, muss OBJECT(t) resultieren.

FROM: : : :

Hier steht eine (durch Komma getrennte) Liste von Tabellen (bzw. abstrakten Schemata) der Form Table AS t und Aufzählungen der Form IN (Collection) AS c. Das Schlüsselwort AS darf entfallen. Collection darf ein Pfad wie bei SELECT sein, der jetzt aber keinen einzelnen Wert liefern darf. Die eingeführten Bezeichner (hier t bzw. c) werden in nachfolgenden Listenelementen bei FROM sowie bei SELECT und WHERE verwendet.

WHERE (optional): (optional): (optional): (optional):

Hier steht eine Bedingung mit den üblichen Operatoren NOT, AND, OR; =, <>, <, <=, >, >= (Vorsicht mit XML!), [NOT] BETWEEN, [NOT] IN, [NOT] LIKE, IS [NOT] NULL, IS [NOT] EMPTY, [NOT] MEMBER OF (IS EMPTY und MEMBER OF fragen Collections ab); +, -, *, /. Zahlen, Zeichenketten (in einfachen Anführungszeichen) und Mengen (in runden Klammern) können verwendet werden. An Funktionen gibt es CONCAT, LENGTH, LOCATE, SUBSTRING, ABS, SQRT und MOD. Die Parameter einer findXYZ- oder ejbSelectXYZ-Methode werden durch ?1, ?2, ... angesprochen.

Page 81: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Übung ee6 : EJB QL (CMP 2.0) Seite 81 von total 218 Seiten

ORDER BY (optional): (optional): (optional): (optional):

(seit EJB 2.1) Hier steht ein Pfadausdruck der Form a, b, c, der direkt vom SELECT-Ausdruck abhängen muss, gefolgt von ASC (Voreinstellung) oder DESC.

BeispielBeispielBeispielBeispiel

public Collection<Customer> findAll() throws RemoteException,FinderException; public Collection<Customer> findByComputerCount(int computerCount) throws RemoteException, FinderException;

resultiert in:

SELECT OBJECT (c) FROM Customer c SELECT OBJECT (c) FROM Customer c WHERE c.computerCount >= ?1

14.2 Primary Key Klasse

Die Primary Key Klasse ist nur für Entity Beans notwendig. Sie kapselt die Felder, die den Primary Key der Datenbank repräsentieren in einem eigenen Objekt. Ist der Primary Key in der Datenbank durch ein einzelnes Feld mit einem Basic Datentyp konzipiert, so darf der Primary Key im Bean als Standard Java Klasse (z.B: java.lang.Integer oder java.lang.String) definiert sein. Natürlich müssen die Datenfelder typengleich sein. (Primitive Datentypen wie int, float oder boolean sind nicht möglich). Dabei wird die Klasse des Primary Keys und bei CMP das entsprechende Feld im Deployment Descriptor definiert:

<prim-key-class>java.lang.Integer</prim-key-class> <primkey-field>id</primkey-field>

Die Alternative ist eine eigene PrimaryKeyClass zu definieren. Die Klasse muss serializable sein und Implementationen der Methoden hashcode() and equals(Object)definieren.

Für CMP sind die folgenden Punkte massgebend:

- Die Felder der Primary Key Klasse müssen als public deklariert werden.

- Die Primary Key Klasse muss einen Default Konstruktor haben.

- Die Namen der Felder der Primary Key Klasse müssen Teil der CMP Felder der Bean Klasse sein.

Beispiel einer PrimaryKeyKlaBeispiel einer PrimaryKeyKlaBeispiel einer PrimaryKeyKlaBeispiel einer PrimaryKeyKlassessessesse

public class PersonBeanPK implements java.io.Serializable { public int id; public PersonBeanPK(int id) { this.id = id; } public PersonBeanPK() { }

public int hashcode() { return id; } public boolean equals(Object other) { ... }

Page 82: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Übung ee6 : EJB QL (CMP 2.0) Seite 82 von total 218 Seiten

14.3 ProductShop

Entwickeln und Testen Sie einen ProductShop mit einer CMP 2.0 Entity Bean, die auf eine mySQL DB mit den Feldern "productID" und "name" und "price" zugreift. Realisieren Sie eine PrimaryKeyKlasse, die das Datenbankfeld "productID" repräsentiert.

Definieren Sie entsprechende Finder Methoden wie:

- findByName

- findAllProducts

Ansatz:Ansatz:Ansatz:Ansatz:

findByName Methode im ProductHome Interface:

public Collection findByName(String name) throws FinderException, RemoteException;

entsprechendes <query> tag im Deployment Descriptor ejb-jar.xml

<query> <query-method> <method-name>findByName</method-name> <method-params> <method-param>java.lang.String</method-param> </method-params> </query-method> <ejb-ql> SELECT OBJECT(a) FROM ProductBean As a WHERE a.name = ?1</ejb-ql> </query>

Erstellen einer XML Datei (Deployment Descriptor), mit der Sie das Datenbankmapping definieren. Diese Datei ergänzt die Einstellungen der Datei standardjbosscmp-jdbc.xml im \conf Verzeichnis des aktuellen Server:

jbosscmpjbosscmpjbosscmpjbosscmp----jdbc.xmljdbc.xmljdbc.xmljdbc.xml

<jbosscmp-jdbc> <defaults> <datasource>java:/DefaultDS</datasource> <datasource-mapping>mySQL</datasource-mapping> <create-table>true</create-table> <remove-table>true</remove-table> </defaults> <enterprise-beans> <entity> <ejb-name>Product</ejb-name> <table-name>ProductTable</table-name> </entity> </enterprise-beans> </jbosscmp-jdbc>

Page 83: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Übung ee6 : EJB QL (CMP 2.0) Seite 83 von total 218 Seiten

14.3.1 Summe aus allen Produkten

Soll das Total des "Warenkorbes" bestimmt werden, so können mit der getPrice Methode des Remote Interfaces die Preise mittels Iteration summiert werden:

Summe aller ProdukteSumme aller ProdukteSumme aller ProdukteSumme aller Produkte

double sum = 0; Iterator i = home.findAllProducts().iterator();

while (i.hasNext()) { Product prod = (Product) PortableRemoteObject.narrow(i.next(),Product.class); sum += prod.getPrice(); } System.out.println("Summe aller Produkte: " + sum);

Die Methode getPrice ist eine treue Operation und bei grossen Datenbeständen ist diese Variante nicht sehr sinnvoll. Als Alternative sollen die Preise der Produkte im EJB Container summiert werden. Dazu bauen wir die Methode getAllPriceTotal() und fügen unserem EJB Local Interfaces hinzu für einen lokalen Zugriff innerhalb des EJB Kontainers:

neue Finder Methode im Home Interface

public double getAllPriceTotal() throws RemoteException;

Alle Methoden des Home Interface müssen durch eine entsprechende MethodenSignature in der Bean Klasse vertreten sein (analog create(...) Methoden).

Die getHomeAllPriceTotal() Methode könnte folgendermassen aussehen:

getHomeAllPriceTotagetHomeAllPriceTotagetHomeAllPriceTotagetHomeAllPriceTotal() Methode in der Bean Implementationl() Methode in der Bean Implementationl() Methode in der Bean Implementationl() Methode in der Bean Implementation

public double ejbHomeGetAllPriceTotal() { double sum = 0.0; try { Collection c = this.ejbSelectAllPrices(); Iterator i = c.iterator(); while (i.hasNext()) { sum += ((ProductLocal) i.next()).getPrice(); } } catch (Exception e) { … } return sum; }

entsprechende <query> im ejbentsprechende <query> im ejbentsprechende <query> im ejbentsprechende <query> im ejb----jar.xml Deployment Descriptorjar.xml Deployment Descriptorjar.xml Deployment Descriptorjar.xml Deployment Descriptor

<query> <query-method> <method-name>ejbSelectAllPrices</method-name> <method-params></method-params> </query-method> <result-type-mapping>Local</result-type-mapping> <ejb-ql> SELECT OBJECT(p) FROM ProductBean As p </ejb-ql> </query>

Die Local Interfaces sind identisch zu den [Remote]Interfaces mit dem Unterschied, dass die Local Interfaces keine RemoteExceptions werfen, da sie ja "nur" einen lokalen Zugriff machen.

Page 84: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Übung ee62 : PersonBean mittels BMP Entity Bean Seite 84 von total 218 Seiten

15151515 Übung ee62 : PersonBean mittels BMP Entity BeanÜbung ee62 : PersonBean mittels BMP Entity BeanÜbung ee62 : PersonBean mittels BMP Entity BeanÜbung ee62 : PersonBean mittels BMP Entity Bean

15.1 BMP – Bean Managed Persistence

Entity Beans kapseln Datenbankinhalte durch Objekte, die gemäss der EJB-Spezifikation instanziierbar und zugreifbar sind. Die Verwaltung der gekapselten Dateninhalte erfolgt durch ein frei festlegbares Datenbankmanagementsystem, die Verwaltung der Objekte selbst durch den EJB-Container.

Ziel dieser Technik ist es die Komplexität der Persistenzlogik für den Verwender der bereitgestellten Bean vollkommen transparent zu gestalten und serverseitig zu realisieren. Die Familie der Entity Beans selbst zerfällt in zwei Untertypen, welche sich entlang des Realisierungspunktes der Persistenzlogik separieren:

Bean Managed PersistenceBean Managed PersistenceBean Managed PersistenceBean Managed Persistence

Dem Bean obliegt die Umsetzung der Persistenzlogik

Container Managed PersistenceContainer Managed PersistenceContainer Managed PersistenceContainer Managed Persistence

Die Persistenzlogik wird durch den EJB-Container realisiert

Wie bereits für die Realisierung von Session Beans eingeführt, werden auch zur Publikation der extern zugänglichen Schnittstellen Home und Remote Interfaces benötigt. Dieser Schnitt-stellentyp dient auch Entity Beans zur Aufnahme der Verwaltungsoperationen zur Erzeugung (create) und zur Suche existierender (findByPrimaryKey) EJBs.

Home InterfaceHome InterfaceHome InterfaceHome Interface

Die HomeHomeHomeHome----SchnittstelleSchnittstelleSchnittstelleSchnittstelle zeigt die create-Operation zur Erzeugung einer neuen EJB-Instanz. Ihre Übergabeparameter dienen zur Konstruktion des neuen Objekts und werden durch die Bean-Implementierung interpretiert. Ferner enthält die Schnittstelle mit findByPrimaryKey eine Operation deren Implementierung eine Entity-Bean anhand ihres Primärschlüssels identifiziert und liefert. Aus diesem Grunde erhält die Methode den zu suchenden Wert vom Typ des Primärschlüssels als Parameter.

Hinsichtlich der verwendeten Typen zeigt sich bereits hier, dass eine Abbildung der Java Typen auf die des eingesetzten Persistenzsystems stattfinden muss. Bei BMP wo die EJB selbst die Persistenz verwalten muss ist diese Abbildung manuell durch den Programmierer bereitzustellen.

Remote InterfaceRemote InterfaceRemote InterfaceRemote Interface

Die RemoteRemoteRemoteRemote----SchnittstelleSchnittstelleSchnittstelleSchnittstelle gibt die für Nutzer der Bean zugänglichen Geschäftsfunktionen wieder. Daher enthält dieser Schnittstellentyp lediglich Operationen zum Zugriff auf die verwalteten Daten, nicht jedoch zur technischen Verwaltung und Interaktion mit dem Bean-Container.

Page 85: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Übung ee62 : PersonBean mittels BMP Entity Bean Seite 85 von total 218 Seiten

Per Konvention muss diese Schnittstelle als Spezialisierung der Schnittstelle EJBObject definiert sein. Diese Standardschnittstelle definiert allgemeine Interaktionsformen, wie:

- Löschen (remove)

- Vergleich (isIdentical)

- Ermittlung des Primärschlüsselwertes (getPrimaryKey)

- Vergleich zweier serverseitiger EJB-Objekte (isIdentical)

- Wert des Primärschlüssels (getPrimaryKey)

Zur Löschung von datenbankresistenten Objekten wird remove eingesetzt. Der Aufruf dieser Methode entfernt ausschliesslich die durch die EJB repräsentierten Datenbanktupel, die programmiersprachliche Objektrepräsentation bleibt jedoch über die gesamte Laufzeit (sofern nicht durch Gültigkeitsbereiche oder explizite NULL-Setzung explizit anders gehandhabt) intakt.

15.2 BMP Person Bean

Erstellen Sie eine Entity Bean zur Personenverwaltung mit Bean Managed Persistence. Jedes Personen-Objekt enthält Daten zu Name, Geburtsdatum und Wohnort. Der Name dient als eindeutige Identifikation und daher datenbankseitig als Primärschlüssel. Die notwendige Datenbanktabelle wird durch folgenden SQL-Ausdruck erzeugt:

CREATE TABLE PERSON( Name VARCHAR(20) PRIMARY KEY, Birthdate DATE, City VARCHAR(30));

Ansatz:

create und findByPrimary Methoden im BMPPersonHome Interface:create und findByPrimary Methoden im BMPPersonHome Interface:create und findByPrimary Methoden im BMPPersonHome Interface:create und findByPrimary Methoden im BMPPersonHome Interface:

public interface BMPPersonHome extends EJBHome { public Person create(int year, int month, int day, String name, String city) throws CreateException, RemoteException; public Person findByPrimaryKey(String name) throws FinderException, RemoteException; }

einige Business Methoden:einige Business Methoden:einige Business Methoden:einige Business Methoden:

public interface Person extends EJBObject { public int getAge() throws RemoteException; public String getCity() throws RemoteException; public void setCity(String city) throws RemoteException;

Die mit getAge in der Remote-Schnittstelle veröffentlichte Operation soll keinen direkt abgespeicherten Wert liefern, sondern diesen dynamisch zur Ausführungszeit anhand der verfügbaren Daten berechnen.

Page 86: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Übung ee62 : PersonBean mittels BMP Entity Bean Seite 86 von total 218 Seiten

spezifische Business Methodespezifische Business Methodespezifische Business Methodespezifische Business Methode

public int getAge() { return (new GregorianCalendar().get(Calendar.YEAR) - birthdate.get(Calendar.YEAR));

Innerhalb der datenbankzugreifenden Methoden muss durch den Anwender die Abbildung der Java-Datentypen auf die des verwendeten Datenbankmanagementsystems erfolgen. Die mit dem Präfix ejb versehenen Methoden zeigen dies für die lesenden und schreibenden DB-Zugriffe. So kann die im Beispiel für name und city verwendete Java-Repräsentation String vergleichsweise leicht in den SQL-Typ VARCHAR abgebildet werden sofern alle Methoden sicherstellen, dass nur konforme Werte eingefügt werden.

Exemplarisch soll das mit den Methoden ejbCreate und setCity gezeigt werden.

setStreetsetStreetsetStreetsetStreet

public void setCity(String city) throws RemoteException { if (city.length() <= 30) { this.city = city; } else { throw new RemoteException("cannot update city"); } }

Für programmiersprachliche Typen, die nicht direkt in DB-Typen abbildbar sind, muss im Falle der Bean Managed Persistence der Bean-Entwickler selbst Sorge für die adäquate Abbildung tragen. Der Java-Datumstyp GregorianCalendar soll manuell in die durch das DBMS erwartete ISO 8601-konforme Darstellung überführt werden.

Datumstyp UmrechnungDatumstyp UmrechnungDatumstyp UmrechnungDatumstyp Umrechnung

public String ejbCreate(int y,int m,int d,String name,String city) throws CreateException {

this.name = name; this.birthdate = new GregorianCalendar(y, m, d); this.street = street; Statement stmt = getStatement(); // open DBMS Connection and return stmt String s = new String("INSERT INTO PERSON VALUES ('" + name + "','" + birthdate.get(Calendar.YEAR) + "-" + birthdate.get(Calendar.MONTH) + "-" + birthdate.get(Calendar.DATE) + "'," + "'" + street + "'" + ");"); try { stmt.executeUpdate(s); } catch (SQLException e) { e.printStackTrace(); } } else { throw new CreateException("Invalid values supplied"); } return name; }

Page 87: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Übung ee62 : PersonBean mittels BMP Entity Bean Seite 87 von total 218 Seiten

Analog zur ejbCreate Methode ist der Bean Provider verantwortlich für die Existenz der ejbRemove, ejbStore, ejbFindByPrimaryKey Methoden. Zusätzlich zu allen notwendigen Bean Life-Cycle Methoden können sämtliche Business Methoden mitverwaltet werden.

Business MethodenBusiness MethodenBusiness MethodenBusiness Methoden

public int ejbHomeGetAge() { return 0; }

public String ejbHomeGetCity() { return new String(); }

Ansatz für den Client CodeAnsatz für den Client CodeAnsatz für den Client CodeAnsatz für den Client Code

Person p1 = home.create(1981, 1, 1, "Leonie", "cityA"); Person p2 = home.create(1972, 2, 2, "Lukas", "cityB"); System.out.println("Leonies Alter: " + p1.getAge()); System.out.println("Leonies PK : "+p1.getPrimaryKey()); p1.remove(); Person p3 = home.findByPrimaryKey("Lukas"); System.out.println("Lukas wohnt in : " + p3.getCity()); p3.setCity("cityC"); System.out.println("Lukas neuer Wohnort: " + p3.getCity()); System.out.println("Lukas alter Wohnort: " + p2.getCity()); System.out.println("sind p2 und p3 das gleiche Java Objekt ? " + (p2==p3)); System.out.println("Sind p2 und p3 das gleiche EJBObject ? " + p2.isIdentical(p3));

Überlegen Sie sich wie die Ausgabe aussieht bevor Sie Ihre Applikation testen !

Output:Output:Output:Output:

Leonies Alter: ___

Leonies PK: ______

Lukas wohnt in: ________

Lukas neuer Wohnort: ________

Lukas alter Wohnort: ________

sind p2 und p3 das gleiche Java Objekt ? ________

Sind p2 und p3 das gleiche EJBObject ? ________

Page 88: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Übung ee62 : PersonBean mittels BMP Entity Bean Seite 88 von total 218 Seiten

ejbejbejbejb----jar.xml (Ausschnitt)jar.xml (Ausschnitt)jar.xml (Ausschnitt)jar.xml (Ausschnitt)

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN' 'http://java.sun.com/dtd/ejb-jar_2_0.dtd'> <ejb-jar> <display-name>Ejb1</display-name> <enterprise-beans> <entity> <display-name>PersonBean</display-name> <ejb-name>PersonBean</ejb-name> <home>beans.PersonHome</home> <remote>beans.Person</remote> <ejb-class>beans.PersonBean</ejb-class> <persistence-type>Bean</persistence-type> <prim-key-class>java.lang.String</prim-key-class> <reentrant>False</reentrant> <security-identity> <description></description> <use-caller-identity></use-caller-identity> </security-identity> </entity> </enterprise-beans> … <assembly-descriptor> <container-transaction> <method> <ejb-name>PersonBean</ejb-name> <method-intf>Home</method-intf> <method-name>create</method-name> <method-params> <method-param>int</method-param> <method-param>int</method-param> <method-param>int</method-param> <method-param>java.lang.String</method-param> <method-param>java.lang.String</method-param> </method-params> </method> <trans-attribute>Never</trans-attribute> </container-transaction> … </assembly-descriptor> </ejb-jar>

Page 89: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Servlets Seite 89 von total 218 Seiten

16161616 ServletsServletsServletsServlets

16.1 Vor- und Nachteile dynamischer Web-Inhalte

Es existieren eine Reihe von Lösungen zur Darstellung aktueller (dynamischer) und nutzerspezifischer Daten im Internet, welche sich im Hinblick auf Erstellungs- und Wartungsaufwand sowie in der Performance bei der Bereitstellung von Daten unterscheiden:

- Statische, häufig aktualisierte HTML-Seiten sind eine sehr leistungsfähige Lösung. Jedoch ist der Aktualisierungs- und Wartungsaufwand nicht vertretbar. Eine individuelle Datenpräsentation für jeden Nutzer ist nicht möglich.

- Eine weit verbreitete Lösung sind Server-basierte Programme wie CGI (Common Gateway Interface), die dynamische HTML-Seiten generieren. Diese bieten eine gute Performance, wenn sie nativ (in Maschinencode) implementiert sind, und erlauben eine Datenbankanbindung. Die Performance ist jedoch gering, wenn sie in Skriptsprachen (z.B. Perl) realisiert sind. Das Ablaufen von CGI-Programmen in eigenen Prozessen erzeugt einen hohen Ressourcenverbrauch (Speicher, Ausführungszeit).

- Web-Server-Erweiterungen stellen eine weitere Variante dar, dynamische HTML-Inhalte zu erzeugen, z.B. durch das ISAPI von Microsoft und das NSAPI von Netscape. Diese ermöglichen ebenfalls eine Datenbankanbindung, haben aber den entscheidenden Nachteil, dass sie nicht portabel sind.

- Eine gute Integration mittels Java bietet die Lösung über Applets. Sie ermöglichen eine gute Wartung, besitzen aber wiederum den Nachteil, dass nicht alle Browser Applets voll unterstützen bzw. nur eine bestimmte Version.

- Servlets stellen häufig eine bessere Alternative zu den vorgestellten Technologien dar, um Daten im Internet oder Intranet dynamisch bereitzustellen. Sie bieten die folgenden Vorteile:

- Web-Browser-unabhängig, da die einzige Voraussetzung auf der Client-Seite die Unterstützung von HTML ist (JavaScript unter anderem kann bei Bedarf auch genutzt werden)

- Schnelle Bereitstellung auf der Serverseite, da Servlets innerhalb eines Prozesses als Thread ablaufen und so lange im Server bleiben (persistent), bis sie explizit entfernt werden

- Sichere Verarbeitung, da sie nur innerhalb eines Prozesses ablaufen

- Plattformunabhängiger Einsatz, da Servlets in Java entwickelt werden

16.2 Grundlagen

Über das Java Servlet API, welches unter anderem durch die J2EE installiert wird, können Sie Servlets entwickeln, die dynamische Web-Inhalte zur Verfügung stellen. Servlets können ausser HTML z.B. auch XML, WML, Bild- oder PDF-Dateien bereitstellen. Prinzipiell ist jedes Datenformat als Rückgabe möglich. Da Servlets in Java implementiert werden, können Sie z.B. über JDBC Informationen aus Datenbanken verarbeiten.

16.3 Funktionsweise

Als Client wird ein Web-Browser genutzt. Die benötigten Fähigkeiten des Browsers hängen von der vom Servlet erzeugten Ausgabe ab. So kann ein Servlet reinen HTML-Code nach dem HTML-Standard 2.0 erzeugen, aber auch HTML-Code, der zusätzlich Java Script, CSS Style Sheets und dynamisches HTML enthält.

Über den Web-Browser gibt der Client einen URL an, der ein Servlet auf einem Web-Server startet. Die Anfrage wird zuerst vom Web-Server entgegengenommen. Dieser erkennt, dass es

Page 90: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Servlets Seite 90 von total 218 Seiten

Web-Browser

Servlet-Engine

Web-Server

Applications

JVM

Servlet basierter Webserver

Prozess

Auftrag A

Auftrag B Servlet B

Servlet A

Servlet C Auftrag C

sich um ein Servlet handelt und leitet die Anfrage des Clients an dieses weiter. Das Servlet wertet übergebene Parameter aus und erzeugt eine Ausgabe, z.B. eine HTML-Seite, die Informationen zu einem bestimmten Software-Produkt enthält. Dieses wird an den Web-Server übergeben, der diese wiederum an den Client weiterleitet. Ändern sich nach dem Aufruf des Servlets Produktdaten, werden die aktualisierten Daten bei der nächsten Anforderung verwendet.

Die HTML-Seite wird damit dynamisch erstellt (bei Bedarf) und enthält immer die zu diesem Zeitpunkt aktuellsten Informationen.

http "pull"

HTML

Der Teil des Web-Servers, der für die Abarbeitung der Servlets zuständig ist, wird häufig auch als Servlet-Engine oder Servlet-Container bezeichnet. Durch die Integration eines Servlets in diesen Container wird es automatisch über die Servlet-Engine dem Web-Server zur Verfügung gestellt und kann von Clients genutzt werden.

16.4 Lebenszyklus

Container Shutdown started destroy Methode

Beim ersten Servlet Aufruf erstellt der Container das Servlet und ruft die init Methode auf Container ruft die service Methode auf, übergibt die Request Parameter und erneuert (leert) das Response Objekt.

Für jeden neuen Auftrag wird ein neuer Thread erzeugt, der das betreffende Servlet ausführt. Die Threads laufen alle in der gleichen JVM innerhalb des gleichen Prozesses. Dadurch können sie relativ einfach miteinander kommunizieren, und die Verarbeitung von Client-Anfragen ist durch leichtgewichtige Prozesse (Threads) nicht sehr ressourcenaufwendig.

Web-Server

Start

Process Requests

Destroy

Page 91: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Servlets Seite 91 von total 218 Seiten

16.5 Übung ee7 : Servlet – ein Beispiel

Erstellen eines Trivial-Servlets, das einen HTTP Response (Response von Tomcat Web-Server) erzeugt. Erstellen Sie dazu ein TOMCAT Java Project. Das entsprechende Plugin muss dazu installiert sein. Die Installationsanleitung ist im Anhang zu finden.

Wenn durch das Plugin ein TOMCAT Projekt erzeugt wird ist die Verzeichnisstruktur vorgegeben und ein entsprechendes "src" Verzeichnis und ein Verzeichnis für den build-Path "WEB-INF/classes" bereitgestellt.

Erstellen Sie in einer Packagestruktur \mypackage die Servlet Java Klasse HelloServlet.java und leiten Sie diese von der Superklasse HttpServlet ab:

@inRequest Parameters send vom Client (Browser) @inRespons HTML sent to Client (Browser)

Erzeugen Sie eine neue Klasse und definieren Sie die service Methode: Erzeugen Sie eine neue Klasse und definieren Sie die service Methode: Erzeugen Sie eine neue Klasse und definieren Sie die service Methode: Erzeugen Sie eine neue Klasse und definieren Sie die service Methode:

public class HelloServlet extends HttpServlet {

public void service( HttpServletRequest inRequest, HttpServletResponse inResponse) throws IOException, ServletException { ... } }

Instanzieren Sie innerhalb der Service Methode ein ResponseWrite Object:Instanzieren Sie innerhalb der Service Methode ein ResponseWrite Object:Instanzieren Sie innerhalb der Service Methode ein ResponseWrite Object:Instanzieren Sie innerhalb der Service Methode ein ResponseWrite Object:

Writer aResponseWriter = inResponse.getWriter();

Spezifizieren Sie den Inhalt als HTML Code:Spezifizieren Sie den Inhalt als HTML Code:Spezifizieren Sie den Inhalt als HTML Code:Spezifizieren Sie den Inhalt als HTML Code:

inResponse.setContentType("text/html");

Erzeugen Sie die gewünschten HTML Seiten folgendermassen:Erzeugen Sie die gewünschten HTML Seiten folgendermassen:Erzeugen Sie die gewünschten HTML Seiten folgendermassen:Erzeugen Sie die gewünschten HTML Seiten folgendermassen:

aResponseWriter.write(<HTML CODE>);

Page 92: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Servlets Seite 92 von total 218 Seiten

Ersetzen Sie dabei denErsetzen Sie dabei denErsetzen Sie dabei denErsetzen Sie dabei den <HTML CODE> durch die gewünschten HTML Statements und durch die gewünschten HTML Statements und durch die gewünschten HTML Statements und durch die gewünschten HTML Statements und definieren Sie diese als String., z.B:definieren Sie diese als String., z.B:definieren Sie diese als String., z.B:definieren Sie diese als String., z.B:

aResponseWriter.write("<html><head>\n"); aResponseWriter.write("<title>1st Servlet</title>\n"); aResponseWriter.write("<body>\n"); aResponseWriter.write("<h1>My first SampleServlet is working great!</h1>\n"); aResponseWriter.write("</body></html>\n");

Erzwingen Sie den ResponseWriter zur Ausgabe:Erzwingen Sie den ResponseWriter zur Ausgabe:Erzwingen Sie den ResponseWriter zur Ausgabe:Erzwingen Sie den ResponseWriter zur Ausgabe:

aResponseWriter.flush();

web.xml Deployment Descriptor (muss im web.xml Deployment Descriptor (muss im web.xml Deployment Descriptor (muss im web.xml Deployment Descriptor (muss im WEB-INF Verzeichnis sein) Verzeichnis sein) Verzeichnis sein) Verzeichnis sein)

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app> <display-name>Servlet Test Application</display-name> <description>Schreibt eine Begrüssung</description>

<servlet> <servlet-name>Hello</servlet-name> <servlet-class>mypackage.HelloServlet</servlet-class> </servlet>

<servlet-mapping> <servlet-name>Hello</servlet-name> <url-pattern>/start</url-pattern> </servlet-mapping> </web-app>

server.xml im Verzeichnis [TOMCAT_ROOT]server.xml im Verzeichnis [TOMCAT_ROOT]server.xml im Verzeichnis [TOMCAT_ROOT]server.xml im Verzeichnis [TOMCAT_ROOT]\\\\conf conf conf conf

(wird durch das TOMCAT Plugin automatisch bei Erstellen des Eclipse Projektes erstellt)

<Context path="/ee7" reloadable="true" docBase="C:\sbb\workspace\ee71" workDir="C:\sbb\workspace\ee71\work" />

Ausgabe im Browser FensterAusgabe im Browser FensterAusgabe im Browser FensterAusgabe im Browser Fenster

Page 93: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Servlets Seite 93 von total 218 Seiten

16.6 Übung ee71 : Web Browser als EJB Client

Erstellen Sie ein Servlet das alle Produkte der Übung ee6 in einem Browser darstellt. Die Klassen des EJB bleiben unverändert. Einzig die Schnittstelle zwischen Servlet Engine (TOMCAT) und EJB-Kontainer (JBoss) muss erstellt werden. Dazu ist es sinnvoll eine Java Klasse als Bean einzusetzen. Die public Methode getProducts() gibt alle Produkte der EJB als Collection retour:

AnsatzAnsatzAnsatzAnsatz

public Collection getProducts() throws Exception { Collection products = null; try { Context ctx = new InitialContext(); home = (ProductHome) PortableRemoteObject.narrow(ctx.lookup("Product"),ProductHome.class); products = home.findAllProducts(); } catch (Exception e) { } return products; }

Die EJB Bean Klassen sind vorteilhaft im neuen Projekt untergebracht. Die entsprechende Verzeichnisstruktur zeigt alle Source Dateien. Die Client Applikation ProduktClient.java ermöglicht einen direkten Zugriff auf den EJB Kontainer (siehe ee6) während das Bean ProductClientBean.java als Schnittstelle zwischen Servlet und EJB fungiert.

Um der TOMCAT VM den Zugriff auf den (REMOTE) EJB-Kontainer von JBoss zu ermöglichen ist das Archiv jbossall-client.jar vom Verzeichnis [JBoss_Home]/client ins /lib Verzeichnis unterhalb des WEB-INF zu stellen.

Browser AusgabeBrowser AusgabeBrowser AusgabeBrowser Ausgabe

Page 94: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 JSP JavaServer Pages Seite 94 von total 218 Seiten

Web-

JSP-Seite

Web-Server JSP-Engine

Java-Datei (Servlet)

Servlets

17171717 JSP JavaServer PJSP JavaServer PJSP JavaServer PJSP JavaServer Pagesagesagesages

Sun Microsystems hat die JavaServer Pages (JSP) für die Realisierung der Präsentationsschicht einer Webanwendung entwickelt. Sie integrieren Businesskomponenten und existierende Systeme elegant ins Web. Die JSP-Technik basiert auf dem Java-Servlet-API und dient im Wesentlichen zur einfachen Erzeugung von HTML- und XML-Ausgaben eines Webservers. Wie PHP, ASP oder Perl können Autoren direkt HTML oder XML mit einer Skriptsprache mischen. Natürlich hat sich Sun hier für Java entschieden, um so die Möglichkeiten der vorhandenen robusten und zahlreichen Java-APIs einzubringen.

Wie auch Servlets ermöglichen JSP die Erstellung dynamischer Webinhalte mit dem Unterschied das JSP aus statischem HTML und dynamischen JAVA Elementen besteht.

17.1 Grundidee

- Ähnliche Vorgehensweise wie bei Server Side Includes, aber unter Benutzung von Java- Anweisungen.

- Funktionalität und Syntax erinnern an Active Server Pages (ASP).

- Blocks von Servlet Code (Scriptlet) werden in statische HTML- Seiten eingefügt.

17.2 Funktionsweise

http (http)

HTML (HTML)

1. Aufruf compiler *.class HTML

JSP

Eine JSP-Seite ist ein Textdokument und besteht aus:

- HTML- Code

- JSP-Code

- JSP-Tags

- Java Anweisungen

Beim ersten Client Request auf eine JSP Seite analysiert die JSP-Engine des Web-Servers (z.B. Tomcat) das HTML Dokument und erstellt dynamisch ein Servlet. Alle weiteren Client Aufrufe werden dann vom automatisch erstellten Servlet behandelt. Die Umwandlung der JSP-Seite in ein Servlet ist für den Entwickler und auch für den Anwender völlig transparent.

17.3 Organisation

Web Applications sind zusammengehörende Webserver-Programmpakete mit einer definierten Hierarchie-Struktur. Sie werden im Webserververzeichnis \webapps als war Archive gespeichert.

Page 95: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 JSP JavaServer Pages Seite 95 von total 218 Seiten

17.4 Aufbau von JavaServer Pages

17.5 Kommentare

Kommentare, die nicht im generierten File auftauchen sollen, haben folgende Form: <%-- ... JSP- Kommentar... --%>

Beispiel: <%-- Das ist ein JSP Kommentar --%>

17.6 Ausdrücke / Expressions

Eine Expression beginnt mit <%= und endet mit %>.

Jeder Java- Ausdruck in der Expression wird ausgewertet, in einen String konvertiert und der Ergebnistext direkt in die Seite eingefügt.

Eine Expression <%= count %> würde übersetzt in out.println(count); und würde den Inhalt der Variablen count in Textform in die Ergebnisseite einfügen.

BeispielBeispielBeispielBeispiel

<%= "Hallo" %><br> <%= "zwei + drei : " 2 + 3 %><br> <%= new Date() %><br>

Ausgabe:Ausgabe:Ausgabe:Ausgabe: Hallo

zwei + drei : 5

Thu Jan 01 00:08:30 GMT+01:00 2000

JSP-Seite - Ausdrücke - Skriptlets - Deklarationen - Direktiven

Ressourcen - HTML-Datei - JSP-Datei

Datei - ASCII- Datei - JSP-Datei

Tag-Libraries - JSP-Tags

JSP-Seite - Ausdrücke - Skiptlets - Deklarationen - Direktiven

Java Klasse

Java Bean Eigenschaften - setter - getter

Page 96: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 JSP JavaServer Pages Seite 96 von total 218 Seiten

17.7 Direktiven

Direktiven sind Informationen für die JSP Engine, um die Auswertung der JSP-Seite zu steuern. Eine Direktive hat die Form einer Variablenzuweisung: <%@ type varname=“value“ %>.

- includeincludeincludeinclude- Direktiven, um Inhalte anderer Dateien einzufügen: <%@ include file=“head.jsp“ %>

- pagepagepagepage- Direktiven zur Kontrolle bestimmter Aspekte des Servlets: <%@ page content-type=“text/plain“ %>

- contentcontentcontentcontent---- type type type type: definiert den Content-Type der erzeugten Seite. Default: “text/ html”:

<%@ page content-type=“text/plain” %>

- importimportimportimport: übergibt eine kommaseparierte Liste der Importe: <%@ page import=“java.io.*,java.util.*” %>

- extendsextendsextendsextends: spezifiziert die Elternklasse des Servlets: <%@ page extends=“MyHttpServlet” %>

- implementsimplementsimplementsimplements: übergibt eine kommaseparierte Liste der Interfaces: <%@ page implements=“Serializable”%>

- methodmethodmethodmethod: Spezifiziert die Servletmethode, die den generierten Code enthalten und Client- Requests behandeln soll. Default: “service”:

<%@ page method=“doPost”%>

- languagelanguagelanguagelanguage: Spezifiziert die Back-End Scriptsprache Default: “java”: <%@ page language=“java”%>

Beispiel:Beispiel:Beispiel:Beispiel:

<%@ page language="java" info="JSP Beispiel" %> <%@ page import="java.util.*" %> <%@ include file="mein_eigenes.jsp" %>

17.8 Deklarationen

Deklarationen dienen zur Definition von Methoden und Attributen. Sie werden durch ein Tag <%! ... Deklaration... %> definiert.

Beispiel:Beispiel:Beispiel:Beispiel:

<%! int i = 0 %> <%! private int getNextInt() { i++; return i; } %>

Page 97: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 JSP JavaServer Pages Seite 97 von total 218 Seiten

17.9 Skriptlets

Definieren Blöcke zur Programmierung in der eingestellten Sprache. Der Code eines Skriptlets wird erst nach einem Request ausgeführt.

- Scriptlet-Tag wird eingeleitet durch <% und beendet durch %> .

- Ein Scriptlet kann folgende vordefinierte Variablen benutzen:

- request : HttpServletRequest Objekt

- response : HttpServletResponse Objekt

- out : PrintWriter Objekt

- in : BufferedReader

Beispiel:Beispiel:Beispiel:Beispiel:

<%@ page import = "java.util.*" %> <html> <head> <title>Zufallsfarbe></title> </head> <% if(new Random.()nextDouble() > 0.5) { %> <body bgcolor="#FF0000"> <% } else { %> <body bgcolor="#00FF00"> <% } %> </body> </html>

generierter Servletgenerierter Servletgenerierter Servletgenerierter Servlet----Code:Code:Code:Code:

out.write("<html>\r\n <head>\r\n "); out.write("<title>Zufallsfarbe></title>\r\n "); out.write("</head>\r\n "); if(new java.util.Random.()nextDouble() > 0.5) { out.write("<body bgcolor="#FF0000">\r\n "); } else { out.write("<body bgcolor="#00FF00">\r\n "); } out.write("</body>\r\n </html>\r\n ");

Alternative zum Beispiel:Alternative zum Beispiel:Alternative zum Beispiel:Alternative zum Beispiel:

<%@ String bg; if (new java.util.Random.()nextDouble() > 0.5) bg = "<body bgcolor=\"#FF0000\">"; else bg = "<body bgcolor=\"#00FF00\">"; %> <%= bg %>

Page 98: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 JSP JavaServer Pages Seite 98 von total 218 Seiten

17.10 Aktionen

Aktionen sind Anweisungen an die JSP-Engine.

- Aktionen werden verwendet:

- bei der Verwendung von JavaBeans

- beim Erzeugen von Tag Libs (eigener Aktionen)

- zum Einbinden externer Ressourcen

- Integration in JSP-Seite durch XML-Syntax

- Beschreibung durch Attribute

- Beginnt mit <jsp:aktion Tag und wird durch /> Tag abgeschlossen

- Standardaktionen (vordefiniert):

- <jsp:forward page> zur Weiterleitung an eine andere Ressource

- <jsp:plugin> zum Einbinden von Applets

- <jsp:getProperty> liest den Wert einer Bean-Eigenschaft

- <jsp:setProperty> setzt den Wert einer Bean-Eigenschaft

- <jsp:include> zum Einbinden externer Ressourcen

- file="... - zur Übersetzungszeit

- page="... - bei Anforderung

- <jsp:useBean> ermöglicht den Zugriff auf Java-Beans

- Attribute:

- id= definiert eindeutiger Name

- scope= definiert Gültigkeitsbereich des Objektes:

- page - innerhalb dieser Seite

- request - Verzweigungen innerhalb dieser Anforderung

- session - innerhalb der Session

- application - innerhalb der Applikation / Web-Anwendung

Beispiel:Beispiel:Beispiel:Beispiel:

<jsp:useBean id="myBean" class="MyBean" scope="page"/>

17.11 Fehlerbehandlung

Es muss unterschieden werden zwischen:

Übersetzungsfehler :Übersetzungsfehler :Übersetzungsfehler :Übersetzungsfehler :

- übermittelt einen HTTP-Fehler 500 (Server Error) an den Client

Ausführungsfehler :Ausführungsfehler :Ausführungsfehler :Ausführungsfehler :

- in der entsprechenden catch Anweisung

- nichtbehandelte Laufzeitfehler leiten den Request an die entsprechende URL (Attribut: errorPager) weiter

Page 99: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 JSP JavaServer Pages Seite 99 von total 218 Seiten

Browser Rates EJB JSP

17.12 Vordefinierte Variablen

Innerhalb einer JSP-Seite sind einige Variablen vordefiniert, die innerhalb von Scriptlets und Ausdrücken verwendet werden können:

application (ServletContext) speichert Daten, die von mehreren JSP-Seiten genutzt werden können, z.B. DB Zugriff

config (ServletConfig) übergibt Initialisierungen der Servlet-Konfiguration

exception enthält Exception-Objekt bei einer Exception, falls: <%@ page errorPage = "true" %>

out(PrintWriter) gibt die Daten an die HTML-Seite aus

page(this) stellt die Referenz auf das Servlet während der Laufzeit der JSP-Seite zur Verfügung

pageContext (PageContext) ermöglicht den Zugriff auf die Attribute der JSP-Seite

request (HttpservletRequest) enthält Informationen über die aktuellen Anforderungen an die JSP-Seite (Parameter, etc.)

response (HttpServletResponse) bearbeitet den HTTP Response Header / HTTP Status Code

session (Httpsession) speichert Informationen über die aktuelle Session

17.13 Übung ee8: JSP Währungsrechner mit JDBC, TagLib und EJB

Diese Übung beschreibt eine vier Layer Web Anwendung mit JSP's und EJB. Nachfolgend das Deployment Diagramm mit den Komponenten:

CLIENT-TIER WEB-TIER LOGIG-TIER DATA-TIER Browser Tomcat JBoss mySQL HTTP RMI JDBC localhost:8080/ee8 JavaServerPages MoneyExchange ee Currency.jspCurrency.jspCurrency.jspCurrency.jsp Stateless SessionStateless SessionStateless SessionStateless Session ---- rates rates rates rates Currency_CDBC.jspCurrency_CDBC.jspCurrency_CDBC.jspCurrency_CDBC.jsp ID,BASECUR,RATEID,BASECUR,RATEID,BASECUR,RATEID,BASECUR,RATE Currency_DBTags.jspCurrency_DBTags.jspCurrency_DBTags.jspCurrency_DBTags.jsp

Die Anwendung soll die Umrechnung eines Betrages von einer Währung in eine andere ermöglichen. Die Währungen und die entsprechenden Wechselkurse sind in der mySQL DB abgelegt. Das Stateless Session Bean wird zur Umrechnung (Business Logik) benutzt. Für die JDBC Anbindung von einem JSP wird die Custem TagLib dbtag.jar benutzt. Informationen zu dieser TagLib und die notwendigen jar Archive sind erhältlich von http://jakarta.apache.org/taglibs/

Page 100: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 JSP JavaServer Pages Seite 100 von total 218 Seiten

Erstellen Sie eine entsprechende Applikation mit JSPs. Benutzen Sie dazu die Referenzbeispiele der lokalen TOMCAT Installation.

Ansatz : Browser WindowAnsatz : Browser WindowAnsatz : Browser WindowAnsatz : Browser Window

Ansatz: JSP mit DBTags um mySQL DB abzubinden Ansatz: JSP mit DBTags um mySQL DB abzubinden Ansatz: JSP mit DBTags um mySQL DB abzubinden Ansatz: JSP mit DBTags um mySQL DB abzubinden

<%@ taglib uri="http://jakarta.apache.org/taglibs/dbtags" prefix="sql" %> <%-- open a database connection --%> <sql:connection id="conn1"> <sql:url>jdbc:mysql://localhost:3306/ee</sql:url> <sql:driver>org.gjt.mm.mysql.Driver</sql:driver> <sql:userId>root</sql:userId> <sql:password> </sql:password> </sql:connection> <%-- get the requestet parameter --%> <sql:statement id="stmt1" conn="conn1"> <sql:queryselect id from rates order by 2> <sql:resultSet id="rset1"> <sql:getColumn position="1"/> </sql:resultSet> </sql:statement> <%-- close a database connection --%> <sql:closeConnection conn="conn1"/>

Ansatz: JSP mit JDBC um mySQL DB anzubindenAnsatz: JSP mit JDBC um mySQL DB anzubindenAnsatz: JSP mit JDBC um mySQL DB anzubindenAnsatz: JSP mit JDBC um mySQL DB anzubinden

<%@ page import="java.sql.*" %>

<% String con = "jdbc:mysql://localhost:3306/ee"; String user = "root"; String pass = ""; Class.forName("org.gjt.mm.mysql.Driver"); Connection connection = DriverManager.getConnection(con,user,pass); Statement statement = connection.createStatement();

SQLQuerry = "select basecur,rate from rates where id = " + jdbc_from; rs = statement.executeQuery(SQLQuerry); rs.next(); String base = rs.getString(1); String exch_rate = rs.getFloat(2);

statement.close(); connection.close(); %>

Page 101: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 J2EE Security Seite 101 von total 218 Seiten

Subject interface Principal

SamplePrincipalCredential

SamplePrincipal

SamplePrivateCredential

0..*

0..*

0..* public Credentials

private Credentials

Object

18181818 J2EE SecurityJ2EE SecurityJ2EE SecurityJ2EE Security

18.1 EJB-Security

Der grundlegende Gedanke von J2EE-Anwendungen ist es, sowenig wie möglich programmatische Sicherheit in die Beans zu codieren, sondern vielmehr deklarativedeklarativedeklarativedeklarative Sicherheitseinstellungen über den Server tätigen zu können.

Während ältere J2EE-Spezifikationen die Sicherheit nur am Rande behandelten, wurde sie seit der Version 2.0 zunehmends genauer reglementiert. Zentrale Themen und Neuerungen sind hierbei die Authentisierung von Clients und sichere Kommunikationsformen zwischen Client und Server. Weiterhin ist die Kommunikation zwischen Containern zunehmends gesichert worden. Die Umsetzung eines rollenbasierten Zugriffsschutzesrollenbasierten Zugriffsschutzesrollenbasierten Zugriffsschutzesrollenbasierten Zugriffsschutzes wird durch die "Security Identity "Security Identity "Security Identity "Security Identity Propagation"Propagation"Propagation"Propagation" innerhalb des Systems ermöglicht, also dem Weiterreichen der IdentitätWeiterreichen der IdentitätWeiterreichen der IdentitätWeiterreichen der Identität eines EJB-aufrufenden Client. Seit der EJB-Spezifikation Version 2.1 ist die Applikation-Client-Authentisierung über den Java Authentication and Authorisation Service (JAAS)Java Authentication and Authorisation Service (JAAS)Java Authentication and Authorisation Service (JAAS)Java Authentication and Authorisation Service (JAAS) möglich.

Ein Client wird bei seiner Anmeldung am System zunächst als ein unidentifiziertes Subject angesehen. Nach erfolgreicher Authentisierung werden diesem Client-Subject (u.A. mehrere) sogenannte PrincipalsPrincipalsPrincipalsPrincipals und CredentialsCredentialsCredentialsCredentials zugeordnet. Principals werden über das java.security.Principal-Interface implementiert und assoziieren das Client-Subject mit einem Benutzernamen oder –konto. Beispiel für ein Principal wäre z.B "Herr Meier, ... " oder "meier@inf...". Credentials sind Objekte, die sicherheitsrelevante Daten wie etwa ein Kerberos-Ticket oder Zertifikate des Clients speichern. Einfachste Möglichkeit wäre das Loginpasswort o.Ä. darin abzulegen. Folgendes Diagramm veranschaulicht die Zuordnung von Principals und Credentials an ein Subject:

Principals werden später wiederum besPrincipals werden später wiederum besPrincipals werden später wiederum besPrincipals werden später wiederum bestimmten Rollen zugeordnettimmten Rollen zugeordnettimmten Rollen zugeordnettimmten Rollen zugeordnet, die Teil der umzusetzenden Sicherheitspolitik des Systems sind. Man spricht dann von "principal-to-role-mapping". Es ist nach Spezifikation für J2EE-Server erforderlich, ein Tool zur Verfügung zu stellen, das dieses Mapping übernimmt (z.B Abgleich mit einer Datenbank). Innerhalb des Systems werden die Principals und mit ihnen die aufgesetzten Rollen von Aufruf zu Aufruf der EJB weiterpropagiert und sind auch über den EJBContext innerhalb des EJB-Codes jederzeit abfragbar.

Page 102: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 J2EE Security Seite 102 von total 218 Seiten

Eine unverschlüsselte Datenübertragung kommt besonders für Geschäftsanwendungen heutzutage selten noch in Frage, da ansonsten eine vertrauliche Übermittlung von Kunden- und Logindaten nicht gewährleistet werden kann. Es sind also sichere Übertragungsverfahren erforderlich, wobei SSL (Secure Sockets Layer) die zentrale Rolle bei J2EE–konformen Anwendungen spielt. SSL bietet die Möglichkeit zur Datenverschlüsselung und Überprüfung der Datenintegrität (über eine TCP/IP-Verbindung).

Es stehen Mechanismen bereit, die es erlauben, authentisierten Clients Rollen zuzuordnen und diese durch das gesamte System zu propagieren. Der Container kann "automatisch" prüfen, ob eine Rolle oder Identität überhaupt Zugriff auf ein bestimmtes Bean hat, dazu ist nicht unbedingt eine Abfrage innerhalb des Bean-Codes notwendig. Bei der J2EE-Architektur ist es möglich, für jedes EJB anzugeben, welche Rolle zum Aufruf welcher Methode berechtigt ist. Ein aufrufendes Subject kann einerseits direkt eine Client-Anwendung sein, aber auch ein anderes EJB. Vom Client aufgerufene EJB propagieren dessen Identität und zugeordnete Rollen zu anderen EJB, die im Zuge der Programmausführung aufgerufen werden.

Als Option steht allerdings noch die Möglichkeit offen, EJB immer dieselbe Rolle propagieren zu lassen, unabhängig vom aufrufenden Subject. Ein Bean kann z.B immer die Rolle "Guest" propagieren, um etwa den niedrigsten Sicherheitslevel einzunehmen, egal ob der Aufrufende nun in die Rolle "Customer" oder "Admin" fällt.

… <enterprise-beans> … <session> <ejb-name>EJBSecurity</ejb-name> … <security-identity> <runAs-specified-identity> <role-name>guest</role-name> </runAs-specified-identity> </security-identity> … </session> … </enterprise-beans>

Page 103: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 J2EE Security Seite 103 von total 218 Seiten

18.1.1 Security Roles

Security Rollen werden in verschiedenen Entwicklungsbereichen definiert. Die Bearbeitungs-schritte unterscheiden sich u.A. in der Art der Deklarierung im Deploymentdescriptor.

Bean Provider (EJBBean Provider (EJBBean Provider (EJBBean Provider (EJB----Entwickler)Entwickler)Entwickler)Entwickler)

Der Bean Provider, also derjenige der die EJB programmiert, soll "so wenig wie möglich" mit Sicherheitsfragen belangt werden. Programmierer sollen sich grösstenteils auf die Erstellung von wiederverwendbaren Komponenten und die Umsetzung von Geschäftsabläufen konzentrieren. Die jeweilige Sicherheitspolitik soll nicht hart im Code eingebettet sein, sondern später über den Container kontrollierbar und konfigurierbar sein.

Ist es nicht möglich, auf die "programmatische Sicherheit" zu verzichten (z.B. Aktionen, die von der Tageszeit oder von einem Konto-Betrag abhängig sind) muss dieses innerhalb des Beans implementiert werden. Die zur Überprüfung dieser Bedingungen nötigen Werte werden schliesslich erst zur Laufzeit bestimmt und verändert. Dem Programmierer ist es innerhalb des EJB-Codes möglich, die Rollen des aufrufenden Subjects zu ermitteln. Er kann dann im Code den Zugriff direkt und dynamisch kontrollieren. Über das vom Container bereitgestellte EJBContext-Objekt javax.ejb.EJBContext für EJB bzw. HttpServletRequest-Objekt für beispielsweise JSP, können die folgenden Methoden aufgerufen werden:

ejbContext.getCallerPrincipal() ejbContext.isCallerInRole("admin"); httpServletRequest.isUserInRole("admin"); httpServletRequest. getUserPrincipal();

Die Methode getCallerPrincipal() bzw. getUserPrincipal() hat als Rückgabewert ein Principal-Object, das die Identität des Aufrufenden Subjects beinhaltet. Mit Hilfe von isCallerInRole(String role) bzw. isUserInRole(String role) ist die direkte boolsche Abfrage der Rollenzugehörigkeit möglich. Da vom Standpunkt des Programmierers aus noch keine systemweiten Rollen eingeführt wurden, kann der Programmierer über den Deploymentdescriptor eigene Rollen einführen. Diese Rollen sollten grösstenteils allgemein und logisch auf eine Geschäftsstruktur angewendet werden können. So wird es höchstwahrscheinlich in einem Bank-EJB, das Kontendaten abruft, eine Rolle "Kunde" bzw. "Angestellter" oder "Admin" geben. Es müssen dazu im Deploymentdescriptor Rollenreferenzen eingeführt werden. Der Entwickler erstellt damit vorerst logische Rollen, die später vom Assembler den tatsächlichen Rollen im System zugeordnet werden.

… <security-role-ref> <description> This role encompasses the administrators of the company. </description> <role-name>admin</role-name> </security-role-ref> …

Später ist es möglich, die letztendlichen Rollen des Systems im Deploymentdescriptor auf diese logischen Rollen des Programmierers abzubilden.

Page 104: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 J2EE Security Seite 104 von total 218 Seiten

Application AssemblerApplication AssemblerApplication AssemblerApplication Assembler

Der Applicationassembler hat die Aufgabe das System aus den EJB-Komponenten zusammenzustellen und verkaufsfertig zu konfigurieren. In Bezug auf Sicherheit deklariert er auf den späteren Einsatzzweck zugeschnittene Rollen. Diese setzen auf den Rollen des Bean-Providers auf und müssen auch diesen zugeordnet werden.

Ohne Zuordnung der Rollenreferenzen auf Rollen des Systems sind diese Rollenreferenzen ohne Bedeutung. Diese erzwungene Zuordnung von logischen Rollen auf die tatsächlich verwendeten Rollen verhindert, dass der Programmierer nur ihm bekannte Rollen einführen kann. Eine geheim deklarierte Rolle wie etwa "Programmierer" müsste also auch vom Assembler/Deployer deklariert und abgesegnet werden, um im System wirken zu können. Somit wird diese Art von programmatischen Hintertürchen vermieden. Weiterhin muss der Assembler festlegen, welche spezifischen Methoden der einzelnen EJB von welcher Rolle aufgerufen werden dürfen. Dies geschieht mittels method permissions.

Diese Permissions werden für jedes Bean einzeln vergeben. Alle diese Schritte manifestiert der Assembler wieder im Deploymentdescriptor.

… <assembly-descriptor> <security-role> <description> This role includes the guests who are allowed limited access. </description> <role-name>guest</role-name> </security-role> <security-role> <description> This role includes the customers. </description> <role-name>customer</role-name> </security-role> <security-role> <description> This role should be assigned to the personnel (authorized to perform administrative functions). </description> <role-name>staff</role-name> </security-role> … </assembly-descriptor> …

Der nächste Auszug zeigt die Einführung der method-permissions für ein einzelnes Bean. Zu den jeweiligen Rollen (guest, customer, staff) werden die für sie erlaubten Methoden deklariert. Innerhalb des <method-name>-Elements können die folgenden drei Werte stehen:

- der Name der erlaubten Methode

- der Name und eventuelle Parameter, um sie eindeutig zu identifizieren

- ein *, um alle Methoden für eine Rolle freizugeben

Das <method-intf> Element definiert das entspechende Interface :

- 'Home', 'Remote', 'LocalHome' oder 'Local'

Page 105: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 J2EE Security Seite 105 von total 218 Seiten

<method-permission> <role-name>guest</role-name> <method> <ejb-name>EJBSecurity</ejb-name> <method-intf>Home</method-intf> <method-name>*</method-name> </method> <method> <ejb-name>EJBSecurity</ejb-name> <method-intf>Remote</method-intf> <method-name>getPrincipalInfo</method-name> </method> </method-permission> …

<method-permission> <role-name>staff</role-name> <method> <ejb-name>EJBSecurity</ejb-name> <method-name>*</method-name> </method> <method-permission>

DeployerDeployerDeployerDeployer

Um eigene Rollen zum System hinzufügen zu können, ist der Deployer auf eine gute Spezifikation des Assemblers angewiesen und muss über Rollenreferenzen des Programmierers Bescheid wissen. Es ist Aufgabe des Deployers, das auf seine Bedürfnisse angepasste Sicherheitssystem zu administrieren.

Es muss in diesem Stadium, d.h. während der Ausführung durch den Deployer, eine letztendliche Zuordnung von Benutzern bzw. Benutzergruppen auf die Rollen festgelegt werden. Zu diesem Zweck erfordert es die J2EE-Spezifikation, dass mit einer Serverimplementierung bestimmte Tools zur Verwaltung mitgeliefert werden. So u.A. für die allgemeine Administration des Rollensystems und der Abbildung von Benutzern und Benutzergruppen auf diese Rollen. Dieses Principal-to-Role-Mapping ist jeweils nur für eine einzelne Applikation innerhalb des Containers gültig, d.h. nur für ein Applikations-jar-File. Für jedes einzelne jar-File müssen Principals also separat auf Rollen abgebildet werden. Das liegt daran, dass ein Deploymentdescriptor nicht applikationsübergreifend lesbar ist, sondern nur für die Applikation gilt, in der er enthalten ist. In ihm werden schliesslich die Rollen deklariert, die für jede Anwendung anders sein können und individuell "gemappt" werden müssen.

PrincipalPrincipalPrincipalPrincipal----totototo----RoleRoleRoleRole----MappingMappingMappingMapping

<security-role-ref> <description> This role encompasses the administrators of the company. </description> <role-name>admin</role-name> <role-link>staff</role-link> </security-role-ref>

Page 106: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 J2EE Security Seite 106 von total 218 Seiten

18.2 Client-Tier Sicherheit

18.2.1 ApplicationClients

Seit der Version 2.0 ist es für J2EE-kompatible Server verpflichtend, eine Unterstützung für den Java Authentication and Authorisation Service (JAAS) zu bieten. Damit ist es möglich, Application-Clients zu authentifizieren. JAAS implementiert eine Version des Pluggable Authentication Module (PAM) Frameworks und erlaubt den Einsatz von eigens entwickelten Loginmodulen. Diese Loginmodule werden auf Seiten des Clients eingesetzt. So ist es verschiedenen Applicationclients möglich, auch verschiedene Loginvarianten zu unterstützen.

Beispielsweise wäre neben einem simplen Modul für Name/Passwort-Dialoge auch ein Modul denkbar, das mit Hilfe von externer Hardware und Smartcards arbeitet, oder Zertifikate weiterreicht. Die Loginmodule selbst steuern den Loginvorgang und sammeln Authentisierungsdaten über sogenannte Callbackhandler. Darüber werden auch Satusinformationen vom Server an den Client zurückgereicht. Die jeweilige Applikation auf Client-Seite muss dazu dem Server u.A. mindestens eine Klasse anbieten, die das Interface javax.security.auth.callback.CallbackHandler implementiert. Durch die Benutzung über solche Interfaces bleibt die Implementierung von Loginmodulen austauschbar.

Ist der Einsatz von JAAS nicht erwünscht, kann der Container den Vorgang der Authentisierung über voreingestellte Mechanismen komplett selbst übernehmen. Die Vorgehensweise dabei ist allerdings abhhängig von der Implementierung. Dazu ist die Clientsoftware entsprechend einzurichten.

MyCallbackHandler, die javax.security.auth.callback.CallbackHandler implementiert.

MyCallbackHandler handler = new MyCallbackHandler(name, password); LoginContext lc = new LoginContext("default", handler); lc.login();

18.2.2 WebClients

Die Spezifikation erlaubt prinzipiell drei Arten von Webclient-Authentisierung, die über den Server einstellbar sein müssen:

- http bzw. http über SSL (https) – Es werden http-Formulare mit einfacher Login/Passwort-Abfrage benutzt.

- formular – Agiert auch über http/https. Diese Einstellung erlaubt jedoch eigens definierte und umfangreichere Abfragen. Es können Mechanismen wie Cookies bzw. Session-Ids benutzt werden.

- client-certificate – Erlaubt die Authentifizierung von Webclients über Zertifikate. Für diese Option muss zur gegenseitigen Authentisierung (mutual authentication) natürlich auch auf Client-Seite ein X.509-Certificate installiert sein.

Der im Mid-Tier genauer beschriebene rollenbasierte Zugriffsschutz wird auch bei Webapplikationen vom Container übernommen. Es sind auch bei Webanwendungen programmatische statt vom Container übernommene Sicherheitsabfragen möglich: Über das HttpServletRequest Interface kann mit der Methode isUserInRole festgestellt werden, ob der Benutzer in einer bestimmten Rolle ist. Um die Identität (in Form eines java.security.Principal) zu erhalten, kann die Methode getUserPrincipal

verwendet werden.

Page 107: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 J2EE Security Seite 107 von total 218 Seiten

18.3 JNDI Sicherheit

Möchte eine Client-Anwendung z.B. eine Methode eines (Session- oder Entity-) EJB aufrufen, erhält es nach Anfrage an das Java Naming and Directory Interface (JNDI) einen Verweis auf ein EJB-HomeInterface. Über dieses Interface generiert er einen Verweis auf das Remote-Interface des EJB, über das dann die (Geschäfts-) Methoden des EJB aufgerufen werden können. Für den lokalen Zugriff müssen Beans auch einen Satz Local Interfaces bereitstellen. Darüber können dann andere Beans innerhalb des Containers oder Webanwendungen auf den-selben Server zugreifen. Es müsste im J2EE-Server somit ein Mechanismus implementiert sein, um Mutual Authentication mit dem JNDI-Dienst zu ermöglichen, was aber bislang selten der Fall ist. Gelänge es, einem Client oder dem Container einen falschen JNDI-Namespace zuzuspielen, könnte man ihnen darüber auch falsche Home-Interfaces und folglich falsche und böswillige Objektreferenzen zukommen lassen. Authentisierungsdaten könnten so z.B durch spoofing eines Loginvorgangs abgefragt werden. Andererseits muss auch der JNDI-Dienst gesichert werden, da sonst auch unberechtigte Server Einträge in dem Dienst vorgenommen werden können.

Die J2EE-Spezifikation rät zur Sicherung der Name-Services und zur Verwendung von "CORBA specified naming services" (Cos-Naming) über eine sichere Verbindung. Die Umsetzung allerdings ist den Serverentwicklern überlassen, da auch die verschiedenen CORBA-Implementierungen nicht immer eine Sicherung ihrer Namensdienste unterstützen.

Im folgenden sei eine Client-Initialisierung des JNDI-Kontextes exemplarisch dargestellt:

… // Set up the environment properties Hashtable h = new Hashtable(); h.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.cosnaming.CNCtxFactory"); h.put(Context.PROVIDER_URL, "iiop://localhost:3700"); h.put(Context.SECURITY_PRINCIPAL, "username"); h.put(Context.SECURITY_CREDENTIALS, "password"); // Get an InitialContext return new InitialContext(h); …

18.4 Realms

Bei der J2EE-Spezifikation werden Realms als eine Gruppe von Benutzern definiert, die alle mit dem selben Mechanismus authentisiert werden (ein Realm wäre etwa "certificate" und "ldap", wie beim Sun ONE Application Server). Realms werden auch manchmal als "security policy domains" bezeichnet. Innerhalb dieser Realms gelten dann die Zuordnungen von Rollen an Benutzer. Bei der Verwendung verschiedener Loginverfahren über JAAS ist es möglich, das System in Realms für jedes Verfahren einzuteilen. Das ist aber abhängig von der jeweiligen Implementierung, ebenso wie z.B. Einteilungen in LDAP-Realms und Betriebssystem-Realms.

18.5 Legacy Tier

Es gibt zwei Möglichkeiten, den Container, bzw. die Beans die in ihm laufen, gegenüber Legacy-Systemen wie etwa Datenbanken oder Gateways zu authentisieren. Die Systeme an sich erfordern meist die Eingabe eines Namen und Passworts oder benutzen andere Loginvarianten.

Die beiden Möglichkeiten sind "Container-Managed" und "Bean-Managed".

Page 108: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 J2EE Security Seite 108 von total 218 Seiten

User: "admin"User: "admin"User: "admin"User: "admin"

18.6 Declarative vs Programmatic Security

Web TierWeb TierWeb TierWeb Tier EJB TierEJB TierEJB TierEJB Tier deklarativedeklarativedeklarativedeklarative SicherheitSicherheitSicherheitSicherheit

programmatischeprogrammatischeprogrammatischeprogrammatische SicherheitSicherheitSicherheitSicherheit

ZugriffskontrolleZugriffskontrolleZugriffskontrolleZugriffskontrolle Web Resources Bean Methods

DeklarationDeklarationDeklarationDeklaration web.xml ejb-jar.xml

Deployment Descriptor

Programm

UmsetzungUmsetzungUmsetzungUmsetzung Web Container EJB Container Container Programm

CodierungCodierungCodierungCodierung Servlet / JSP EJB Bean "all or nothing" Logikbasiert

18.7 J2EE Security Architecture

18.8 Role Mapping

User: "user"User: "user"User: "user"User: "user" User: "guest"User: "guest"User: "guest"User: "guest"

Principal: adminPrincipal: adminPrincipal: adminPrincipal: admin Principal: userPrincipal: userPrincipal: userPrincipal: user Principal: guePrincipal: guePrincipal: guePrincipal: guestststst

Role: staffRole: staffRole: staffRole: staff Role: customerRole: customerRole: customerRole: customer

Role Reference:Role Reference:Role Reference:Role Reference: staffstaffstaffstaff

Role Reference:Role Reference:Role Reference:Role Reference: customercustomercustomercustomer

JBOSSJBOSSJBOSSJBOSS (Vendorspecific)

J2EEJ2EEJ2EEJ2EE

Page 109: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 J2EE Security Seite 109 von total 218 Seiten

18.9 ejb-jar.xml Security Elemente

Die folgende Graphik zeigt die Security Related Elements des ejb-jar.xml Deployment Descriptors.

Page 110: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 J2EE Security Seite 110 von total 218 Seiten

18.10 Übung ee9 : J2EE Security

Erstellen Sie ein ApplicationClient der sich am JBoos Applikationsserver mittels username / password identifiziert und anschliessend seiner Security Policy entsprechende Businessmethoden aufruft:

Ansatz: SecurityTestClientAnsatz: SecurityTestClientAnsatz: SecurityTestClientAnsatz: SecurityTestClient

public class SecurityTestClient { public static void main(String args[]) throws Exception {

/* username, password, role * admin admin staff * user user customer * guest guest guest */

String name = "admin"; String pass = "admin"; String role = "staff";

char[] password = pass.toCharArray();

System.setProperty("java.security.auth.login.config", "[JBoss-Home]/client/auth.conf"); // [Jboss-Home]/client/auth.conf: // SecurityTest { // org.jboss.security.ClientLoginModule required debug=false; // };

try { AppCallbackHandler handler = new AppCallbackHandler(name, password); LoginContext lc = new LoginContext("SecurityTest", handler); lc.login();

Properties env = new Properties(); env.load(new FileInputStream("resources/jndi.properties")); InitialContext initial = new InitialContext(env);

SecurityTestHome home = (SecurityTestHome)initial.lookup("ejb/Security"); SecurityTest st = home.create();

System.out.println("Principal : " + name + " wants to getPrincipalInfo : " + st.getPrincipalInfo(role));

System.out.println("Principal : " + name + " wants to doSomething : " + st.doSomething(role));

st.remove(); lc.logout(); } catch (Exception e) { System.err.println("Failed :"); Throwable t = e; while (t != null) { System.err.println("Type: " + t.getClass().getName()); System.err.println("Message: " + t.getMessage()); t = t.getCause(); } } } }

Page 111: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 J2EE Security Seite 111 von total 218 Seiten

18.10.1 deklarative Security

Die Security Policies für die "user" und die "roles" werden in zwei text-basierten Dateien abgebilded und im root Verzeichnis in der JAR Datei bereitgestellt:

users.policiesusers.policiesusers.policiesusers.policies

admin=admin user=user guest=guest

roles.propertiesroles.propertiesroles.propertiesroles.properties

admin=staff user=customer guest=guest

Die entsprechenden Business Methoden werden declarativ im Deployment Descriptor ejb-jar.xml definiert:

ejbejbejbejb----jar.xmljar.xmljar.xmljar.xml

<method-permission> <role-name>customer</role-name> <method> <ejb-name>EJBSecurity</ejb-name> <method-intf>Home</method-intf> <method-name>*</method-name> </method> <method> <ejb-name>EJBSecurity</ejb-name> <method-intf>Remote</method-intf> <method-name>doSomething</method-name> </method> </method-permission>

18.10.2 prommatische Security

Die programmatische Sicherheit kommt zusätzlich im Sourcecode zur Geltung:

Business Methode doSomething der SecurityTestBean.javaBusiness Methode doSomething der SecurityTestBean.javaBusiness Methode doSomething der SecurityTestBean.javaBusiness Methode doSomething der SecurityTestBean.java

public String doSomething(String role) throws FailedLoginException { Principal p = sc.getCallerPrincipal(); if (sc.isCallerInRole(role)) { return "Principal (" + p + ") identifies as Role \"" + role + "\""; } else { throw new FailedLoginException("wrong Principal / wrong Role"); } }

Output:Output:Output:Output: Principal : admin wants to getPrincipalInfo : Principal = admin Role(staff) = true Principal : admin wants to doSomething : Principal (admin) identifies as Role "staff"

Page 112: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Transaktionen Seite 112 von total 218 Seiten

19191919 TransaktionenTransaktionenTransaktionenTransaktionen

Allgemein der kleinste, unteilbare und daher an einem Stück ununterbrochen abzuarbeitende Prozess einer Anwendung. Transaktionen werden daher vollständig oder gar nicht abgearbeitet. Speziell ist häufig eine logisch zusammenhängende Folge von Operationen in einer Datenbank gemeint, die die Datenbank von einem konsistenten in einen weiteren konsistenten Zusand überführt.

19.1 Transaktionskonzepte

Die vier Eigenschaften von Transaktionen bezeichnet man als ACIDACIDACIDACID-Prinzip:

AtomicityAtomicityAtomicityAtomicity (Atomarität = unteilbar): Eine Transaktion wird entweder vollständig oder gar nicht ausgeführt. Resultate teilweise ausgeführter Transaktionen sind nie nach aussen sichtbar.

ConsistencyConsistencyConsistencyConsistency (Konsistenz = zusammenhaltend): Eine Transaktion bewirkt immer den Übergang von einem konsistenten Datenbankzustand in einen anderen konsistenten Datenbankzustand. Falls durch eine Transaktion Integritätsbedingungen verletzt werden, wird die Transaktion abgebrochen und die Datenbank im Ursprungszustand belassen.

IsolationIsolationIsolationIsolation (Isolation = getrennt): Parallel ablaufende Transaktionen sehen nichts von Parallelität. Jede Transaktion sieht während ihrer Ausführung stets nur einen konsistenten, während der Transaktion von aussen unveränderten, Datenbankzustand.

DurabilityDurabilityDurabilityDurability (Dauerhaftigkeit = persistent): Sobald eine Transaktion beendet ist, ist der von ihr bewirkte Zustandsübergang dauerhaft. Die durch die Transaktion vorgenommenen Änderungen können nicht mehr verschwinden.

19.1.1 Lokale und verteilte Transaktionen

Transaktionen, bei deren Durchführung nur lokale Daten betroffen sind und nicht mehrere Ressourcen verwendet werden müssen, werden als lokale Transaktionen (local transactions) bezeichnet. Wenn dagegen mit mehreren Daten, die auf verteilten Systemen liegen, gearbeitet wird, spricht man von einer verteilten Transaktion (distributed transaction) oder einer globalen Transaktion (global transaction). Um eine globale Transaktion durchzuführen, muss sie in Teil-transaktionen aufgeteilt werden.

In dem Sequenzdiagramm startet die Applikation (BOT = begin of transaction) zunächst eine TeilTeilTeilTeiltrantrantrantransaktion 1saktion 1saktion 1saktion 1 auf der ersten Datenbank und ändert den Wert AWert AWert AWert A. Von Teiltransaktion 1 erfolgt eine positive Rückmeldung. Daraufhin startet die Applikation eine zweite Teiltransaktionzweite Teiltransaktionzweite Teiltransaktionzweite Teiltransaktion auf der zweiten Datenbank und ändert ebenfalls den Wert AWert AWert AWert A, worauf sie auch hier eine positive Rückmeldung erhält. Nun kann an die erste Datenbank ein Commit übermittelt werden und die Teiltransaktion 1 ist beendet. Das Gleiche geschieht mit der zweiten Teiltransaktion, und damit wurde die gesamte Transaktion positiv abgeschlossen.

Page 113: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Transaktionen Seite 113 von total 218 Seiten

19.1.2 Zwei Phasen Commit

Allerdings kann es zu inkonsistenten Zuständen kommen, falls die Datenbank, die für Teiltransaktion 2 zuständig ist, vor dem Empfang der zweiten Commit-Anweisung ausfällt. Beim Neustart der Datenbank wird diese die Teiltransaktion 2 und damit auch den Wert A zurücksetzen, weil sie nicht korrekt beendet wurde. Dadurch haben die Datenbanken unterschiedliche Daten für Wert A.

Um solche Fehlerfälle abzufangen, bedarf es erweiteter Protokolle, z.B. des Zwei-Phasen-Commit-Protokolls (2PC-Protokoll).

In der ersten Phase teilt die Applikation den Ressourcen der Teiltransaktionen mit, dass sie sich vorbereiten sollen ("Prepare-to-Commit"). Wenn die Antworten ("Ready to Commit") aller Knoten positiv waren, wird die zweite Phase eröffnet, und die Applikation sendet ein Commit an die Knoten ("Commit Phase").

19.2 Java Transaction API (JTA) und Java Transaction Service (JTS)

Java Transaction Service (JTS) spezifiziert die Implementierung eines Transaktionsmanagers, der die Java Transaction API als Programmierschnittstelle anbietet und JTA die Programmierschnittstelle. Damit können Programmierer, Applikationsserver und transaktionsunterstützende Ressourcen den Dienst verwenden. Für jede transaktionsunterstützende (XA-kompatible) Ressource wird ein Ressourcenmanager eingesetzt.

Die Koordination von Transaktionen über die Grenzen eines Ressourcenmanagers hinaus wird durch den Transaktionsmanager realisiert und hat nun die folgenden Aufgaben:

- Initiierung von Start, Abbruch und Abschluss von Transaktionen.

- Über Transaktionsmanager erfolgt die Realisierung globaler, verteilter Transaktionen. Für eine globale Transaktion werden die beteiligten Ressourcen von dem Transaktions-manager verwaltet.

- Der erfolgreiche Abschluss globaler Transaktionen wird mittels des Zwei-Phasen-Commit-Protokolls koordiniert.

- Die Kooperation eines Transaktionsmanagers mit anderen Transaktionsmanagern kann über CORBA erfolgen.

Page 114: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Transaktionen Seite 114 von total 218 Seiten

Java Client Anwendung oder Applikationsserver

Transaktions- Manager DB

DB

JMS- Server

Ressourcen- Manager Ressourcen-

Manager Ressourcen- Manager

Der Zugriff auf einen Java Transaction Service erfolgt mit der Java Transaction API, die aus drei Schnittstellen besteht:

javax.transaction.UserTransactionjavax.transaction.UserTransactionjavax.transaction.UserTransactionjavax.transaction.UserTransaction: Mit diesem Interface können Transaktionen gestartet begin(), abgebrochen rollback() oder abgeschlossen commit() werden. Zusätzlich kann man noch den Status einer Transaktion abfragen getStatus(), ein Timeout setzen setTransactionTimeout() oder sicherstellen, dass mit einem Rollback setRollbackOnly() die Transaktion auf jeden Fall beendet wurde.

javax.transaction.TransactionManagerjavax.transaction.TransactionManagerjavax.transaction.TransactionManagerjavax.transaction.TransactionManager: Ausser den Methoden der UserTransaction ermöglicht dieses Interface einem Applikationsserver noch zwei zusätzliche Methoden: Mit suspend() kann eine Transaktion vorübergehend angehalten und mit resume() wieder aufgenommen werden.

javax.transaction.Transaction und javax.transaction.xa.XAResourcejavax.transaction.Transaction und javax.transaction.xa.XAResourcejavax.transaction.Transaction und javax.transaction.xa.XAResourcejavax.transaction.Transaction und javax.transaction.xa.XAResource: Auch in der Transaktion-Schnittstelle wurden alle Methoden aus UserTransaction implementiert. Ausserdem besteht noch die Möglichkeit zum Registrieren enlistResource() und zum Deregistrieren einer Ressource delistResource() innerhalb der Transaktion; enlistResource() erhält als Parameter einerseits die Ressource selbst – als Objekt, das die XAResource-Schnittstelle implementiert – und andererseits einen als Objekt typisierten Parameter, der den Ressourcenmanager identifiziert und mit diesem interagiert, um das Zwei-Phasen-Commit durchzuführen. Die XARessource-Schnittstelle ist ein Java-Mapping des XA-Standards nach der X/Open-Spezifikation. Die wichtigsten Methoden dieser Schnittstelle sind:

- der Beginn der Ausführung mit der Zuordnung zu einer globalen Transaktion durch Aufruf

von start()

- das Einholen der Entscheidung über ein Commit mittels prepare()

- das Beenden der Ausführung mit end()

- das Abschliessen / Zurücksetzen der Transaktion mit commit() / rollback()

JDBC

JMS

Page 115: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Transaktionen Seite 115 von total 218 Seiten

19.3 User-Transaktionen

Um sicherzustellen, dass die Transaktionen einer Applikation den ACID-Prinzipien folgen, sind sorgfältiges Entwerfen und Implementieren nötig. Jede nachträgliche Änderung kann teuer werden. Um die Implementierung zu unterstützen, hat die EJB-Spezifikation zwei Typen von Transaktionsverwaltung vorgesehen:

- implizite (container-managed transactions) Transaktionssteuerung

- explizite (bean-managed transactions) Transaktionssteuerung

In allen EJBeans ausser den Entity-Beans kann zwischen den beiden Transaktionssteuerungen gewählt werden. Bei den beiden Entity-Beans ist seit der Spezifikation 2.0 nur noch die im-plizite Transaktionssteuerung möglich:

Wenn eine Entity-Bean in einer Client-Transaktion aufgerufen wird, werden erst einmal mit ejbLoad die Daten von der Datenbank geladen. Es werden entsprechende Locks in der Datenbank gesetzt und die Entity-Bean mit den Werten der Datenbank "gefüllt". Dann werden ein oder mehrere Geschäftsmethoden aufgerufen, und dann wird die Client-Transaktion "commited". Daraufhin ruft der Container ejbStore auf, um die Datenbank mit den neuen Werten zu aktualisieren. Die Locks in der Datenbank werden wieder entfernt. Die Transaktion in der Entity-Bean sollte also die ejbLoad, die Geschäftsmethoden und ejbStore umfassen. Wenn nun Bean-Managed-Transactions (BMT) verwendet werden würde, müsste in ejbLoad mit begin() die Transaktion begonnen und in ejbStore mit commit() beendet werden. Das Problem dabei ist, dass der Container die Methoden aufruft und nicht der Client. Dadurch kann nicht garantiert werden, dass die Methoden auch tatsächlich in dieser Reihenfolge aufgerufen werden. Es könnten mehr Transaktionen begonnen als beendet werden. Infolge der Container-Verwaltung sind BMT in Entity-Beans nicht erlaubt.

Das Element <transaction-type> im Deployment-Deskriptor legt fest, welche Transak-tionsverwaltung verwendet werden soll. Der Wert ist entweder Bean oder Container.

19.3.1 Bean Managed Transaction

Mit Hilfe der BMT, ist es möglich, Transaktionen explizit zu steuern. Dies kann umfassen:

betrifft Transaktionen sowohl mit anderen EJBeans, als auch mit Datenbanken über JDBC.

- Transaktionen mit anderen EJBeans

- Transaktionen mit Datenbanken über JDBC

Es kann nötig sein, die Transaktionssteuerung selbst zu übernehmen, wenn z.B. einige Ressourcen nicht vom Transaktions-Manager gesteuert werden können. BMT können jedoch keine verschachtelten Transaktionen verwalten. Um die explizite Transaktionssteuerung zu ermöglichen, unterstützt EJB die Java Transaction API (JTA). Die darin enthaltene Klasse UserTransaction stellt eine Schnittstelle zum Transaktions-Manager zur Verfügung, mit der der Gültigkeitsbereich einer Transaktion verwaltet werden kann. In dieser Schnittstelle können folgende Methoden aufgerufen werden:

Page 116: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Transaktionen Seite 116 von total 218 Seiten

- begin() –––– leitet eine neue Transaktion ein. Der Thread, der die neue Transaktion erzeugt hat, wird mit dieser verbunden. Falls innerhalb dieser Transaktion Beans verwendet werden, die bereits existierende Transaktionen unterstützen, wird die Transaktion an sie weitergereicht.

- commit() –––– beendet die aktuelle mit diesem Thread verbundene Transaktion.

- rollback() –––– Transaktion wieder zurückführen Um im Falle eines Fehlers die Transaktion wieder zurückzuführen und die schon durchgeführten Aktualisierungen rückgängig zu machen.

- setRollBackOnly() –––– merkt die Transaktion für das Zurückführen vor. Die Transaktion wird nach ihrer Beendigung in jedem Fall zurückgeführt, ob sie nun erfolgreich war oder nicht.

- setTransactionTimeout(int seconds) –––– Lebenszeit festlegen Mit dieser Methode wird festgelegt, wie lange die Transaktion existieren darf, bevor ein Timeout auftritt. Falls diese Methode nicht verwendet oder der Wert 0 übergeben wird, gilt der Default-Wert des Transaktions-Managers. Diese Methode muss unmittelbar nach begin() aufgerufen werden.

- getStatus() –––– Abfrage des aktuellen Transaktions-Status Liefert einen Integer-Wert zurück, der mit denen in der Schnittstelle javax.transaction.Status definierten Konstanten verglichen werden kann.

Um eine BMT verwenden zu können, wird das entsprechende <transaction-type> Tag mit Bean beschrieben.

<transaction-type>Bean</transaction-type>

Dann wird eine Verbindung zum Transaktions-Manager des EJB-Server hergestellt und über den Container ein UserTransaction-Objekt geholt.

Context jndiContext = new InitialContext(); UserTransaction trans = (UserTransaction) jndiContext.lookup("java:comp/UserTransaction"); ...

oder:oder:oder:oder:

SessionContext ejbContext; UserTransaction trans = ejbContext.getUserTransaction(); trans.begin(); ... trans.commit();

<interface> UserTransaction: <interface> UserTransaction: <interface> UserTransaction: <interface> UserTransaction:

interface UserTransaction { void begin(); void setTransactionTimeout(int seconds); void commit(); void rollback(); void setRollbackOnly(); int getStatus(); }

Die möglichen Werte der Methode getStatus finden sich als Konstanten in der Schnittstelle javax.transaction.Status.

Page 117: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Transaktionen Seite 117 von total 218 Seiten

19.3.2 Container-Managed-Transactions

Mit Hilfe der CMT ist es möglich, die Steuerung der Transaktionen dem Container zu überlassen. Der Vorteil ist, dass kein zusätzlicher Code in die Geschäftslogik geschrieben werden muss und die Bean dadurch übersichtlicher wird. Alles was sich innerhalb eines try-catch-Blocks befindet, gehört zur selben Transaktion. Falls bei der Ausführung des Blocks ein Fehler auftritt, werden alle schon durchgeführten Anweisungen rückgängig gemacht. Diese Methode hat allerdings den Nachteil, dass keine verschachtelten Transaktionen möglich sind. Ein weiterer Aspekt ist, dass das Verhalten der Bean geändert werden kann, ohne die Imple-mentierung ändern zu müssen. Zusätzlich wird das Risiko einer fehlerhaften Verwendung von Transaktions-Protokollen wie JTA reduziert. Das Transakionsverhalten kann über den Deployment-Deskriptor gesteuert werden, der die Transaktions-Attribute für die gesamte Bean oder für jede Bean-Methode einzeln festlegt. Ein Beispiel soll den Unterschied verdeutlichen:

CMT auf Bean EbeneCMT auf Bean EbeneCMT auf Bean EbeneCMT auf Bean Ebene

<assembly-descriptor> <container-transaction> <method> <ejb-name>AdressBean</ejb-name> <!-- Hiermit werden alle Methoden angesprochen --> <method-name>*</method-name> </method> <!-- Jetzt kommt das Transaktions-Attribut. Es kann die Werte "NotSupported", "Supports", "Required", "RequiresNew", "Mandatory" oder "Never" bekommen. --> <!-- Alle Methoden bekommen das Transaktions-Attribut "Required". --> <trans-attribute>Required</trans-attribute> ...

Wie man dagegen einzelne Methoden unterschiedlich konfigurieren kann, soll der folgende Ausschnitt aus einem Deployment-Descriptor zeigen:

CMT auf Methoden EbeneCMT auf Methoden EbeneCMT auf Methoden EbeneCMT auf Methoden Ebene

<container-transaction> <method> <ejb-name>AdressBean</ejb-name> <method-name>getVorname</method-name> </method> <trans-attribute>Required</trans-attribute> </container-transaction>

<container-transaction> <method> <ejb-name>AdressBean</ejb-name> <method-name>getVorname</method-name> <method-param>format</method-param> </method> <trans-attribute>Required</trans-attribute> </container-transaction> ...

Mit dem Eintrag <method-name> können überladenen Methoden unterschiedliche Trans-aktions-Attribute zugewiesen werden:

- Required: Die Bean soll immer in einer Transaktion laufen. Falls schon eine Transaktion läuft, wird die Methode ein Teil von ihr, andernfalls wird eine

Page 118: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Transaktionen Seite 118 von total 218 Seiten

neue Transaktion vom Container gestartet. Die neue Transaktion umfasst allerdings nur die Required-Bean und die von ihr benutzten Beans. Wenn die Required-Methode beendet ist, wird auch die Transaktion beendet.

- RequiresNew: Es wird immer eine neue Transaktion gestartet. Wenn der aufrufende Client bzw. Bean selbst zu einer Transaktion gehört, wird diese ausgesetzt, bis die "RequiresNew"-Methode beendet ist.

- Supports: Die Methode wird zur Transaktion des Aufrufers einbezogen. Jedoch nur wenn dieser eine Transaktion hat. Falls der Aufrufer zu keiner Transaktion gehört, wird auch keine neue Transaktion vom Container erzeugt.

- Mandatory: Diese Bean-Methode gehört immer zur Transaktion des aufrufenden Clients. Das entspricht dem Gegenteil des Never-Attribut. Falls der aufrufende Client mit keiner Transaktion verbunden ist, tritt eine Exception auf.

- NotSupported: Methoden können keine Transaktionen unterstützen oder erzeugen. Falls der aufrufende Client Teil einer Transaktion ist, wird diese Transaktion während der Ausführung der Methode ausgesetzt (unterbrochen).

- Never: Die Methode darf nicht in eine Transaktion einbezogen werden. Falls ein Client innerhalb einer Transaktion diese Methode aufrufen sollte, tritt eine Exception auf. Wenn man also vermeiden möchte, dass die Clients, die diese Methode aufrufen, Transaktionen verwenden, dann kann man das mit diesem Attribut erreichen.

Allerdings lassen sich nicht alle Transaktions-Attribute mit allen Beans nutzen. Die folgende Tabelle zeigt, welche Kombinationen möglich sind:

TransaktionsTransaktionsTransaktionsTransaktions----AttributAttributAttributAttribut StatelessStatelessStatelessStateless SessionSessionSessionSession BeanBeanBeanBean

StatefulStatefulStatefulStateful SessionSessionSessionSession BeanBeanBeanBean

EntityEntityEntityEntity BeanBeanBeanBean

MessageMessageMessageMessage DrivenDrivenDrivenDriven BeanBeanBeanBean

RequiredRequiredRequiredRequired Ja Ja Ja Ja

RequiresNewRequiresNewRequiresNewRequiresNew Ja Ja Ja NeinNeinNeinNein

MandaMandaMandaMandatorytorytorytory Ja Ja Ja NeinNeinNeinNein

SupportsSupportsSupportsSupports Ja NeinNeinNeinNein NeinNeinNeinNein NeinNeinNeinNein

NotSupportedNotSupportedNotSupportedNotSupported Ja NeinNeinNeinNein NeinNeinNeinNein Ja

NeverNeverNeverNever Ja NeinNeinNeinNein NeinNeinNeinNein NeinNeinNeinNein

Für CMP EntityBeans ist es sinnvoll nur RequiredRequiredRequiredRequired, RequiresNewRequiresNewRequiresNewRequiresNew oder MandatoryMandatoryMandatoryMandatory als Transaktionsattribut zu verwenden, damit die Datenbankzugriffe zuverlässig bleiben.

Auf einer Collection, die von einem HomeInterface einer CMP Enitity-Bean geliefert wird, darf man nur innerhalb einer Transaktion zugreifen, und zwar derjenigen, in der sie erzeugt wurde. Für solche Methoden des HomeInterface soll man daher nicht RequiresNew als Transaktionsattribut verwenden.

Beim Auftreten einer Exception wird eine laufende Transaktion abgebrochen. Darunter versteht man eine RuntimeException (insbesondere EJBException). Ausserdem vernichtet in diesem Fall der EJB-Container die Bean, weil er sich nicht mehr sicher ist, dass ihr Inhalt noch brauchbar ist. Der Aufrufer erhält eine RemoteException bzw. EJBException, die in irgendeiner Form als Fehlermeldung ausgegeben wird.

Alle Ausnahmen ausser RuntimeExceptions und RemoteExceptions (einschliesslich Unterklassen) zählen als ApplicationExceptions. Sie werden an den Aufrufer weitergegeben. Wenn möglich, wird die Transaktion fortgeführt. Ob dies nicht gelungen ist, kann man mit dem

Page 119: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Transaktionen Seite 119 von total 218 Seiten

Methodenaufruf context.getRollbackOnly() herausfinden; context ist vom Typ EJBContext. Mit context.setRollbackOnly() kann man den erfolglosen Abbruch der laufenden Transaktion erzwingen.

19.3.3 JDBC Transaktionen

Die JDBC-Transaktionen sind Transaktionen, die vom Transaktions-Manager des Datenbank-managementsystems (DBMS) verwaltet werden. Mit Hilfe der java.sql.Connection-Schnittstelle ist es möglich, Datenbank-Transaktionen selbst zu steuern. Der standardmässig eingeschaltete AutoCommit-Modus sollte vorher mit setAutoCommit(false) ausgeschaltet werden. Der Beginn einer Transaktion erfolgt implizit mit der ersten SQL-Anweisung. Es können dann weitere SQL-Anweisungen folgen, bis schliesslich die gesamte Transaktion mit commit() bestätigt oder mit rollback() zurückgenommen wird.

BeispielBeispielBeispielBeispiel

con.setAutoCommit(false); stmt.executeUpdate("INSERT INTO Tabelle VALUES (Wert1, Wert2, ...);"); if (error) { con.rollback(); } else { con.commit(); }

Page 120: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Transaktionen Seite 120 von total 218 Seiten

19.4 Übung ee10 : EJB Transaction

Wie bereits erwähnt laufen alle Methodenaufrufe einer Enterprise Bean innerhalb einer Transaktion. Normalerweise erstreckt sich die Transaktion sogar über entfernte Methodenaufrufe (nicht aber auf die Benutzung von Webdiensten). Wenn eine Methode eine Exception auslöst (bzw. eine Nachricht, als Folge davon, nicht bestätigt wird), wird die Transaktion erfolglos abgebrochen (rollback). Nur wenn alles gut geht, wird die Transaktion erfolgreich abgeschlossen (commit).

Das liegt daran, dass wir im Deployment-Descriptor bisher immer Folgendes geschrieben haben:

<assembly-descriptor> ... <container-transaction> ... <trans-attribute>Required</trans-attribute> </container-transaction> ... </assembly-descriptor>

Insgesamt gibt es folgende mögliche Werte für das Tag <trans-attribute>:

NeverNeverNeverNever : Die Methoden dürfen nicht im Rahmen einer Transaktion aufgerufen werden.

NotSupportedNotSupportedNotSupportedNotSupported : Es ist egal, ob die Methoden im Rahmen einer Transaktion aufgerufen werden. In jedem Fall werden die Methodenaufrufe ausserhalb einer Transaktion abgewickelt.

SupportsSupportsSupportsSupports : Falls die Methoden im Rahmen einer Transaktion aufgerufen werden, werden diese Transaktionen weitergeführt, andernfalls werden die Methodenaufrufe eben ausserhalb einer Transaktion abgewickelt.

RequiredRequiredRequiredRequired : Falls die Methoden im Rahmen einer Transaktion aufgerufen werden, werden diese Transaktionen weitergeführt, andernfalls wird eine Transaktion begonnen.

RequiresNewRequiresNewRequiresNewRequiresNew : Es ist egal, ob die Methoden im Rahmen einer Transaktion aufgerufen werden. In jedem Fall wird eine (Unter-)Transaktion begonnen. (Dies kann ziemlich aufwendig werden.)

MandatoryMandatoryMandatoryMandatory : Die Methoden müssen im Rahmen einer Transaktion aufgerufen werden.

19.4.1 Transaktionssteuerung

Erstellen Sie eine Bankkontenverwaltung mit einem BMP Entity Bean, das einen Übertrag von einem Konto A zu einem Konto B ermöglicht. Negative Saldos auf einem der Konten soll dabei mit einer entsprechenden Transaktionssteuerung unterbunden werden.

Ein Konto definiert sich durch eine "id" einem "owner" und einer "balance" .

mysql> desc accounts; +---------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+-------------+------+-----+---------+-------+ | id | char(3) | | PRI | 0 | | | owner | varchar(50) | YES | | NULL | | | balance | double | YES | | NULL | | +---------+-------------+------+-----+---------+-------+

Page 121: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Transaktionen Seite 121 von total 218 Seiten

SQL Skript : accounts TableSQL Skript : accounts TableSQL Skript : accounts TableSQL Skript : accounts Table

# MySQL-Front Dump 2.2 # Host: localhost Database: ee #-------------------------------------------------------- # Server version 4.1.1a-alpha-nt USE ee; # Table structure for table 'accounts' DROP TABLE IF EXISTS accounts; CREATE TABLE `accounts` ( `id` char(3) NOT NULL default '0', `owner` varchar(50) default NULL, `balance` double default NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; # Dumping data for table 'accounts' INSERT INTO accounts VALUES("1","Client 1","100"); INSERT INTO accounts VALUES("2","Client 2","200");

Ansatz: BankClient.javaAnsatz: BankClient.javaAnsatz: BankClient.javaAnsatz: BankClient.java

final Bank bank = home.create();

final Account a1 = bank.getAccount("1"); final Account a2 = bank.getAccount("2");

printAccount(a1); printAccount(a2);

final double amount = 100;

Thread t1 = new Thread() { public void run() { try { System.out.println("Thread started : transfer 1 -> 2 : " + amount); bank.transfer(a1, a2, amount); System.out.println("Thread finished"); } catch (Exception e) { e.printStackTrace(); } } };

t1.start(); Thread.sleep(2000);

printAccount(a1); printAccount(a2);

Output:Output:Output:Output:

ID : 1 OWNER : Client 1 BALANCE : 100.0 ID : 2 OWNER : Client 2 BALANCE : 200.0 Thread started : transfer 1 -> 2 : 100.0 Thread finished ID : 1 OWNER : Client 1 BALANCE : 0.0 ID : 2 OWNER : Client 2 BALANCE : 300.0

Page 122: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Transaktionen Seite 122 von total 218 Seiten

Wird bei einem Übertrag der Saldo des "Client 1" kleiner als Null so soll die Transaktion nicht durchgeführt und die bereits ausgeführten Datenänderungen rückgängig gemacht werden:

Ansatz: BankBean.java (Fragment)Ansatz: BankBean.java (Fragment)Ansatz: BankBean.java (Fragment)Ansatz: BankBean.java (Fragment)

public class BankBean implements SessionBean {

private SessionContext context; private AccountHome accountHome;

public Account getAccount(String number) { log(); try { return accountHome.findByPrimaryKey(number); } catch (Exception e) { throw new EJBException(e.getMessage()); } }

public void transfer(Account from, Account to, double amount) throws IllegalOperationException { log(); try { to.deposit(amount); from.withdraw(amount); } catch (IllegalOperationException e) { context.setRollbackOnly(); } catch (Exception e) { throw new EJBException(e.getMessage()); } … }

Ansatz: AmounAnsatz: AmounAnsatz: AmounAnsatz: AmountBean.java (Fragment)tBean.java (Fragment)tBean.java (Fragment)tBean.java (Fragment)

public class AccountBean implements EntityBean {

public void deposit(double amount) throws IllegalOperationException { log(); balance += amount; if (balance < 0) throw new IllegalOperationException("balance becomes less than 0"); }

public void withdraw(double amount) throws IllegalOperationException { log(); balance -= amount; if (balance < 0) throw new IllegalOperationException("balance becomes less than 0"); } … }

Ansatz: IllegalOperationException.javaAnsatz: IllegalOperationException.javaAnsatz: IllegalOperationException.javaAnsatz: IllegalOperationException.java

package beans;

public class IllegalOperationException extends Exception { public IllegalOperationException(String reason) { System.out.println(reason); } }

Page 123: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Transaktionen Seite 123 von total 218 Seiten

Testen Sie den SampleCode und stellen Sie sicher, dass die Transaktionssteuerung funktioniert.

Die Konsolestatements (LogDatei) des Applikationsservers erläutern die Sequenz:

file:///[jboss.home]/server/ee/log/server.log

17:24:33,234 INFO [STDOUT] beans.BankBean@14bfb68[16604072]: setSessionContext 17:24:33,234 INFO [STDOUT] beans.BankBean@14bfb68[16604072]: ejbCreate 17:24:33,234 INFO [STDOUT] beans.BankBean@14bfb68[16604072]: getAccount 17:24:33,234 INFO [STDOUT] beans.AccountBean@1667cff[16604072]: <init> 17:24:33,250 INFO [STDOUT] beans.AccountBean@1667cff[16604072]: setEntityContext 17:24:33,250 INFO [STDOUT] beans.AccountBean@1667cff[16604072]: makeConnection 17:24:33,265 INFO [STDOUT] beans.AccountBean@1667cff[16604072]: ejbFindByPrimaryKey 17:24:33,265 INFO [STDOUT] beans.AccountBean@1667cff[16604072]: selectByPrimaryKey 17:24:33,359 INFO [STDOUT] beans.BankBean@14bfb68[16604072]: getAccount 17:24:33,359 INFO [STDOUT] beans.AccountBean@1667cff[16604072]: ejbFindByPrimaryKey 17:24:33,359 INFO [STDOUT] beans.AccountBean@1667cff[16604072]: selectByPrimaryKey 17:24:33,375 INFO [STDOUT] beans.AccountBean@1667cff[16604072]: ejbActivate 17:24:33,375 INFO [STDOUT] beans.AccountBean@1667cff[16604072]: ejbLoad 17:24:33,390 INFO [STDOUT] beans.AccountBean@1667cff[16604072]: getOwner 17:24:33,390 INFO [STDOUT] beans.AccountBean@1667cff[16604072]: ejbStore 17:24:33,406 INFO [STDOUT] beans.AccountBean@1667cff[16604072]: getBalance 17:24:33,406 INFO [STDOUT] beans.AccountBean@1667cff[16604072]: ejbStore 17:24:33,406 INFO [STDOUT] beans.AccountBean@1881bb1[16604072]: <init> 17:24:33,406 INFO [STDOUT] beans.AccountBean@1881bb1[16604072]: setEntityContext 17:24:33,421 INFO [STDOUT] beans.AccountBean@1881bb1[16604072]: makeConnection 17:24:33,437 INFO [STDOUT] beans.AccountBean@1881bb1[16604072]: ejbActivate 17:24:33,453 INFO [STDOUT] beans.AccountBean@1881bb1[16604072]: ejbLoad 17:24:33,453 INFO [STDOUT] beans.AccountBean@1881bb1[16604072]: getOwner 17:24:33,453 INFO [STDOUT] beans.AccountBean@1881bb1[16604072]: ejbStore 17:24:33,468 INFO [STDOUT] beans.AccountBean@1881bb1[16604072]: getBalance 17:24:33,468 INFO [STDOUT] beans.AccountBean@1881bb1[16604072]: ejbStore 17:24:33,500 INFO [STDOUT] beans.BankBean@14bfb68[16604072]: transfer 17:24:33,500 INFO [STDOUT] beans.AccountBean@1881bb1[16604072]: deposit 17:24:33,500 INFO [STDOUT] beans.AccountBean@1667cff[16604072]: withdraw 17:24:33,500 INFO [STDOUT] balance becomes less than 0 17:24:35,484 INFO [STDOUT] beans.AccountBean@d4e99c[16604072]: <init> 17:24:35,484 INFO [STDOUT] beans.AccountBean@d4e99c[16604072]: setEntityContext ...

Testen und überprüfen Sie anhand der Methoden-Transaktionsattribute das transaktionale Verhalten der EJB Applikation:

KlasseKlasseKlasseKlasse BankBean AccountBean

MethodenMethodenMethodenMethoden transfere() deposit() withdraw()

getBalance() getOwner()

TransaktionsTransaktionsTransaktionsTransaktions---- VerhaltenVerhaltenVerhaltenVerhalten

ReReReRequiredquiredquiredquired RequiredRequiredRequiredRequired RequiredRequiredRequiredRequired ����

RequiredRequiredRequiredRequired RequiresNewRequiresNewRequiresNewRequiresNew RequiredRequiredRequiredRequired ����

SupportsSupportsSupportsSupports RequiredRequiredRequiredRequired SupportsSupportsSupportsSupports ����

RequiredRequiredRequiredRequired SupportsSupportsSupportsSupports NotSupportedNotSupportedNotSupportedNotSupported ����

RequiredRequiredRequiredRequired SupportsSupportsSupportsSupports RequiredRequiredRequiredRequired ����

NotSupportedNotSupportedNotSupportedNotSupported RequiredRequiredRequiredRequired RequiredRequiredRequiredRequired ����

TransaktionsattributTransaktionsattributTransaktionsattributTransaktionsattribut

NotSupportedNotSupportedNotSupportedNotSupported NotSupportedNotSupportedNotSupportedNotSupported NotSupportedNotSupportedNotSupportedNotSupported ����

Page 124: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Message Driven Beans Seite 124 von total 218 Seiten

20202020 Message Driven Message Driven Message Driven Message Driven BeansBeansBeansBeans

Die Session-Bean und die Entity-Bean können als Remote-Procedure-Call-basierte Komponenten angesehen werden, die immer synchron vom Client aufgerufen werden. Die Message-Driven-Bean dagegen unterstützt die asynchrone Kommunikation. Der Client muss nun nicht mehr warten, bis der Server die Aufgabe erledigt hat, sondern kann gegebenenfalls sofort mit seiner Arbeit fortfahren. Um dies zu realisieren, wird von der Message-Bean keine direkte Schnittstelle zur Verfügung gestellt, sondern vom Client eine Nachricht an einen Message-Server (Nachrichten-Server) geschickt. Sie wird vom Container aufgerufen, wenn eine Nachricht für sie eintrifft. Bei Inbetriebnahme (deployment) der Bean auf dem Server wird daher bestimmt, auf welche Nachrichten die Message-Driven-Bean reagieren soll (subscribe). Was sie dann machen soll, wird in der onMessage-Methode festgelegt.

20.1 JMS

Der Java Message Service (JMS) von Sun ist eine API für den Zugang zu unternehmensweiten Messaging-Systemen. JMS definiert eine Schnittstelle, legt aber die Implementierung nicht fest. Der Vorteil für Software-Hersteller besteht darin, dass sie ihre existierenden Messaging-Produkte mit JMS-Schnittstellen versehen können, ohne sie wesentlich ändern zu müssen.

Bei der Integration von EJB mit JMS spielt die Message-Driven-Bean die zentrale Rolle. Da sie weder Remote- noch Home-Interface hat, greift der Client per JMS auf diese Bean zu. Er findet sie indirekt über die Auswahl einer Message-Queue (Point-to-Point-Verbindung) oder eines Message-Topics (Publish/Subscribe-Mechanismus) mittels JNDI (Java Naming and Directory Service). Der Deployment Descriptor (DD) legt fest, für welches der beiden Messaging-Modelle die Message-Driven-Bean zuständig ist. Den Vertrag für letztere schliessen Bean Provider und Container Provider folgendermassen: Ersterer programmiert die Message-Driven-Bean und implementiert die Business-Methode - die fachliche Logik - in der onMessage()-Methode. Letzterer aktiviert die MDB und ruft die genannte Methode bei Eintreffen einer Message auf. Die Message-Driven-Bean ermöglicht den asynchronen Aufruf von EJBeans und realisiert nebenläufige Nachrichten. EJBeans lassen sich nun wie jeder andere JMS Message Listener ansprechen.

Nachrichten erzeugen mit der JMS APINachrichten erzeugen mit der JMS APINachrichten erzeugen mit der JMS APINachrichten erzeugen mit der JMS API

Das Erzeugen und Absenden einer Nachricht über JMS erfolgt in sechs Schritten.

1. Treiber lokalisieren

2. Verbindung erzeugen

3. Session erzeugen

4. Destination lokalisieren

5. Consumers / Producers erzeugen

6. Nachricht senden / empfangen

Page 125: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Message Driven Beans Seite 125 von total 218 Seiten

Lokalisieren des JMSLokalisieren des JMSLokalisieren des JMSLokalisieren des JMS----Treibers:Treibers:Treibers:Treibers:

Zunächst muss ein Treiber für das verwendete JMS-Produkt geladen werden. Dies geschieht durch ein lookup(CONNECTION_FACTORY), wobei CONNECTION_FACTORY der JNDI-Name des Treibers ist, der die Schnittstelle ConnectionFactory implementiert.

Erzeugen der JMSErzeugen der JMSErzeugen der JMSErzeugen der JMS----Verbindung:Verbindung:Verbindung:Verbindung:

Eine JMS-Verbindung ist eine aktive Verbindung zu einem JMS-Provider, der die Netzwerk-Kommunikation kapselt. Analog zu JDBC wird der Treiber verwendet, um eine Connection anzufordern. Es gibt zwei Connection-Klassen, TopicConnection und QueueConnection.

Erzeugen einerErzeugen einerErzeugen einerErzeugen einer JMS JMS JMS JMS SessioSessioSessioSession:n:n:n:

Eine JMS Session ist ein Hilfsobjekt, das verwendet wird, um Nachrichten zu senden oder zu empfangen. Es dient dazu, um die Eigenschaften des Nachrichtenaustauschs festzulegen und in eine Transaktion einzubeziehen. Es gibt zwei JMS Session Klassen, TopicSession und QueueSession.

Lokalisieren einer JMS Lokalisieren einer JMS Lokalisieren einer JMS Lokalisieren einer JMS DestinatioDestinatioDestinatioDestination:n:n:n:

Eine JMS Destination ist ein Kommunikationskanal zu dem Nachrichten gesendet oder von dem Nachrichten empfangen werden können. Die Auswahl des Kanals erfolgt über ein lookup(CHANNEL), wobei CHANNEL der JNDI-Name des Kanals ist, der beim Server eingetragen wurde.

Erzeugen eines JMS Erzeugen eines JMS Erzeugen eines JMS Erzeugen eines JMS Consumers Consumers Consumers Consumers oder eines JMS oder eines JMS oder eines JMS oder eines JMS ProducerProducerProducerProducers:s:s:s:

Senden oder Empfangen der Nachricht:Senden oder Empfangen der Nachricht:Senden oder Empfangen der Nachricht:Senden oder Empfangen der Nachricht:

Falls eine Nachricht verschickt werden soll, muss sie erst noch erstellt werden. Zu diesem Zweck gibt es mehrere Typen von Nachrichten: Text, Bytes, Streams, Objects und Maps. Nachdem die Nachricht instantiiert wurde, kann sie über den Producer gesendet werden. Falls eine Nachricht über den Consumer empfangen wurde, muss sie dem Typ entsprechend verarbeitet werden.

Dieser gesamte Ablauf ist bei beiden Kommunikationsmodellen gleich. Es gibt für jedes Interface zwei Ausprägungen analog zu den beiden Kommunikationsmodellen.

ErzeugerErzeugerErzeugerErzeuger----InterfaceInterfaceInterfaceInterface PointPointPointPoint----totototo----PointPointPointPoint Publish / SubscribePublish / SubscribePublish / SubscribePublish / Subscribe

ConnectionFactory QueueConnectionFactory TopicConnectionFactory

Connection Queue Connection TopicConnection

Destination Queue Topic

Session QueueSession TopicSession

MessageProducer QueueSender TopicPublisher

MessageConsumer QueueReciever, -Browser TopicSubscriber

Page 126: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Message Driven Beans Seite 126 von total 218 Seiten

20.2 MDB

Eine Message-Driven-Bean (MDB) ist eine EJB Komponente, die ausschliesslich dem Empfang von Nachrichten dient, welche über Queues oder Topics eines JMS-Servers gesendet wurden.

Die Eigenschaften einer MDB lassen sich wie folgt zusammenfassen:

Im Gegensatz zu den anderen EJBeans besitzt die MDB kein Remote, Home, Local-Home oder Local-Interface. Sie wird ausschliesslich über Nachrichten verwendet.

Die MDB hat nur eine einzige Geschäftsmethode. Die Methode onMessage(Message) wird immer dann vom Container aufgerufen, wenn eine Nachricht für die MDB eingetroffen ist. Sie akzeptiert eine JMS Message. Standardmässig sollte in dieser Methode zuerst geprüft werden, ob auch die richtige Nachricht eingetroffen ist.

Eine MDB liefert keine Rückgabewerte oder Exceptions. Falls der Client Rückgabewerte benötigt, müssen diese wiederum als Nachricht abgeschickt werden. Dies macht der Container aber nicht automatisch, sondern muss in der Geschäftsmethode implementiert werden. Dies gilt ebenso für den Fehlerfall. Natürlich kann ein Systemfehler auftreten, dieser wird aber nur vom Container registriert.

Eine MDB ist zustandslos und verhält sich wie eine Stateless-Session-Bean.

Eine MDB kann ein permanenter (durable) oder nicht-permanenter (non-durable) Empfänger sein. Als permanenter Empfänger kann die MDB selbst dann die Nachrichten empfangen, die an einen Topic gesendet wurden, wenn sie nicht aktiv war. Der JMS-Server speichert die Nachrichten und überträgt sie, wenn die MDB wieder aktiv ist. Als nicht-permanenter Empfänger gehen die Nachrichten dagegen verloren.

20.2.1 Bean Life Cycle

Container initiated:Container initiated:Container initiated:Container initiated: Container initiated:Container initiated:Container initiated:Container initiated:

ejbRemove() setMessageDrivenContext ejbCreate()

Container initiated:Container initiated:Container initiated:Container initiated: onMessage()

setSessionContextsetSessionContextsetSessionContextsetSessionContext Die Methode setMessageDrivenContext(MessageDrivenContext) wird vor ejbCreate ausgeführt, um der Message-Driven-Bean einen Zugang zu den Informationen über die Laufzeit-Umgebung zu geben.

ejbCreateejbCreateejbCreateejbCreate Die Methode ejbCreate der Message-Driven-Bean wird vom Container ausgeführt. In dieser Methode sollen Verbindungen (JNDI) zu Ressourcen und Referenzen anderer EJ-Beans initialisiert werden. Datenbankverbindungen sollten hier nicht geöffnet werden, da sie sonst für die gesamte Existenz der MDB belegt sind.

ejbRemoveejbRemoveejbRemoveejbRemove Die Methode ejbRemove wird vom Container aufgerufen, wenn der Pool verkleinert werden soll oder der Server runtergefahren wird. Entwickler sollten diese Methode zum Schliessen von Ressourcen nutzen.

onMessageonMessageonMessageonMessage Die Message-Driven-Bean kann zwei Zustände annehmen. Entweder sie existiert nicht oder sie ist bereit (pooled), Nachrichten zu empfangen. Falls eine Nachricht eintrifft, wird onMessage ausgeführt.

Methode-Ready-Pool

does not exist

Page 127: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Message Driven Beans Seite 127 von total 218 Seiten

20.3 Übung ee11 : MDB Wetterstation

Wie bereits bei der Betrachtung des Java Message Service (JMS) aufgezeigt gibt es zwei verschiedene Arten von Mechanismen, nämlich:

TopicTopicTopicTopic:

Nachrichten haben die Form eines Newsletters oder eines Beitrags in einer Newsgroup. Jeder Abonnent bekommt die Nachricht zu sehen.

Queue: Queue: Queue: Queue:

Nachrichten haben die Form eines Anrufs in einem Call-Center. Nur der erste freie Bearbeiter, der den Anruf entgegennimmt, hat damit zu tun.

In beiden Fällen muss man eine Destination einrichten, in dem der Absender die Nachricht ablegt und aus dem der Empfänger die Nachricht holt.

Bevor man einen Briefkasten benutzen kann, muss man ihn im EJB-Behälter einrichten. Dazu dient der proprietäre Deployment-Descriptor jbossmq-service.xml:

<server> <mbean code="org.jboss.mq.server.jmx.Topic" name="jboss.mq.destination:service=Topic,name=TestTopic"> <depends optional-attribute-name="DestinationManager"> jboss.mq:service=DestinationManager </depends> </mbean> <mbean code="org.jboss.mq.server.jmx.Queue" name="jboss.mq.destination:service=Queue,name=TestQueue"> <depends optional-attribute-name="DestinationManager"> jboss.mq:service=DestinationManager</depends> </mbean> </server>

Page 128: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Message Driven Beans Seite 128 von total 218 Seiten

Übung ee11: WetterstationÜbung ee11: WetterstationÜbung ee11: WetterstationÜbung ee11: Wetterstation

Konzipieren Sie einen WetterTopic MDB das eine Wettermessage definiert:

Log: file:///[jboss.home]/server/ee/log/server.log

10:49:46,437 INFO [STDOUT] WetterMDB: Wetter=Sonnig Wind=West Temp=18.7C 10:49:46,437 INFO [STDOUT] WetterMDB: Wetter=Sonnig Wind=Ost Temp=3.7C 10:49:46,453 INFO [STDOUT] WetterMDB: Wetter=Wolkig Wind=Ost Temp=2.9C

Ansatz: WetterBean.java (Fragment)Ansatz: WetterBean.java (Fragment)Ansatz: WetterBean.java (Fragment)Ansatz: WetterBean.java (Fragment)

public void onMessage(javax.jms.Message message) { try { MapMessage mapMessage = (MapMessage) message; System.out.println("WetterMDB: " + Wetter=" + mapMessage.getString("Wetterlage") + " Wind=" + mapMessage.getString("Windrichtung") + " Temp=" + mapMessage.getDouble("Temperatur") + "C"); } catch (Exception ex) { System.out.println(ex.getMessage()); ex.printStackTrace(); } }

Ansatz: WetterClient.java Fragment)Ansatz: WetterClient.java Fragment)Ansatz: WetterClient.java Fragment)Ansatz: WetterClient.java Fragment)

public class WetterClient { public static void main(String[] args) throws Exception { Hashtable props = new Hashtable(); props.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory"); props.put("java.naming.provider.url", "jnp://localhost:1099"); props.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces"); props.put("jnp.socket.Factory", "org.jnp.interfaces.TimedSocketFactory"); Context ctx = new InitialContext(props); TopicConnectionFactory qcf = (TopicConnectionFactory) ctx .lookup("ConnectionFactory"); Topic topic = (Topic) ctx.lookup("topic/WetterTopic"); TopicConnection connect = qcf.createTopicConnection(); TopicSession session = connect.createTopicSession(false, TopicSession.AUTO_ACKNOWLEDGE); connect.start(); TopicPublisher publisher = session.createPublisher(topic);

String[] wetterlagen = { "Sonnig", "Wolkig", "Regen" }; String[] windrichtungen = { "Nord", "West", "Sued", "Ost" }; for (int i = 0; i < 10; i++) { int rndm = (int) (Math.random() * 300); String sWetterlage = wetterlagen[rndm % 3]; String sWindrichtung = windrichtungen[rndm % 4]; double dTemperatur = (double) (rndm - 50) / 10; MapMessage msg = session.createMapMessage(); msg.setString("Wetterlage", sWetterlage); msg.setString("Windrichtung", sWindrichtung); msg.setDouble("Temperatur", dTemperatur); publisher.publish(msg); System.out.println("-> Wetter=" + sWetterlage + " Wind=" + sWindrichtung + " Temparatur=" + dTemperatur + "C"); } session.close(); connect.close(); } }

Page 129: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Alles wird viel einfacher! Seite 129 von total 218 Seiten

DDDD EJB 3.0EJB 3.0EJB 3.0EJB 3.0

21212121 Alles wirdAlles wirdAlles wirdAlles wird viel einfacher! viel einfacher! viel einfacher! viel einfacher!

Viele Entwickler haben erkannt, dass EJB viel zu kompliziert ist, da man für jede Enterprise Bean mehrere Artefakte entwickeln muss:

- Ausser der Beanklasse selbst, um die es eigentlich geht, braucht man einige Interfaces

- Man braucht etliche XML-Deskriptordokumente, die nicht leicht zu schreiben sind

- In der Beanklasse werden diverse Callbackmethoden benötigt, die entweder trivial (und darum nur lästig) oder aber relativ knifflig zu programmieren sind

21.1 EJB 3.0 Spezifikation

Folgende Ziele gelten für die neue Spezifikation:

- Elimination der Deskriptoren

- Kapselung der Abhängigkeiten von der Umgebung und dem JNDI-Zugriff mit Hilfe der in Java 5 neu eingeführten Annotationen sowie durch Dependency Injection

- Enterprise Beans sollten so weit vereinfacht werden, dass sie eine grössere Ähnlichkeit mit POJOs bzw. JavaBeans besitzen

- Elimination der speziellen Remote Interfaces (remote und local); hierfür sollten normale Javainterfaces ausreichen

- Elimination der Home Interfaces

- Elimination von Callbacks. Nicht alle Callbacks waren lästig bzw. überflüssig, man hat solche übriggelassen (bzw. neue eingeführt), die besonders sinnvoll erscheinen

- Verbesserte Möglichkeiten für das Testen (z. B. Unit Tests) ausserhalb des AS

21.2 EJB 3.0 Features

einfacheres EJB APIeinfacheres EJB APIeinfacheres EJB APIeinfacheres EJB API

EJB 3.0 eliminiert das Home Interfaces und verlangt für die Bean Klassen keine Implementation der APIs mehr. Session Beans, Message Driven Beans und Entity Beans sind nun triviale Java Beans, die sich auf die Implementation der Businesslogik konzentrieren. EJB sind nun einfache Java Klassen (POJO) ohne überladene Interfaces. Entity Beans folgen nun der normalen objektorientierten (O-O) Entwurfsmuster und profitieren von Vererbung, Polymorphismus und den standart OO-Konstrukten.

Java AnnotationenJava AnnotationenJava AnnotationenJava Annotationen

EJB 3.0 nützt die seit JDK 5.0 eingeführte Java Annotation als Alternative für das Nennen der Deploymentparameter. Die EJB 3.0 Specifikation definieren eine Vielzahl von Annotationen, die Bean Typ, Dependency Injection, Transaction, Security, Callbacks, Object-Relational Mapping, Relations, etc. beschreiben. Deployment Descriptors dienen weiterhin und können Annotationen überschreiben. JBoss AS und Hibernate als OR-Mapping unterstützen Annotationen.

Page 130: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Alles wird viel einfacher! Seite 130 von total 218 Seiten

Dependency InjectionDependency InjectionDependency InjectionDependency Injection

Komplexe Szenarien für das Anbinden von EJBs oder Ressourcen verschwinden. Durch die @Inject, @EJB, und @Resource Annotationen werden diese Abhängigkeiten transparent durch den Kontainer an die Java Beans angebunden.

Optionale CallbacksOptionale CallbacksOptionale CallbacksOptionale Callbacks

Entwickler müssen nur noch die Callbacks implementieren die sie brauchen. Auch hier erlauben Annotationen @PostConstruct, @PreDestroy, @PrePersist, oder @PostPersist Java Bean Methoden mit den Callbacks zu verbinden um entsprechende Event Benachrichtigungen zu erhalten.

Entity Manager APIEntity Manager APIEntity Manager APIEntity Manager API

Der Entity Manager API ist neu in EJB 3.0 und ermöglicht Java Bean Instanzen sich mit einem EntityManager zu synchronisieren. JBoss AS wie auch Hibernate unterstützen dieses neue API.

einfachere Persistenz und erweiterte Querieseinfachere Persistenz und erweiterte Querieseinfachere Persistenz und erweiterte Querieseinfachere Persistenz und erweiterte Queries

EJB 3.0 standardisiert das Java Persistenz Modell. Dabei spielt Hibernate eine wichtige Rolle bei der Definition dieses API. Etliche Java Annotationen wurden definiert um das Object-Relational Mapping zu definieren. EJB 3.0 erweitert auch die EJB-QL, die nun auch dynamische Queries, Subqueries, bulk Updates, und bulk Deletes unterstützt.

Einsatz ausserhalb des KontainersEinsatz ausserhalb des KontainersEinsatz ausserhalb des KontainersEinsatz ausserhalb des Kontainers

Die EJB 3.0 Persistenz Spezifikation erlaubt den Gebrauch des neuen Persistenz API auch in normalen Java Anwendungen. JBoss EJB 3.0 ermöglicht den Gebrauch von Session Beans und Message Driven Beans auch ausserhalb des JBoss AS in standalone Programme, Junit Tests, standalone Tomcat, und auch in anderen ASs.

21.3 Meta-Annotationen

ermöglichen:

- Generierung von Interfaces

- Steuerung des Laufzeitverhaltens von EJB-Komponenten

- Eliminierung der Deployment Deskriptoren

- Demarkation von Injection-Punkten

für:

- Klassen

- Methoden

- Parameter

- Attribute

Page 131: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Alles wird viel einfacher! Seite 131 von total 218 Seiten

Verwendung von MetaVerwendung von MetaVerwendung von MetaVerwendung von Meta----Annotationen im Quellcode:Annotationen im Quellcode:Annotationen im Quellcode:Annotationen im Quellcode:

@Stateless // NEU @Remote (HelloEJB3WorldBean.class) // NEU public class HelloEJB3WorldBean { // implements SessionBean fällt weg String sayHello(){ return "Hello EJB3 World!"; }

generierter Code für das Interface:generierter Code für das Interface:generierter Code für das Interface:generierter Code für das Interface:

public interface HelloEJB3WorldBean { String sayHello() throws RemoteException;

generierter Deployment Descriptorgenerierter Deployment Descriptorgenerierter Deployment Descriptorgenerierter Deployment Descriptor

… <session> <ejb-name>HelloEJB3World</ejb-name> <home>ejb3.HelloEJB3WorldHome</home> <remote>ejb3.HelloEJB3World</remote> <ejb-class>ejb3.HelloEJB3WorldBean</ejb-class> ... </session> ...

21.4 JNDI Kapselung

- ermöglicht Testen von EJBKomponenten

- J2EE-Applikationsserver als Testumgebung nicht mehr zwingend notwendig

- über setter-Methoden werden einer Komponente zur Laufzeit entsprechende Informationen zur Verfügung gestellt (injiziert).

- DI : Dependency Injection

- IOC : Inversion of Control (Hollywood-Prinzip: "don't call us – we call you")

Neue Methode <Object lookup(String name)> ist zum EJBContext hinzugefügt, erlaubt direkter Zugriff für Beans auf den JNDI-Server, ohne extra Code:

Zugriffsvarianten:Zugriffsvarianten:Zugriffsvarianten:Zugriffsvarianten:

- @EJB = Referenz auf EJB-Komponenten

- @Resource = Referenz auf Ressourcen

@Stateless public class MySessionBean { @Resource(name="myDB") private DataSource customerDB; public void myMethod (String myString) { try { Connection conn = customerDB.getConnection(); ... } catch (Exception ex) { ...} } }

Page 132: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Alles wird viel einfacher! Seite 132 von total 218 Seiten

@Session public class MySessionBean { private DataSource customerDB; @Resource private void setCustomerDB(DataSource customerDB) { this.customerDB = customerDB; } public void myMethod (String myString) { ... Connection conn = customerDB.getConnection(); ... } }

Injection von "Singletons" im ContainerInjection von "Singletons" im ContainerInjection von "Singletons" im ContainerInjection von "Singletons" im Container

- @Resource javax.ejb.SessionContext ctx;

- @ Resource javax.ejb.MessageDrivenContext ctx;

- @ Resource javax.ejb.TimerService timer;

- @ Resource javax.ejb.UserTransaction ut;

- @ Resource javax.ejb.EntityManager manager;

21.5 Configuration by Exception

Spezifiziertes Default-Verhalten von EJB-Komponenten mit dem Ziel der Reduzierung der Entwicklungszeit

Beispiel:Beispiel:Beispiel:Beispiel:

- EJB-Komponenten (Session Beans) sind per default "lokal" zugreifbar und erlauben eine explizite Steuerung durch Verwendung der Annotationen

- @Local und @Remote für das Interface bzw. die Bean-Klasse

- auf Attribute von Entity Beans wird per default über get/set-Methoden zugegriffen und erlaubt eine explizite Steuerung durch Verwendung der Werte der Annotation

- @Entity(access=PROPERTY) und @Entity(access=FIELD)

21.6 Callback-Annotationen für Lifecycle Events

- vordefinierte Callbacks

- gekennzeichnet durch Annotationen (z.B. @PostConstruct, @PreDestroy)

- Session Beans, Message-Driven Beans, Entity Beans

21.7 Interzeptor-Methoden

- Abfangen von Geschäftsmethodenaufrufen

- ermöglicht die Ausführung von beliebigem Code

- z.B. technische Prüfungen, Security

- Session Beans, Message-Driven Beans

Page 133: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Alles wird viel einfacher! Seite 133 von total 218 Seiten

21.8 Stateless Session Bean

Das Home Interface (und deren create Methode) entfällt, dadurch ist der Zugriff auf die EJB Komponente aus Sicht des Clients vereinfacht:

Version 2.1Version 2.1Version 2.1Version 2.1

public static void main(...) throws Exception { InitialContext ctx = new InitialContext(); Object o = ctx.lookup("MyEJB3"); MyEJB3Home home = (MyEJB3Home) PortableRemoteObject.narrow(o, MyEJB3Home.class); MyEJB3 myEJB3 = home.create(); }

Version 3.0Version 3.0Version 3.0Version 3.0

public static void main(...) throws Exception { InitialContext ctx = new InitialContext(); MyEJB3 myEJB3 = (MyEJB3) ctx.lookup("MyEJB3"); ... // do something }

- Business (Remote) Interface muss weiterhin vorhanden sein:

- als einfaches Java-Interface (POJI), ohne extens (EJBObject / EJBLocalObject)

- somit auch keine RemoteExceptions mehr in den Methoden

- Business (Remote) Interface kann auch generiert werden

- Bean-Klasse muss nicht mehr das Callback-Interface javax.ejb.SessionBean implementieren

- ejbRemove() gibt es nicht mehr, ist für eine Stateless Session Bean sowieso eine völlig überflüssige Methode

- @Stateless annotiert Bean-Klasse als Stateless Session Bean

Component InterfComponent InterfComponent InterfComponent Interface (Remoteace (Remoteace (Remoteace (Remote---- oder Business Interface): oder Business Interface): oder Business Interface): oder Business Interface):

public Interface EJB3 { public void sayHello(); }

Bean Klasse: Bean Klasse: Bean Klasse: Bean Klasse:

@Stateless public class EJB3Bean implements EJB3 { public void sayHello() { return "Hello EJB3 World!"; }

Page 134: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Alles wird viel einfacher! Seite 134 von total 218 Seiten

21.9 Statefull Session Bean

Das Home Interface (und deren create Methode) entfällt, dadurch ist der Zugriff auf die EJB Komponente aus Sicht des Clients vereinfacht:

- Initialisierung der Bean erfolgt durch die Geschäftsmethode, (ev. über Annotation)

- create Methode kann im Component Interface vorhanden sein

Business (Remote) Interface muss weiterhin vorhanden sein:

- als einfaches Java-Interface (POJI), ohne extens (EJBObject / EJBLocalObject)

- somit auch keine RemoteExceptions mehr in den Methoden

- Business (Remote) Interface kann auch generiert werden

- Bean-Klasse muss nicht mehr das Callback-Interface javax.ejb.SessionBean implementieren

- die remove() Methode (annotiert durch @Remove) kann eine beliebige Methode der Bean Klasse sein

- @Stateful annotiert Bean-Klasse als Stateful Session Bean

Component InteComponent InteComponent InteComponent Interface (Remoterface (Remoterface (Remoterface (Remote---- oder Business Interface): oder Business Interface): oder Business Interface): oder Business Interface):

public Interface AutomaticTellerEJB3 { public void depositMoney(float amount); public void withdrawMoney(float amount); public float getAccountBalance(); @Remove public void closeAccount(); }

Bean Klasse: Bean Klasse: Bean Klasse: Bean Klasse:

@Stateful public class AutomaticTellerEJB3Bean implements AutomaticTellerEJB3 { public void depositMoney(float amount) { accountBalance += amount); } public void withdrawMoney(float amount) { accountBalance -= amount); } public float getAccountBalance() { return accountBalance; } @Remove public void closeAccount() { ... // do something do cleanup } }

Page 135: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Alles wird viel einfacher! Seite 135 von total 218 Seiten

21.10 Message Driven Bean

Ein MDB muss entweder mit @MessageDriven Annotation gekennzeichnet werden oder das Callback-Interface javax.ejb.MessageDrivenBean implementieren.

21.11 Entity Bean

Der Schwerpunkt bildet die CMP mit einer Weiterentwicklung der Persistenzfunktionalität, eine einfachere CMP/BMP Nutzung und einen höheren Leistungsumfang.

- Ziel: Simplifizierung von Entity Beans durch POJOs

- konkrete (keine abstrakte) Klasse

- @Entity annotiert Bean-Klasse als Entity Bean

- leichtgewichtiges Domänen-Objekt

- Entity Beans sind nicht mehr direkt entfernt zugreifbar!Entity Beans sind nicht mehr direkt entfernt zugreifbar!Entity Beans sind nicht mehr direkt entfernt zugreifbar!Entity Beans sind nicht mehr direkt entfernt zugreifbar!

Zugriff erfolgt nur noch über neu eingeführten javax.ejb.EntityManager zum:

- Erzeugen und Löschen von persistenten Entity-Instanzen

- Finden von Entitäten über Primärschlüssel

- Abfragen über Entitäten

BeispielBeispielBeispielBeispiel

@Stateless public class Product { EntityManager em; @Inject public void setEntityManager(EntityManager em) { this.em = em; } public int createProduct(String name, double price) { Product product = new Product(name, price); em.create(order); return order.getId(); } public Product find(int id) { return em.find(Product.class, id); } public void enterProduct(int custID, Product newProduct) { Customer cust = (Customer)em.find("Customer", custID); cust.getProducts().add(newProduct); newProduct.setCustomer(cust); } }

Page 136: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Alles wird viel einfacher! Seite 136 von total 218 Seiten

Entity Beans beherrschen nun Vererbung und Polymorphie:

- Polymorphe EJB QL-Abfragen sind nun zulässig

- kein Home Interface mehr nötig

- kein Business Interface mehr nötig (technisch gesehen)

- JavaBean-Stil

- Attribute sind nur per getter/setter-Methoden zugreifbar

- Eliminieren der komplexen, aufwendigen und fehleranfälligen Deployment Deskriptoren

- Beziehungen etc. werden in den Klassen per Annotationen deklariert

- kein DTO (Data Transfere Object) für Transport von Entity Bean-Daten mehr notwendig

- Entity Bean selbst wird transferiert (detached object)

- nach Änderungen am "detached object" können diese mit dem persistenten Zustand zusammengebracht werden (reattached object)

Beispiel: Bean KlasseBeispiel: Bean KlasseBeispiel: Bean KlasseBeispiel: Bean Klasse

@Entity @Table(name = "PURCHASE_ORDER") public class Order implements java.io.Serializable { private int id; private double total; private Collection<LineItem> lineItems; @Id(generate = GeneratorType.AUTO) public int getId() { return id; } public void setId(int id) { this.id = id; } public double getTotal() { return total; } public void setTotal(double total) { this.total = total;} public void addPurchase(String product, int quantity, double price) { if (lineItems == null) lineItems = new ArrayList<LineItem>(); LineItem item = new LineItem(); item.setOrder(this); ... } @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) @JoinColumn(name = "order_id") public Collection<LineItem> getLineItems() { return lineItems; } public void setLineItems(Collection<LineItem> lineItems) { this.lineItems = lineItems; } }

Page 137: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Alles wird viel einfacher! Seite 137 von total 218 Seiten

21.12 EJB QL

Weiterentwicklung der EJB QL sind:

Sub QueriesSub QueriesSub QueriesSub Queries

SELECT goodCustomer FROM Customer goodCustomer WHERE goodCustomer.balance < ( SELECT avg(c.balance) FROM Customer c )

GroupBy / HavingGroupBy / HavingGroupBy / HavingGroupBy / Having

SELECT c.status, avg(c.filledOrderCount), count(c) FROM Customer c GROUP BY c.status HAVING s.status IN (1, 2)

Explizite Explizite Explizite Explizite InnerInnerInnerInner----Joins und OuterJoins und OuterJoins und OuterJoins und Outer----Joins / ProjectionJoins / ProjectionJoins / ProjectionJoins / Projection

SELECT c.id, c.status FROM Customer c JOIN c.orders o WHERE o.count > 100

Liefert ein Array von java.lang.Object

SELECT new CustomerDetails(c.id, c.status, o.count) FROM Customer c JOIN c.orders o WHERE o.count > 100

Liefert ein Array von CustomerDetails

Bulk updates, Bulk deletesBulk updates, Bulk deletesBulk updates, Bulk deletesBulk updates, Bulk deletes

DELETE FROM Customer c WHERE o.status = "inactive" AND c.orders IS EMPTY

Auch werden native SQL-Abfragen unterstützt und weiter zusätzliche Funktionen in der WHERE-Klausel sind zulässig:

- UPPER

- LOWER

- TRIM

- POSITION

- CHARACTER_LENGTH

- CHAR_LENGTH

- BIT_LENGTH

- CURRENT_TIME

- CURRENT_DATE

- CURRENT_TIMESTAMP

Page 138: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Alles wird viel einfacher! Seite 138 von total 218 Seiten

Dynamische Abfragen, NamedDynamische Abfragen, NamedDynamische Abfragen, NamedDynamische Abfragen, Named----QueriesQueriesQueriesQueries

// Erzeugen einer NamedQuery ... @NamedQuery( name="findAllCustomersWithName", queryString="SELECT c FROM Customer c WHERE c.name LIKE :custName" ) ... // Nutzen einer NamedQuery ... @Inject public EntityManager em; customers = em.createNamedQuery("findAllCustomersWithName") .setParameter("custName", "Smith") .listResults(); ...

Polymorphe AbfragenPolymorphe AbfragenPolymorphe AbfragenPolymorphe Abfragen

Liefert als Ergebnis nicht nur den spezifizierten Typ, sondern auch alle dazugehörigen Subtypen.

21.13 Zusammenfassung

- Statt komplexer Komponenten einfache POJOs / POJIs

- Verkürzung der Entwicklungszeit

- Wegfall von überflüssigen Interfaces (Home Interface, Remote Interface und der Typen-Callback Interfaces)

- Bessere und einfachere Modellierbarkeit

- Einfache Java-Klassen mit allen Vorteilen von Container-Komponenten

- Statt Deployment Deskriptoren Meta-Annotation im Java-Code

- Nur noch eine Codebasis

- Erlaubt nun Prüfungen zur Kompilierungszeit

- Inversion of Control / Dependency Injection

- Configuration by Exception

- Vereinfachung der Entwicklung (Reduzierung Code und Entwicklungszeit)

- Mit EJB 3.0 wird die Komponententechnologie erheblich einfacher und gleichzeitig mächtiger.

- EJB 3.0 wird die Entwicklung von komponenten-basierten Systemen beschleunigen

- Konkurrenz .NET

- Das leidige Thema der konkurrierenden Persistenzstrategien innerhalb von J2EE/J2SE wird mit EJB 3.0 endlich behoben

Page 139: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Entwicklungstools für J2EE Seite 139 von total 218 Seiten

E E E E Aufsetzen und Konfiguration der EntwickAufsetzen und Konfiguration der EntwickAufsetzen und Konfiguration der EntwickAufsetzen und Konfiguration der Entwicklungsumgebunglungsumgebunglungsumgebunglungsumgebung

22222222 Entwicklungstools für J2EEEntwicklungstools für J2EEEntwicklungstools für J2EEEntwicklungstools für J2EE

Der Markt bietet neben kommerziellen AS Produkten, die mehr oder weniger hohe Lizenzkosten beinhalten auch einige Open-Source Projekte an. Dieses Skript und die aufgeführten Beispiele fokussieren bewusst auf OS Tools um das Testen der Lerninhalte so einfach wie möglich zu gestalten.

Die folgenden Installationsanleitungen und die Beschreibung der Entwicklungs-Tools basieren auf den im Skript aufgeführten Beispielsübungen und deren Lösungen.

Die Beispiele in diesem Skript basieren auf den nachfolgend installierten Versionen. Neue Releases sind meist "down-kompatible", eventuelle Anpassungen an den Source Code der Beispiele müssen gemäss den entsprechenden Handbüchern gemacht werden. Die Beispiele sind auch auf einer EJB 3 konformen Umgebung einsetzbar, entsprechen jedoch nicht der EJB 3 Spezification.

23232323 Java J2SE / J2EE InstallationJava J2SE / J2EE InstallationJava J2SE / J2EE InstallationJava J2SE / J2EE Installation

Neben einem JDK (z.B. JDK1.5) muss für die Entwicklung von J2EE Applikationen die J2EE Umgebung von Sun™ installiert werden (z.B. J2EESDK1.4). Beide Dateien, sowie etliche Dokumentationen können unter http://java.sun.com bezogen und lokal installiert werden.

J2SE installieren:J2SE installieren:J2SE installieren:J2SE installieren:

ausführen: jdk-1_5….exe

von: [CD]\install\j2se oder von http://java.sun.com

J2EE installieren:J2EE installieren:J2EE installieren:J2EE installieren:

ausführen: j2eesdk-1_4….exe

von: [CD]\install\j2ee oder von http://java.sun.com

Page 140: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Eclipse als Entwicklungsumgebung Seite 140 von total 218 Seiten

24242424 Eclipse als EntwicklungsumgebungEclipse als EntwicklungsumgebungEclipse als EntwicklungsumgebungEclipse als Entwicklungsumgebung

Eclipse.org ist die Plattform für mehr Hintergrundinformationen betreffend der Eclipse Entwicklungsumgebung:

- Basiert auf Initiative von IBM

- Mitarbeit von Borland, webgain, GNX, serena, Rational, redhat, SuSe, TogetherSoft, ...

- Entwickelt von mehr als 1200 Software Entwicklern von mehr als 150 führenden Software Herstellern aus mehr als 60 verschiedenen Ländern

( einige ) Plattform Komponenten:

- Ant ( integration of Ant scripting )

- Compare ( universal compare facility )

- Debug ( generic execution and debug framework )

- Help ( platform help system )

24.1 Installation

Die aktuelle Version von Eclipse kann als ZIP Datei von http://www.eclipse.org oder direkt unter http://mirror.switch.ch/mirror/eclipse/downloads/ bezogen werden und folgendermassen installiert werden:

zu einem lokalen Verzeichnis dekomprimieren (Verzeichnisstruktur sollte keine Leerzeichen enthalten, wie z.B. "Eigene Dateien"):

entpacken: eclipse-SDK-3.2-win32.zip

von: [CD]\install\eclipse

nach: ...\ee

bevorzugte Plugbevorzugte Plugbevorzugte Plugbevorzugte Plug----Ins installieren, z.B: Quantum DB Explorer:Ins installieren, z.B: Quantum DB Explorer:Ins installieren, z.B: Quantum DB Explorer:Ins installieren, z.B: Quantum DB Explorer:

entpacken: Quantum_2.4.5_for_Eclipse_3.zip

von: [CD]\install\eclipse plugins

nach: ...\ee\eclipse\

bevorzugte Plugbevorzugte Plugbevorzugte Plugbevorzugte Plug----Ins installieren, z.B: XMLBuIns installieren, z.B: XMLBuIns installieren, z.B: XMLBuIns installieren, z.B: XMLBuddy:ddy:ddy:ddy:

entpacken: xmlbuddy_2.0.72.zip

von: [CD]\install\eclipse plugins

nach: ...\ee\eclipse\plugins

weitere Eclipse Plugweitere Eclipse Plugweitere Eclipse Plugweitere Eclipse Plug----Ins unter:Ins unter:Ins unter:Ins unter:

http://www.eclipseplugincentral.com

24.2 Eclipse starten

Im Insallationsverzeichnis auf das entsprechende Icon klicken.

Page 141: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 JBoss AS Seite 141 von total 218 Seiten

25252525 JBoss JBoss JBoss JBoss ASASASAS

JBoss war ursprünglich als EJB Kontainer konzipiert, wurde aber zu einem kompletten Applikations Server für J2EE Applikationen weiterentwickelt.

Entstanden 1999 - JBoss ist das Produkt einer OpenSource Developer Community die das erklärte Ziel hatte, den besten J2EE-compliant Applikationsserver auf dem Markt zu entwickeln

- 1000 Developer weltweit

- JBoss ist heute wahrscheinlich der verbreitetste EJB Server

- 4000 Downloads des EJB Servers pro Tag (mehr als manche kommerzielle Hersteller insgesamt haben)

- Die Distribution erfolgt unter LGPL License, d.h. JBoss kostet keine Lizenzgebühren.

- JBoss hat sich als eine vitale Alternative zu überpreisten EJB Servern im kommerziellen Umfeld entwickelt.

25.1 Installation

Die aktuelle Version von JBoss kann als ZIP Datei von http://www.jboss.org bezogen werden und folgendermassen installiert werden:

zum lokalen Verzeichnis C:\ee dekomprimieren (Verzeichnisstruktur sollte keine Leerzeichen enthalten, wie z.B. "Eigene Dateien")

entpacken: jboss-4.0.4.GA.zip

von: [CD]\install\jboss

oder http://www.jboss.org

nach: ...\ee\

JAVA_HOME Umgebungsvariable als Benutzer- oder Systemvariablen entsprechend der installierten JDK Version definieren/ergänzen:

25.2 JBoss AS starten / stoppen

- das run.bat Skript in \bin Verzeichnis der JBoss Installation ausführen

- mit http://localhost:8080 den JBoss Server testen.

- CTRL+C, shutdown.bat oder über die Management Konsole http://localhost:8080/jmx-console

kann der JBoss Applikations Server gestoppt werden.

Page 142: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 JBoss AS Seite 142 von total 218 Seiten

25.3 JBoss Verzeichnisstruktur

Das Installationsverzeichnis enthält fünf Ordner:

- bin Skript Files

- client JAR Dateien für Client Applikationen, jbossall-client.jar enthält sämtliche Lybraries

- docs enthält XML DTD für JBoss Referenzen sowie example J2EE Connector Architecture Dateien für das Anbinden von externen Ressourcen (z.B. MySQL, etc.)

- lib JBoss microkernel JAR Lybraries

- server die verschiedenen server Konfigurationen

- all startet alle zur Verfüfung stehenden Dienste wie: RMI-IIOP, Clustering und WEB-Service

- default started in der standart Konfiguration

- ee (erstellter) benutzerspezifischer Server für die EnterpriseEducation Beispiele: ee4, ... (als Kopie des default Verzeichnis)

- minimal minimum Requirement für den JBoss Server mit: JNDI und URL Deployment Scanner ohne: WEB- oder EJB Container, ohne JMS

Der entsprechende Server ist, wenn gestartet (z.B. run –c default), auch zugleich das entsprechende Verzeichnis, indem alle Deployments stattfinden und alle LOGs geschrieben werden. Die Verzeichnisstruktur beschreibt:

- conf enthält die jboss-service.xml Datei, die den core Service spezifiziert

- data Verzeichnis für die Hypersonic Datenbank

- deploy HOT-Deployment Verzeichnis für JAR, WAR und EAR Dateien

- lib JAR Dateien für die Server Konfiguration und Ressourcen z.B. "fremde" JDBC Drivers, etc.

- log Verzeichnis für die Logging Informationen

- tmp Temporäres Verzeichnis für Deployment, etc.

- work JSP-Kompilationsverzeichnis für Tomcat

25.4 Benutzerspezifischer Server einrichten

Als Default wird der "default" Sever gestartet. Alle serverspezifischen Informationen sind im entsprechenden Verzeichnis. Mit den Beispielsapplikationen benutzen wir mySQL als Datenbank. Um einen entsprechenden benutzerspezifischen Server "ee" für die EnterpriseEducation Beispiele zu definieren sind die folgenden Schritte massgebend:

[JBoss_Home]\server\default Verzeichnis kopieren zu "ee"

kopieren: Verzeichnis

von: [JBoss_Home]\server\default

nach: [JBoss_Home]\server\ee

Page 143: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 JBoss AS Seite 143 von total 218 Seiten

Der JDBC Treiber wird als "MySQL Connector" auf der offiziellen Website von MySQL angeboten, wobei die im Root des heruntergeladenen TAR- oder ZIP Verzeichnis befindliche JAR-Datei von Bedeutung ist. Diese im JAR-Format befindliche Java-Bibliothek muss in den /lib Ordner der JBoss Installation kopiert werden - damit erhält der Application Server den Zugriff darauf, und die Voraussetzung, mit dem MySQL Server kommunizieren zu können.

JDBC Driver mysql-connector-java-3.0.15-ga-bin.jar oder aktuellen Connector/J von http://www.mysql.com ins Verzeichnis [JBoss_Home]\server\ee\lib kopieren:

kopieren: mysql-connector-java-5.0.3-bin.jar

von: [CD]\install\mysql

http://www.mysql.com

nach: [JBoss_Home]\server\ee\lib

Die logische Repräsentation der MySQL Datenbank innerhalb der J2EE Programme wird nicht, wie vermutet, durch ein direktes Verwenden des JDBC-Treibers geschaffen, sondern über eine abstrakte Datenbankschnittstelle, DataSource genannt. Durch eine neu anzulegende Konfigurationsdatei im /deploy Ordner der JBoss Installation können DataSources zentral durch den Namens- und Verzeichnisdienst verwaltet werden.

In /docs/examples/jca/mysql-ds.xml befindet sich eine Vorlage, die den Verhältnissen entsprechend angepasst werden muss.

mySQL DataSource Konfigurationsdatei mySQL DataSource Konfigurationsdatei mySQL DataSource Konfigurationsdatei mySQL DataSource Konfigurationsdatei mysql-ds.xml:

kopieren: mysql-ds.xml

nach: [JBoss_Home]\server\ee\deploy

anpassen: benutzerspezifisch konfigurieren

<?xml version="1.0" encoding="UTF-8"?>

<datasources> <local-tx-datasource> <jndi-name>mySSqlDS</jndi-name> <connection-url> jdbc:mysql://localhost:3306/ee </connection-url> <driver-class>com.mysql.jdbc.Driver</driver-class> <user-name>root</user-name> <password></password> </local-tx-datasource> </datasources>

25.5 Benutzerspezifischer JBoss-Server starten

Um den neu erstellten Server "ee" zu starten muss vorgängig mySQL installiert, sowie die entsprechende Datenbank "ee" mit den entsprechenden Benutzerrechten erstellt sein.

- cd\ C:\ee\ jboss-4.0.4.GA\bin\

- run -c ee

Das entsprechende Script um den Server zu stoppen ist: shutdown -S

Page 144: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 mySQL Datenbankserver installieren und Datenbank erstellen Seite 144 von total 218 Seiten

26262626 mySQL Datenbankserver installieren und Datenbank erstellenmySQL Datenbankserver installieren und Datenbank erstellenmySQL Datenbankserver installieren und Datenbank erstellenmySQL Datenbankserver installieren und Datenbank erstellen

mySQL ist eine der verbreitetsten Open Source Datenbanken und wird von vielen Organisationen kommerziell benutzt.

26.1 Installation

entpacken: mysql-noinstall-5.0.24-win32.zip

von: [CD]\install\mysql

oder http://www.mysql.com

nach: c:\ (entziptes Verzeich(entziptes Verzeich(entziptes Verzeich(entziptes Verzeichnis umbenennen zu mysql!)nis umbenennen zu mysql!)nis umbenennen zu mysql!)nis umbenennen zu mysql!)

mySQL kann bei der Installation und beim Starten des DBMS Dienstes Probleme verursachen wenn diese mySQL Distribution nicht im c:\ (root) Verzeichnis liegt:

26.2 mySQL-Tools

Zur windowbasierten Administration von mySQL DBMS können verschiedene Tools installiert werden, z.B:

entpacken: mysql-gui-tools-noinstall-5.0-r2-win32

von: [CD]\install\mysql

oder http://www.mysql.com

nach: c:\

26.3 EnterpriseEducation DB anlegen

Mit Administrationstool oder per Konsole den Datenbankserver starten und die Datenbank "ee" erstellen:

- c:\>set path %PATH%;c:\mysql\bin

- c:\>mysqld-nt.exe --install - c:\>net start mysql

- c:\>mysqladmin -u root create ee

- c:\>mysql –u root –D e

- mysql> GRANT ALL PRIVILEGES ON ee.* TO 'Ihr_Name'@localhost IDENTIFIED BY 'Ihr_Password'

Page 145: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 EJB Applikation mit Eclipse / JBoss Seite 145 von total 218 Seiten

27272727 EJB Applikation mit Eclipse / JBossEJB Applikation mit Eclipse / JBossEJB Applikation mit Eclipse / JBossEJB Applikation mit Eclipse / JBoss

Für das Deployen einer mit der Eclipse Plattform erstellten EJB Applikation steht eine build.xml Datei zur Verfügung. Diese muss im root Verzeichnis des Eclipse Projectes liegen und implementiert die folgenden Targets:

- deploy Deployment von Sample Applikationen

- run-client-application Ausführen von Client Applikation

- run-sql-script Ausführen von SQL Statements

Apache Ant ist ein Java basiertes Build Tool und ist integrierter Bestandteil der Eclipse Entwicklungs- umgebung. Information und Beispielanwendungen sind unter http://ant.apache.org erhältlich.

Apache Ant build.xml Script für die Enterprise Education Beispiele:Apache Ant build.xml Script für die Enterprise Education Beispiele:Apache Ant build.xml Script für die Enterprise Education Beispiele:Apache Ant build.xml Script für die Enterprise Education Beispiele:

<?xml version="1.0" encoding="UTF-8" ?> <!-- Enterprise Education: deploy : Deployment von Sample Applikationen run-client-application : Ausführen von Client Applikation run-sql-script : Ausführen von SQL Statements Author : s.metzler Datum : 2006-08-20 Version : 3.0 --> <project name="EnterpriseEducation Packaging and Deployment Script" default="deploy" basedir="."> <!-- Property Datei: enthält Applikationsspezifische Parameter --> <property file="${basedir}/properties/enterpriseeducation.properties" /> <!-- Resources dir: enthält jndi.properties Datei für den Client --> <property name="resources.dir" value="${basedir}/resources" /> <!-- Client Classpath: Classpath Parameter für den Client --> <path id="client.classpath"> <pathelement location="${resources.dir}" /> <fileset dir="${jboss.home}/client"> <include name="**/*.jar" /> </fileset> </path> <!-- Build Classpath: Classpath Parameter für den Build Prozess --> <path id="build.classpath"> <path refid="client.classpath" /> <pathelement location="${build.dir}" /> <pathelement location="${servlet.jar}" /> </path> <!-- SQL Classpath: Classpath Parameter für die Datenbankanbindung --> <path id="sql.classpath"> <pathelement location="${mysql.driver.jar}" /> </path>

Page 146: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 EJB Applikation mit Eclipse / JBoss Seite 146 von total 218 Seiten

<!-- depoly target: Deployment von Sample Applikationen --> <!-- ++++++++++++++++++++++++++++++++++++++++++++++++++ --> <target name="deploy"> <mkdir dir="${build.dir}" /> <!-- Bean Klassen kompilieren --> <javac destdir="${build.dir}" classpathref="build.classpath"> <src path="${src.dir}/${ejb.dir}" /> </javac> <!-- Client Klassen kompilieren --> <javac destdir="${build.dir}" classpathref="build.classpath"> <src path="${src.dir}/${client.dir}" /> </javac> <!-- Bean Archivedatei löschen --> <delete file="jar/${app.name}.jar" /> <!-- Bean Deployment Descriptor kopieren --> <copy file="dd/ejb-jar.xml" tofile="${build.dir}/ejb-jar.xml" overwrite="true" /> <copy file="dd/jboss.xml" tofile="${build.dir}/jboss.xml" overwrite="true" /> <!-- Bean Archivedatei bilden --> <jar jarfile="jar/${app.name}.jar"> <metainf dir="${build.dir}" includes="ejb-jar.xml, jboss.xml" /> <fileset dir="${build.dir}"> <include name="${ejb.dir}/**" /> </fileset> </jar> <!-- Bean Archivedatei deployen --> <copy file="jar/${app.name}.jar" todir="${jboss.deploy.dir}" /> <!-- Client Archivedatei löschen --> <delete file="jar/${app.name}AppClient.jar" /> <!-- Client Deployment Descriptor(en) kopieren --> <copy file="dd/application-client.xml" tofile="${build.dir}/application-client.xml" overwrite="true" /> <copy file="dd/jboss-client.xml" tofile="${build.dir}/jboss-client.xml" overwrite="true" /> <!-- Client Archivedatei bilden --> <jar jarfile="jar/${app.name}AppClient.jar"> <metainf dir="${build.dir}" includes="application-client.xml, jboss-client.xml" /> <fileset dir="${build.dir}"> <include name="${resources.dir}/jndi.properties" /> <include name="${client.dir}/**" /> <include name="${ejb.dir}/${app.name}Home.class" /> <include name="${ejb.dir}/${app.name}.class" /> </fileset> <fileset dir="${resources.dir}"> <include name="jndi.properties" /> </fileset> </jar> <!-- Tempöräres Build Verzeichnis löschen --> <delete dir="${build.dir}" /> </target> <!-- run-client-application target: Ausführen von Client Applikation --> <!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> <target name="run-client-application" depends="deploy"> <java classname="client.${app.name}Client" fork="yes"> <classpath> <pathelement path="jar/${app.name}AppClient.jar" /> <path refid="client.classpath" /> <pathelement path="${java.class.path}" /> </classpath> </java> </target>

Page 147: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 EJB Applikation mit Eclipse / JBoss Seite 147 von total 218 Seiten

<!-- run-sql-script target: Ausführen von SQL Statements --> <!-- +++++++++++++++++++++++++++++++++++++++++++++++++++ --> <target name="run-sql-script"> <sql classpathref="sql.classpath" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost/${database}" userid="${user}" password="${password}" src="sql/${sql.data}" /> </target> </project>

Die Parameter des InitialContext PROVIDER_URL, NITIAL_CONTEXT_FACTORY, und URL_PKG_PREFIXES sind in einer Property Datei definiert:

resources/jndi.proresources/jndi.proresources/jndi.proresources/jndi.propertiespertiespertiesperties

# Definiert die JBoss Server Context Properties java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory java.naming.provider.url=jnp://localhost:1099 java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces

Die zur Ausführung dieses Skripts notwendigen applikationsspezifischen Parameter sind in einer PropertyDatei untergebracht:

properties/enterpriseeducation.propertiesproperties/enterpriseeducation.propertiesproperties/enterpriseeducation.propertiesproperties/enterpriseeducation.properties

# Enterprise Education Properties # zum Deployen und Ausführen der JBoss Beispiele # Pfad des Projekt Verzeichnis ee.home=D:/ee # JBoss-spezifische Einstellungen # ------------------------------- jboss.home=${ee.home}/jboss-4.0.4.GA # Pfad des JBoss Server jboss.server=${jboss.home}/server/ee # Pfad des deploy Ordner jboss.deploy.dir=${jboss.server}/deploy # den Pfad des Servlet Archives angeben servlet.jar=${jboss.server}/lib/javax.servlet.jar # Applikations-spezifische Einstellungen # ------------------------------------- # Name der Applikation app.name=MoneyExchange # Source Verzeichnis src.dir=${basedir}/src # Beans Verzeichnis ejb.dir=beans # Client Verzeichnis client.dir=client # Build Verzeichnis (temporäres Verzeichnis)

Page 148: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 EJB Applikation mit Eclipse / JBoss Seite 148 von total 218 Seiten

build.dir=${basedir}/build # Name der ClientApplikation j2ee.clientName=MonexExchangeClient # Datenbank-spezifische Einstellungen # ------------------------------------- # Connector/J Archive mysql.driver.jar=${ee.home}/lib/mysql-connector-java-5.0.3-bin.jar # SQL Skript Datei sql.data=create_rates_table.sql # Benutzereinstellungen für DBMS user=root password= database=ee

Das Apache Ant Skript verlangt zusammen mit den applikationsspezifischen Parametern nach einer entsprechenden Struktur innerhalb der Eclipse Entwicklungsumgebung. Diese ist wie folgt abgebildet (Beispiel MoneyExchange):

Project: ee4 (EnterpriseEducation BeispProject: ee4 (EnterpriseEducation BeispProject: ee4 (EnterpriseEducation BeispProject: ee4 (EnterpriseEducation Beispiel 4) iel 4) iel 4) iel 4)

- ee4 Projektordner

- bin default output folder

- beans wird generiert

- client wird genertiert

- dd Deployment Descriptor Dateien

- jar generierte JAR Dateien

- properties Property Dateien

- resources Resource Dateien

- sql SQL Skript Dateien

- src source folder on build path

- beans Home Interface Class Remote Interface Class Bean Implementation Class

- client Client Applikations Class

- build.xml Apache Ant Datei liegt im Project-Verzeichnis!

Classpath Einstellungen:Classpath Einstellungen:Classpath Einstellungen:Classpath Einstellungen:

Page 149: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Tomcat Seite 149 von total 218 Seiten

28282828 TomcatTomcatTomcatTomcat

Tomcat Version 5 implementiert die Servlet 2.4- und JavaServer Pages 2.0 Specifikation, definiert durch den Java Community Process (http://www.jcp.org/) und beinhaltet viele zusätzliche Funktionen die eine Entwicklung und das Deployen von Web Applikationen unterstützen.

28.1 Server Architektur

Web Applokationen liegen im Verzeichnis [Tomcat_Home][Tomcat_Home][Tomcat_Home][Tomcat_Home]\\\\webappswebappswebappswebapps\\\\. Per Default soll ein \\\\WEBWEBWEBWEB----INFINFINFINF\\\\ Ordner die Deploydateien enthalten.

Der entsprechende Eintrag in der WebserverWebserverWebserverWebserver----KonfigurationKonfigurationKonfigurationKonfigurationsdateisdateisdateisdatei [TOMCAT_HOME][TOMCAT_HOME][TOMCAT_HOME][TOMCAT_HOME]\\\\confconfconfconf\\\\server.xmlserver.xmlserver.xmlserver.xml weist auf das entsprechende Verzeichnis der WEB-Applikation.

Ressourcen, die direkt zum Client geschickt werden oder vom Client aus ansprechbar sind, wie z.B. .jsp-, .html- und .gif-Dateien sowie clientseitig nutzbare .class-Applets, befinden sich nicht unterhalb des Verzeichnisses WEB-INF, sondern parallel dazu.

- Unter /WEB_INF/classes befinden sich Servlets, JavaBeans und andere Server-seitige .class-Dateien.

- Unter /WEB_INF/lib befinden sich .jar-Archive.

- /WEB_INF/web.xml ist die Konfigurationsdatei der Web Application.

- In die Webserver-Konfigurationsdatei [TOMCAT_HOME]\conf\server.xml muss die Web Application mit einem Context-Element angemeldet werden.

Beschreibung des Context TagsBeschreibung des Context TagsBeschreibung des Context TagsBeschreibung des Context Tags

ElementElementElementElement AttributeAttributeAttributeAttribute BeschreibungBeschreibungBeschreibungBeschreibung DefaultDefaultDefaultDefault

Context path URL Fragment um den Kontext zu identifizieren. none, must be specified

docBase Path zum Projektverzeichnis. none, must be specified

reloadable Erlaubt das "Reloading" der Servlets für diesen Kontext. true

debug Debug Level für das Logging 0

Page 150: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Tomcat Seite 150 von total 218 Seiten

Beispiel eines Eintrags in der Webserver KBeispiel eines Eintrags in der Webserver KBeispiel eines Eintrags in der Webserver KBeispiel eines Eintrags in der Webserver Konfigurationsdatei:onfigurationsdatei:onfigurationsdatei:onfigurationsdatei:

<Context path="/examples" docBase="webapps/examples" debug="0" reloadable="true" >

oder:

<Context path="/ee4" docBase="C:\ee\workspace\ee4" workDir="C:\ee\workspace\ee4\work" /> debug="0" reloadable="true" >

28.2 Installation

entpacken: jakarta-tomcat-5.0.28.zip

von: [CD]\install\tomcat

oder von http://jakarta.apache.org/site/binindex.cgi

nach: ...\ee\

Tomcat PlugTomcat PlugTomcat PlugTomcat Plug----In installierenIn installierenIn installierenIn installieren

entpacken: tomcatPluginV31.zip

von: [CD]\install\eclipse plugins

nach: ...\ee\eclipse\plugins

Um einen Portkonflikt mit dem JBoss AS zu vermeiden muss der Port in der Datei ..\conf\server.xml umkonfiguriert werden.

- <Connector port="8090" …

- Tomcat starten mit : http://localhost:8090

Page 151: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 151 von total 218 Seiten

rate + 100 amount x (

100 )years

FFFF Lösungen zu den ÜbungenLösungen zu den ÜbungenLösungen zu den ÜbungenLösungen zu den Übungen

29292929 Lösungen zu ÜbLösungen zu ÜbLösungen zu ÜbLösungen zu Übungen aus dem Skriptungen aus dem Skriptungen aus dem Skriptungen aus dem Skript

Die abgedruckten Lösungen sind auch auf beiligender CD enthalten.

29.1 Lösung zu Übung ee1 : Stateless Session Bean – Zinsberechnung

Formel zur Zinsberechnung:

Home Interface: ZinsHome.javaHome Interface: ZinsHome.javaHome Interface: ZinsHome.javaHome Interface: ZinsHome.java

package ejb; import java.rmi.RemoteException; import javax.ejb.CreateException; import javax.ejb.EJBHome; public interface ZinsHome extends EJBHome { Zins create() throws CreateException, RemoteException; }

Remote Interface: Zins.javaRemote Interface: Zins.javaRemote Interface: Zins.javaRemote Interface: Zins.java

package ejb; import javax.ejb.EJBObject; import java.rmi.RemoteException; public interface Zins extends EJBObject { double calculate(double amount, double rate, int years) throws RemoteException; }

Bean Class: ZinsBean.javaBean Class: ZinsBean.javaBean Class: ZinsBean.javaBean Class: ZinsBean.java

package ejb;

import javax.ejb.SessionBean; import javax.ejb.SessionContext;

public class ZinsBean implements SessionBean {

public double calculate(double amount, double rate, int years) { return amount * Math.pow((rate / 100.0) + 1.0, (double) years); }

public void ejbCreate() {} public void ejbRemove() {} public void ejbActivate() {} public void ejbPassivate() {} public void setSessionContext(SessionContext sc) { } }

Page 152: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 152 von total 218 Seiten

Client Application: ZinsClient.javaClient Application: ZinsClient.javaClient Application: ZinsClient.javaClient Application: ZinsClient.java

package client; import javax.naming.Context; import javax.naming.InitialContext; import javax.rmi.PortableRemoteObject; import ejb.Zins; import ejb.ZinsHome; public class ZinsClient { public static void main(String[] args) { double amount = 100.0; double rate = 10.0; int years = 5; try { Context initial = new InitialContext(); Object objref = initial.lookup("ZinsBean"); ZinsHome home = (ZinsHome) PortableRemoteObject.narrow(objref, ZinsHome.class); Zins zins = home.create(); System.out.println("Betrag:\t" + amount + "\nZins:\t" + rate + "\nJahre:\t" + years); System.out.println("Result:\t" + zins.calculate(amount, rate, years)); } catch (Exception ex) { System.err.println("unexpected exception!"); ex.printStackTrace(); } } }

Output:Output:Output:Output:

Betrag: 100.0 Zins: 10.0 Jahre: 5 Result: 161.05100000000004

Page 153: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 153 von total 218 Seiten

29.2 Lösung zu Übung ee2 : Stateful Session Bean – Kontoführung

Home Interface: TellerHome.javaHome Interface: TellerHome.javaHome Interface: TellerHome.javaHome Interface: TellerHome.java

package ejb; import java.rmi.RemoteException; import javax.ejb.CreateException; import javax.ejb.EJBHome; public interface TellerHome extends EJBHome { Teller create() throws CreateException, RemoteException; }

Remote Interface: Teller.javaRemote Interface: Teller.javaRemote Interface: Teller.javaRemote Interface: Teller.java

package ejb; import javax.ejb.EJBObject; import java.rmi.RemoteException; public interface Teller extends EJBObject { public void depositMoney(float inAmount) throws RemoteException; public void withdrawMoney(float inAmount) throws RemoteException; public float getAccountBalance() throws RemoteException; public float getRate() throws RemoteException; }

Page 154: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 154 von total 218 Seiten

Bean Class: TellerBean.javaBean Class: TellerBean.javaBean Class: TellerBean.javaBean Class: TellerBean.java

package ejb;

import javax.ejb.SessionBean; import javax.ejb.SessionContext; import javax.naming.Context; import javax.naming.InitialContext;

public class TellerBean implements SessionBean { private float accountBalance; private float rate = 0.5f; private SessionContext context;

public float getRate() { return rate; }

public void depositMoney(float inAmount) { accountBalance += inAmount; System.out.println("Deposition of " + inAmount + ".- CHF!"); }

public void withdrawMoney(float inAmount) { accountBalance -= inAmount; System.out.println("Withdrawel of " + inAmount + ".- CHF!"); }

public float getAccountBalance() { System.out.println("User requested account balance!"); return accountBalance; } public void setSessionContext(SessionContext sc) { try { InitialContext ic = new InitialContext(); Context local = (Context) ic.lookup("java:comp/env"); Float interestrate = (Float) local.lookup("Zins"); rate = interestrate.floatValue(); System.out.println("AutomaticTellerBean context set!"); System.out.println("NEW RATE SET TO: " + rate); } catch (javax.naming.NamingException e) { e.printStackTrace(); } System.out.println("AutomaticTellerBean context set!"); }

public void ejbCreate() { System.out.println("AutomaticTellerBean created!"); }

public void ejbRemove() { System.out.println("AutomaticTellerBean removed!"); }

public void ejbActivate() { System.out.println("AutomaticTellerBean activated!"); }

public void ejbPassivate() { System.out.println("AutomaticTellerBean passivated!"); } }

Page 155: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 155 von total 218 Seiten

Client Application: Client Application: Client Application: Client Application: TellerClient.javaTellerClient.javaTellerClient.javaTellerClient.java

package client;

import javax.naming.Context; import javax.naming.InitialContext; import javax.rmi.PortableRemoteObject;

import ejb.Teller; import ejb.TellerHome;

public class TellerClient { public static void main(String[] args) { try {

// create initial context Context initial = new InitialContext();

// get home interface TellerHome home = (TellerHome) PortableRemoteObject.narrow( initial.lookup("TellerBean"), TellerHome.class);

// Get ejb object Teller myTeller = home.create();

// deposit money on account myTeller.depositMoney(500f); System.out.println("your deposit:\t500"); // withdraw money on account myTeller.withdrawMoney(250f); System.out.println("your withdraw:\t250");

// deposit money on account myTeller.depositMoney(350f); System.out.println("your deposit:\t350");

// print AccountBalance(myTeller); System.out.println("\nyou have now\t" + myTeller.getAccountBalance() + " on your account!");

// print current rate (all Teller Beans); System.out.println("the rate is \t" + myTeller.getRate() + "% for all Teller Beans!");

} catch (Exception e) { e.printStackTrace(); } } }

Output:Output:Output:Output:

your deposit: 500 your withdraw: 250 your deposit: 350 you have now 600.0 on your account! the rate is 1.0% for all Teller Beans!

Page 156: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 156 von total 218 Seiten

29.3 Lösung zu Übung ee3 : CMP 1.0 Entity Bean – Personenverwaltung

Home Interface: PersonHome.javaHome Interface: PersonHome.javaHome Interface: PersonHome.javaHome Interface: PersonHome.java

package ejb;

import java.rmi.RemoteException; import java.util.Collection; import javax.ejb.EJBHome; import javax.ejb.CreateException; import javax.ejb.FinderException;

public interface PersonHome extends EJBHome {

// create und finder Methoden deklarieren public Person create(String id, String name, String fname) throws CreateException, RemoteException;

// entsprechender Return Type festlegen ( [0..1] -> Person ) public Person findByPrimaryKey(String key) throws FinderException, RemoteException;

// entsprechender Return Type festlegen ([0..*] -> Collection public Collection findAll() throws FinderException, RemoteException; }

Remote Interface: Person.javaRemote Interface: Person.javaRemote Interface: Person.javaRemote Interface: Person.java

package ejb;

import java.rmi.RemoteException; import javax.ejb.EJBObject;

public interface Person extends EJBObject {

// public setter und getter Methoden der Entitäten deklarieren public void setId(String id) throws RemoteException; public void setName(String name) throws RemoteException; public void setFname(String fname) throws RemoteException;

public String getName() throws RemoteException; public String getFname() throws RemoteException; public String getId() throws RemoteException; }

Page 157: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 157 von total 218 Seiten

Bean Class: PersonBean.javaBean Class: PersonBean.javaBean Class: PersonBean.javaBean Class: PersonBean.java

package ejb;

import java.rmi.RemoteException; import javax.ejb.EJBException; import javax.ejb.EntityBean; import javax.ejb.EntityContext; import javax.ejb.RemoveException;

public class PersonBean implements EntityBean {

// DB felder als public attribute definieren public String id = ""; public String name = ""; public String fname = "";

// public setter und getter Methoden der Entitäten definieren public String getId() {return id;} public void setId(String id) {this.id = id;}

public String getName() {return name;} public void setName(String name) {this.name = name;}

public String getFname() {return fname;} public void setFname(String fname) {this.fname = fname;}

// Für jede create() Methode des Home Interfaces muss es eine // entsprechende ejbCreate() Methode mit derselben Signatur geben public String ejbCreate(String id, String name, String fname) { // Belegen der Bean Attribute mit den Übergabeparameter this.id = id; this.name = name; this.fname = fname; // Rückgabewertes ist Primary_Key Attribute return id; }

// Für jede create() Methode des Home Interfaces muss es eine // entsprechende ejbPostCreate() Methode mit derselben Signatur geben public void ejbPostCreate(String id, String name, String fname) { }

// sämliche Kontainer Lyfe Cycle Methoden müssen definiert werden public void setEntityContext(EntityContext arg0) throws EJBException, RemoteException { }

public void unsetEntityContext() throws EJBException, RemoteException { }

public void ejbRemove() throws RemoveException, EJBException, RemoteException { }

public void ejbActivate() throws EJBException, RemoteException { } public void ejbPassivate() throws EJBException, RemoteException { } public void ejbLoad() throws EJBException, RemoteException { } public void ejbStore() throws EJBException, RemoteException { } }

Page 158: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 158 von total 218 Seiten

Client Application: PersonClient.javaClient Application: PersonClient.javaClient Application: PersonClient.javaClient Application: PersonClient.java

package client;

import java.rmi.RemoteException; import java.util.Iterator; import javax.ejb.CreateException; import javax.ejb.FinderException; import javax.ejb.RemoveException; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.rmi.PortableRemoteObject; import ejb.Person; import ejb.PersonHome;

public class PersonClient {

private static PersonHome anPersonHome = getHomeObject(); private static Person anPerson = null; private static Iterator persons = null;

private static PersonHome getHomeObject() { PersonHome person = null; try { Context initial = new InitialContext(); Object objref = initial.lookup("PersonBean"); person = (PersonHome) PortableRemoteObject.narrow(objref, PersonHome.class); } catch (ClassCastException ce) {ce.printStackTrace(); } catch (NamingException ne) {ne.printStackTrace(); } return person; }

public static void main(String[] args) { create("100", "myName_100", "myFirstName_100"); create("101", "myName_101", "myFirstName_101"); create("102", "myName_102", "myFirstName_102"); create("103", "myName_103", "myFirstName_103"); create("104", "myName_104", "myFirstName_104"); findById("100"); modify("100", "myName_new", "myFirstName_new"); findAll(); remove("100"); remove("101"); remove("102"); remove("103"); remove("104"); }

private static void create(String id, String name, String fname) { try { anPerson = getHomeObject().create(id, name, fname); } catch (RemoteException re) {re.printStackTrace(); } catch (CreateException ce) {ce.printStackTrace(); } }

private static void findById(String id) { try { anPerson = getHomeObject().findByPrimaryKey(id); System.out.println("found: " + anPerson.getId() + " " + anPerson.getFname() + " " + anPerson.getName()); } catch (RemoteException re) {re.printStackTrace(); } catch (FinderException fe) {fe.printStackTrace(); } }

private static void findAll() {

Page 159: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 159 von total 218 Seiten

try { persons = getHomeObject().findAll().iterator(); while (persons.hasNext()) { anPerson = (Person) persons.next(); System.out.println("found: " + anPerson.getId() + " " + anPerson.getFname() + " " + anPerson.getName()); } } catch (RemoteException re) {re.printStackTrace(); } catch (FinderException fe) {fe.printStackTrace(); } }

private static void modify(String id, String name, String fname) { try { anPerson = getHomeObject().findByPrimaryKey(id); anPerson.setName(name); anPerson.setFname(fname); } catch (RemoteException re) {re.printStackTrace(); } catch (FinderException fe) {fe.printStackTrace(); } }

private static void remove(String id) { try { anPerson = getHomeObject().findByPrimaryKey(id); anPerson.remove(); } catch (RemoteException re) {re.printStackTrace(); } catch (FinderException fe) {fe.printStackTrace(); } catch (RemoveException re) {re.printStackTrace(); } } }

Output:Output:Output:Output:

found: 100 myFirstName_100 myName_100 found: 100 myFirstName_new myName_new found: 101 myFirstName_101 myName_101 found: 102 myFirstName_102 myName_102 found: 103 myFirstName_103 myName_103 found: 104 myFirstName_104 myName_104

Page 160: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 160 von total 218 Seiten

29.4 Lösung zu Übung ee3.1 : Entity Bean CMP 2.0 - Kundenverwaltung

Local Home Interface: AddressLocalHone.javaLocal Home Interface: AddressLocalHone.javaLocal Home Interface: AddressLocalHone.javaLocal Home Interface: AddressLocalHone.java

package ejb.address;

import javax.ejb.*;

public interface AddressLocalHome extends EJBLocalHome {

public AddressLocal create(String street, String location) throws CreateException;

// Methode findByPrimaryKey(...) muss deklariert werden public AddressLocal findByPrimaryKey(String id) throws FinderException; }

Local Remote Interface: AddressLocal.javaLocal Remote Interface: AddressLocal.javaLocal Remote Interface: AddressLocal.javaLocal Remote Interface: AddressLocal.java

package ejb.address;

import javax.ejb.*;

public interface AddressLocal extends EJBLocalObject {

public String getStreet();

public String getLocation(); }

Bean Class: ABean Class: ABean Class: ABean Class: AddressBean.javaddressBean.javaddressBean.javaddressBean.java

package ejb.address;

import javax.ejb.*;

public abstract class AddressBean implements EntityBean {

private EntityContext context;

// abstrakte getter/setter-Methoden - PERSISTENTE FELDER public abstract String getId(); public abstract void setId(String id);

public abstract String getStreet(); public abstract void setStreet(String street);

public abstract String getLocation(); public abstract void setLocation(String location);

public String ejbCreate(String street, String location) throws CreateException { System.out.println("AddressEJB: ejbCreate called"); setId(street + location); setStreet(street); setLocation(location); return null; }

public void ejbPostCreate(String street, String location) { System.out.println("AddressEJB: ejbPostCreate called"); }

public void ejbRemove() { System.out.println("AddressEJB: ejbRemove called"); }

public AddressBean() { }

public void setEntityContext(EntityContext context) {

Page 161: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 161 von total 218 Seiten

System.out.println("setEntityContextCalled"); this.context = context; }

public void unsetEntityContext() { System.out.println("AddressEJB: unsetEntityContextCalled"); this.context = null; }

public void ejbActivate() { Object id = context.getPrimaryKey(); System.out.println("AddressEJB: ejbActivate called" + id); }

public void ejbPassivate() { System.out.println("AddressEJB: ejbPassivate called"); }

public void ejbLoad() { System.out.println("AddressEJB: ejbLoad called"); }

public void ejbStore() { System.out.println("AddressEJB: ejbStore called"); } }

Local Home Interface: NameLocalHome.javaLocal Home Interface: NameLocalHome.javaLocal Home Interface: NameLocalHome.javaLocal Home Interface: NameLocalHome.java

package ejb.name;

import javax.ejb.*;

public interface NameLocalHome extends EJBLocalHome {

public NameLocal create(String id, String street, String location) throws CreateException;

// Methode findByPrimaryKey(...) muss deklariert werden public NameLocal findByPrimaryKey(String id) throws FinderException; }

Local Remote Interface: NameLocal.javaLocal Remote Interface: NameLocal.javaLocal Remote Interface: NameLocal.javaLocal Remote Interface: NameLocal.java

package ejb.name;

import javax.ejb.EJBLocalObject; import ejb.address.AddressLocal;

public interface NameLocal extends EJBLocalObject {

public AddressLocal getAddress(); public void setAddress(AddressLocal address); }

Page 162: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 162 von total 218 Seiten

(Remote) Home Interface: NameHome.java(Remote) Home Interface: NameHome.java(Remote) Home Interface: NameHome.java(Remote) Home Interface: NameHome.java

package ejb.name;

import java.rmi.RemoteException; import javax.ejb.*;

public interface NameHome extends EJBHome {

public Name create(String id, String name, String fname, String street, String location) throws CreateException, RemoteException;

//Methode findByPrimaryKey(...) muss deklariert werden public Name findByPrimaryKey(String id) throws FinderException, RemoteException; }

(Remote) Remote Interface: Name.java(Remote) Remote Interface: Name.java(Remote) Remote Interface: Name.java(Remote) Remote Interface: Name.java

package ejb.name;

import java.rmi.RemoteException; import javax.ejb.*;

public interface Name extends EJBObject {

public String getFullName() throws RemoteException; public String getFullAddress() throws RemoteException; }

Bean Class: NameBean.javaBean Class: NameBean.javaBean Class: NameBean.javaBean Class: NameBean.java

package ejb.name;

import javax.ejb.*; import javax.naming.*; import javax.rmi.PortableRemoteObject; import ejb.address.AddressLocalHome; import ejb.address.AddressLocal;

public abstract class NameBean implements EntityBean {

// Nicht PERSISTENTE FELDER private EntityContext context; private AddressLocalHome addressLocalHome;

// abstrakte getter/setter-Methoden - PERSISTENTE FELDER public abstract String getId(); public abstract void setId(String id);

public abstract String getName(); public abstract void setName(String name);

public abstract String getFname(); public abstract void setFname(String fname);

//abstrakte getter/setter-Methoden - RELATIONEN public abstract AddressLocal getAddress(); public abstract void setAddress(AddressLocal address);

public String ejbCreate(String id, String name, String fname, String street, String location) throws CreateException { setId(id); setName(name); setFname(fname); return null; }

public void ejbPostCreate(String id, String name, String fname, String street, String location) throws CreateException { System.out.println("ejbPostCreate called"); AddressLocal address = addressLocalHome.create(street, location);

Page 163: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 163 von total 218 Seiten

setAddress(address); }

// Business Methoden des REMOTE NTERFACE public String getFullName() { return getName() + ", " + getFname(); }

public String getFullAddress() { return getAddress().getStreet() + ", " + getAddress().getLocation(); }

public NameBean() { }

// LIFECYCLE METHODEN public void ejbRemove() { System.out.println("ejbRemove called"); }

public void setEntityContext(EntityContext context) { System.out.println("setEntityContextCalled"); this.context = context; try { Context ctx = new InitialContext(); Context localCtx = (Context) ctx.lookup("java:comp/env"); Object obj = localCtx.lookup("ejb/address"); addressLocalHome = (AddressLocalHome) PortableRemoteObject .narrow(obj, AddressLocalHome.class); } catch (NamingException e) { throw new EJBException(e); } }

public void unsetEntityContext() { System.out.println("unsetEntityContextCalled"); this.context = null; }

public void ejbActivate() { Object id = context.getPrimaryKey(); System.out.println("ejbActivate called" + id); }

public void ejbPassivate() { System.out.println("ejbPassivate called"); }

public void ejbLoad() { System.out.println("ejbLoad called"); }

public void ejbStore() { System.out.println("ejbStore called"); } }

Page 164: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 164 von total 218 Seiten

Client Application: CustomerClient.javaClient Application: CustomerClient.javaClient Application: CustomerClient.javaClient Application: CustomerClient.java

package client;

import javax.naming.Context; import javax.naming.InitialContext; import javax.rmi.PortableRemoteObject; import ejb.name.Name; import ejb.name.NameHome;

public class CustomerClient {

public static void main(String[] arg) { try { Context initial = new InitialContext(); Object objref = initial.lookup("NameBean"); NameHome home = (NameHome) PortableRemoteObject.narrow( objref, NameHome.class); Name cust1 = home.create("1", "name", "first", "street", "city"); Name cust2 = home.create("2", "name", "vorname", "strasse", "ort"); Name mycust1 = home.findByPrimaryKey("1"); System.out.println("found:\tNAME\t" + mycust1.getFullName() + "\tADDRESS\t" + mycust1.getFullAddress()); Name mycust2 = home.findByPrimaryKey("2"); System.out.println("found:\tNAME\t" + mycust2.getFullName() + "\tADDRESS\t" + mycust2.getFullAddress()); mycust1.remove(); mycust2.remove(); } catch (Exception ex) { System.err.println("unexpected exception!"); ex.printStackTrace(); } } }

Output:Output:Output:Output:

found: NAME name, first ADDRESS street, city found: NAME name, vorname ADDRESS strasse, ort

Page 165: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 165 von total 218 Seiten

29.5 Lösung zu Übung ee4 : DB Session Bean - Money Exchange

Home Interface: MoneyExchangeHome.javaHome Interface: MoneyExchangeHome.javaHome Interface: MoneyExchangeHome.javaHome Interface: MoneyExchangeHome.java

package beans;

import javax.ejb.EJBHome; import java.rmi.RemoteException; import javax.ejb.CreateException;

public interface MoneyExchangeHome extends EJBHome {

public MoneyExchange create() throws RemoteException, CreateException; }

Remote Interafce: MoneyExchange.javaRemote Interafce: MoneyExchange.javaRemote Interafce: MoneyExchange.javaRemote Interafce: MoneyExchange.java

package beans;

import java.rmi.RemoteException; import javax.ejb.EJBObject;

public interface MoneyExchange extends EJBObject {

public float change(float inAmount, String base, boolean jdbc) throws RemoteException; }

Bean Class: MoneyExchangeBean.javaBean Class: MoneyExchangeBean.javaBean Class: MoneyExchangeBean.javaBean Class: MoneyExchangeBean.java

package beans;

import javax.ejb.SessionBean; import javax.ejb.SessionContext; import javax.naming.*; import java.sql.*; import javax.sql.*;

public class MoneyExchangeBean implements SessionBean {

private InitialContext ictx; private DataSource ds; private Connection con; private Statement stmt; private ResultSet rs;

public float change(float inAmount, String base, boolean jdbc) { float rate = 1.0f; float result = 0.0f; String SQLQuery = "SELECT rate FROM rates WHERE basecur = '" + base + '"; if (jdbc) { //jdbc Connection to mySQL Database enterpriseeducation final String userName = "root"; final String password = ""; final String databaseUrl = "jdbc:mysql://localhost/ee"; try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException cnfe) { System.err.println("Driver not found: " + cnfe.getMessage()); System.exit(0); } Connection aConnection = null; try { aConnection = DriverManager.getConnection(databaseUrl, userName, password); } catch (SQLException sqle) {

Page 166: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 166 von total 218 Seiten

System.err.println("Could not get connection to db:" + sqle.getMessage()); System.exit(0); } ResultSet aResultSet = null; try { Statement aStatement = aConnection.createStatement(); aResultSet = aStatement.executeQuery(SQLQuery); if (aResultSet.next()) rate = aResultSet.getFloat("rate"); aConnection.close(); } catch (SQLException e) { System.err.println("Could not execute statement '" + SQLQuery + "':" + e.getMessage()); System.exit(0); } } else { // Database Connection over JNDI lookup try { ictx = new InitialContext(); ds = (DataSource) ictx.lookup("java:comp/env/jdbc/ExchangeTable"); con = ds.getConnection(); stmt = con.createStatement(); rs = stmt.executeQuery(SQLQuery); if (rs.next()) rate = rs.getFloat("rate"); con.close(); } catch (Exception ex) { ex.printStackTrace(); } } result = inAmount * rate; System.out.println(inAmount + "*" + rate + "=" + result + ":" + jdbc); return result; } public void setSessionContext(SessionContext sc) { System.out.println("MoneyExchangeBean context set !"); } public void ejbCreate() {System.out.println("ejbCreate called !");} public void ejbRemove() {System.out.println("ejbRemove called !");} public void ejbActivate() {System.out.println("ejbActivate called !");} public void ejbPassivate() {System.out.println("ejbPassivate called !");} }

Deployment Descriptor: Deployment Descriptor: Deployment Descriptor: Deployment Descriptor: ejbejbejbejb----jar.xmljar.xmljar.xmljar.xml

<?xml version="1.0" encoding="UTF-8"?>

<ejb-jar> <description>Money Exchange</description> <display-name>MoneyExchange</display-name> <enterprise-beans> <session> <ejb-name>moneyexchange</ejb-name> <home>beans.MoneyExchangeHome</home> <remote>beans.MoneyExchange</remote> <ejb-class>beans.MoneyExchangeBean</ejb-class> <session-type>Stateless</session-type> <transaction-type>Bean</transaction-type> <resource-ref> <res-ref-name>jdbc/ExchangeTable</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref> </session> </enterprise-beans> </ejb-jar>

Page 167: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 167 von total 218 Seiten

Deployment Descriptor: jboss.xml (JNDI Mapping)Deployment Descriptor: jboss.xml (JNDI Mapping)Deployment Descriptor: jboss.xml (JNDI Mapping)Deployment Descriptor: jboss.xml (JNDI Mapping)

<jboss> <enterprise-beans> <session> <ejb-name>moneyexchange</ejb-name> <jndi-name>ejb/moneyexchange</jndi-name> <resource-ref> <res-ref-name>jdbc/ExchangeTable</res-ref-name> <jndi-name>java:/mySQLDS</jndi-name> </resource-ref> </session> </enterprise-beans> </jboss>

Client Application: MoneyExchangeClient.javaClient Application: MoneyExchangeClient.javaClient Application: MoneyExchangeClient.javaClient Application: MoneyExchangeClient.java

package client;

import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Properties; import javax.naming.Context; import javax.naming.InitialContext; import javax.rmi.PortableRemoteObject; import beans.MoneyExchange; import beans.MoneyExchangeHome;

public class MoneyExchangeClient {

protected static Properties getInitialProperties() { Properties property = new Properties(); try { property.load(new FileInputStream("resources/jndi.properties")); } catch (FileNotFoundException e) { System.out.println("can't find file: jndi.properties"); } catch (IOException e) {e.printStackTrace();} return property; }

public static void main(String[] args) { // jdbc=true : JDBC database connection // jdbc=false : JNDI lookup database connection final boolean jdbc = false; final int amount = 100; final String changeTo = "USD"; try { // create initial context Context initial = new InitialContext(getInitialProperties()); // get home interface MoneyExchangeHome home = (MoneyExchangeHome) PortableRemoteObject .narrow(initial.lookup("ejb/moneyexchange"), MoneyExchangeHome.class); // get ejb object MoneyExchange aMoneyExchange = home.create(); // call methods on ejb System.out.println(amount + " CHF are " + aMoneyExchange.change(amount, changeTo, jdbc) + " " + changeTo); } catch (Exception e) {e.printStackTrace();} }}

Page 168: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 168 von total 218 Seiten

mySQL Script: create_rates_table.sql : mySQL Script: create_rates_table.sql : mySQL Script: create_rates_table.sql : mySQL Script: create_rates_table.sql :

DROP TABLE IF EXISTS RATES;

CREATE TABLE RATES( ID VARCHAR(10) PRIMARY KEY, BASECUR VARCHAR(3), RATE VARCHAR(10) );

INSERT INTO RATES VALUES('1', 'USD', '1.25'); INSERT INTO RATES VALUES('2', 'EUR', '1.52'); INSERT INTO RATES VALUES('3', 'CHF', '1.00'); INSERT INTO RATES VALUES('4', 'CND', '1.17');

JBoss Logfile: [JBoss_HOME]JBoss Logfile: [JBoss_HOME]JBoss Logfile: [JBoss_HOME]JBoss Logfile: [JBoss_HOME]\\\\sssservererverervererver\\\\eeeeeeee\\\\loglogloglog\\\\server.logserver.logserver.logserver.log

13:26:38,984 INFO [STDOUT] MoneyExchangeBean context set 13:26:38,984 INFO [STDOUT] ejbCreate called ! 13:26:59,562 INFO [STDOUT] 100.0 * 1.25 = 125.0 : false

Output:Output:Output:Output:

100 CHF are 125.0 USD

Page 169: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 169 von total 218 Seiten

29.6 Lösung zu Übung ee5 : Handle auf Session Bean - AutomaticTeller

Home Interface: AutomaticTellerHome.javeHome Interface: AutomaticTellerHome.javeHome Interface: AutomaticTellerHome.javeHome Interface: AutomaticTellerHome.jave

package beans;

import javax.ejb.EJBHome; import java.rmi.RemoteException; import javax.ejb.CreateException;

public interface AutomaticTellerHome extends EJBHome { public AutomaticTeller create() throws RemoteException, CreateException; }

Remote Interface: AutomaticTeller.javaRemote Interface: AutomaticTeller.javaRemote Interface: AutomaticTeller.javaRemote Interface: AutomaticTeller.java

package beans;

import java.rmi.RemoteException; import javax.ejb.EJBObject;

public interface AutomaticTeller extends EJBObject { public void depositMoney(float amount) throws RemoteException; public void withdrawMoney(float amount) throws RemoteException; public float getAccountBalance() throws RemoteException; }

Bean Class: AutomaticTellerBean.javaBean Class: AutomaticTellerBean.javaBean Class: AutomaticTellerBean.javaBean Class: AutomaticTellerBean.java

package beans;

import javax.ejb.SessionBean; import javax.ejb.SessionContext;

public class AutomaticTellerBean implements SessionBean {

private float accountBalance = 0.0f; private SessionContext context;

public void depositMoney(float amount) { accountBalance += amount; }

public void withdrawMoney(float amount) { accountBalance -= amount; }

public float getAccountBalance() { return accountBalance; }

public void setSessionContext(SessionContext sc) { this.context = sc; }

public void ejbCreate() { } public void ejbRemove() { } public void ejbActivate() { } public void ejbPassivate() { } }

Page 170: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 170 von total 218 Seiten

Deployment Descriptor: Deployment Descriptor: Deployment Descriptor: Deployment Descriptor: ejbejbejbejb----jar.xmljar.xmljar.xmljar.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">

<ejb-jar> <display-name>AC</display-name> <enterprise-beans> <session> <ejb-name>AutomaticTeller</ejb-name> <home>beans.AutomaticTellerHome</home> <remote>beans.AutomaticTeller</remote> <ejb-class>beans.AutomaticTellerBean</ejb-class> <session-type>Stateful</session-type> <transaction-type>Bean</transaction-type> </session> </enterprise-beans> </ejb-jar>

Deployment Descriptor: Deployment Descriptor: Deployment Descriptor: Deployment Descriptor: jboss.xmljboss.xmljboss.xmljboss.xml

<?xml version="1.0" encoding="UTF-8"?>

<jboss> <enterprise-beans> <entity> <ejb-name>AutomaticTeller</ejb-name> <jndi-name>ejb/account</jndi-name> </entity> </enterprise-beans> </jboss>

Client Applilation: Client Applilation: Client Applilation: Client Applilation: AutomaticTellerClient.javaAutomaticTellerClient.javaAutomaticTellerClient.javaAutomaticTellerClient.java

package client;

import javax.ejb.*; import java.io.*; import java.rmi.*; import javax.naming.*; import java.util.Properties; import beans.*;

public class AutomaticTellerClient {

private static AutomaticTellerHome home; private static Handle handle_1; private static Handle handle_2; private static Handle handle_3;

protected static Properties getInitialProperties() { Properties property = new Properties(); try { property.load(new FileInputStream("resources/jndi.properties")); } catch (FileNotFoundException e) { System.out.println("can't find file: jndi.properties"); } catch (IOException e) { e.printStackTrace(); } return property; }

public static Handle erstelleAccount(AutomaticTellerHome home) throws CreateException, RemoteException { AutomaticTeller at = home.create(); return at.getHandle();

Page 171: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 171 von total 218 Seiten

}

public static void deposit(Handle handle, float Betrag) throws RemoteException { AutomaticTeller at = getRemoteObjekt(handle); at.depositMoney(Betrag); }

public static void withdraw(Handle handle, float Betrag) throws RemoteException { AutomaticTeller at = getRemoteObjekt(handle); at.withdrawMoney(Betrag); }

private static AutomaticTellerHome erzeugeHomeObjekt() throws NamingException { InitialContext ctx = new InitialContext(getInitialProperties()); Object ref = ctx.lookup("ejb/account"); home = (AutomaticTellerHome) PortableRemoteObject.narrow(ref, AutomaticTellerHome.class); return home; }

private static void printAccountBalance(int id, Handle handle) throws RemoteException { AutomaticTeller at = getRemoteObjekt(handle); System.out.println("ID " + id + " has : " + at.getAccountBalance() + " CHF!"); }

private static AutomaticTeller getRemoteObjekt(Handle handle) throws RemoteException { return (AutomaticTeller) javax.rmi.PortableRemoteObject.narrow(handle .getEJBObject(), AutomaticTeller.class); }

public static void main(String[] args) { try { home = erzeugeHomeObjekt(); handle_1 = erstelleAccount(home); handle_2 = erstelleAccount(home); handle_3 = erstelleAccount(home); deposit(handle_1, 500f); deposit(handle_2, 300f); withdraw(handle_1, 100f); withdraw(handle_2, 50f); deposit(handle_2, 300f); withdraw(handle_1, 100f); withdraw(handle_3, 50f); deposit(handle_2, 300f); withdraw(handle_1, 100f); withdraw(handle_2, 50f); printAccountBalance(1, handle_1); printAccountBalance(2, handle_2); printAccountBalance(3, handle_3); } catch (Exception e) { e.printStackTrace(); } } }

Output:Output:Output:Output:

ID 1 has : 200.0 CHF! ID 2 has : 800.0 CHF! ID 3 has : -50.0 CHF!

Page 172: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 172 von total 218 Seiten

Client Application: speichert (Remote) Handle persistent in lokale Datei (Ausschnitt) Client Application: speichert (Remote) Handle persistent in lokale Datei (Ausschnitt) Client Application: speichert (Remote) Handle persistent in lokale Datei (Ausschnitt) Client Application: speichert (Remote) Handle persistent in lokale Datei (Ausschnitt)

public static void main(String[] args) { try { home = erzeugeHomeObjekt(); handle_1 = erstelleAccount(home); deposit(handle_1, 500f); withdraw(handle_1, 100f); printAccountBalance(1, handle_1); // write the handle to serialized file FileOutputStream f = new FileOutputStream("TellerHandle_1.ser"); ObjectOutputStream o = new ObjectOutputStream(f); o.writeObject(handle_1); o.flush(); o.close(); } catch (Exception e) { e.printStackTrace(); } }

Output:Output:Output:Output:

ID 1 has : 400.0 CHF!

Client Application: liest Handle von lokaler Datei und macht Buchungen (AusschnitClient Application: liest Handle von lokaler Datei und macht Buchungen (AusschnitClient Application: liest Handle von lokaler Datei und macht Buchungen (AusschnitClient Application: liest Handle von lokaler Datei und macht Buchungen (Ausschnitt) t) t) t)

public static void main(String[] args) { try { // read handle from file at later time FileInputStream fi = new FileInputStream("TellerHandle_1.ser"); ObjectInputStream oi = new ObjectInputStream(fi); //read the object from the file and cast it to a Handle handle_1 = (Handle) oi.readObject(); oi.close(); deposit(handle_1, 500f); withdraw(handle_1, 100f); printAccountBalance(1, handle_1); // write the handle to serialized file FileOutputStream f = new FileOutputStream("TellerHandle_1.ser"); ObjectOutputStream o = new ObjectOutputStream(f); o.writeObject(handle_1); o.flush(); o.close(); } catch (Exception e) { e.printStackTrace(); } }

Output:Output:Output:Output:

ID 1 has : 800.0 CHF!

Page 173: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 173 von total 218 Seiten

29.7 Lösung zu Übung ee6 : CMP 2.0 Entity Bean - ProductShop

Home Interface: ProductHome.javaHome Interface: ProductHome.javaHome Interface: ProductHome.javaHome Interface: ProductHome.java

package beans;

import javax.ejb.*; import java.rmi.RemoteException; import java.util.Collection;

public interface ProductHome extends EJBHome {

Product create(String pid, String name, double price) throws CreateException, RemoteException;

public Product findByPrimaryKey(ProductPK key) throws FinderException, RemoteException;

public Collection findByName(String n) throws FinderException, RemoteException;

public Collection findAllProducts() throws FinderException, RemoteException; }

Remote Interafce: Product.javaRemote Interafce: Product.javaRemote Interafce: Product.javaRemote Interafce: Product.java

package beans;

import javax.ejb.*; import java.rmi.RemoteException;

public interface Product extends EJBObject {

public String getName() throws RemoteException; public void setName(String name) throws RemoteException;

public double getPrice() throws RemoteException; public void setPrice(double price) throws RemoteException;

public String getProductID() throws RemoteException; }

Primary Key Class: ProductPK.jaPrimary Key Class: ProductPK.jaPrimary Key Class: ProductPK.jaPrimary Key Class: ProductPK.javavavava

package beans;

public class ProductPK implements java.io.Serializable {

public String productID;

public ProductPK(String pid) { productID = pid; }

public ProductPK() { }

public int hashCode() { return productID.hashCode(); }

public boolean equals(Object obj) { return ((ProductPK) obj).productID.equals(productID); } }

Page 174: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 174 von total 218 Seiten

Bean Class: ProductBean.javaBean Class: ProductBean.javaBean Class: ProductBean.javaBean Class: ProductBean.java

package beans;

import javax.ejb.*;

public abstract class ProductBean implements EntityBean {

protected EntityContext ctx;

public ProductBean() { }

public abstract String getName(); public abstract void setName(String name);

public abstract double getPrice(); public abstract void setPrice(double price);

public abstract String getProductID(); public abstract void setProductID(String pid);

public ProductPK ejbCreate(String pid, String n, double price) throws CreateException { setProductID(pid); setName(n); setPrice(price); return new ProductPK(pid); }

public void ejbPostCreate(String pid, String n, double price) { }

public void ejbActivate() { } public void ejbPassivate() { }

public void ejbRemove() { }

public void ejbLoad() { }

public void ejbStore() { }

public void setEntityContext(EntityContext ctx) { this.ctx = ctx; }

public void unsetEntityContext() { this.ctx = null; } }

Deployment Descriptor: Deployment Descriptor: Deployment Descriptor: Deployment Descriptor: ejbejbejbejb----jar.xmljar.xmljar.xmljar.xml

<ejb-jar> <description>Product Business Model</description> <display-name>Product Bean</display-name> <enterprise-beans> <entity> <description>Models a Productline</description> <ejb-name>Product</ejb-name> <home>beans.ProductHome</home> <remote>beans.Product</remote> <ejb-class>beans.ProductBean</ejb-class> <persistence-type>Container</persistence-type> <reentrant>False</reentrant> <prim-key-class>beans.ProductPK</prim-key-class> <cmp-version>2.x</cmp-version> <abstract-schema-name>ProductBean</abstract-schema-name> <cmp-field> <field-name>productID</field-name> </cmp-field> <cmp-field> <field-name>name</field-name> </cmp-field>

Page 175: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 175 von total 218 Seiten

<cmp-field> <field-name>price</field-name> </cmp-field> <query> <query-method> <method-name>findByName</method-name> <method-params> <method-param>java.lang.String</method-param> </method-params> </query-method> <ejb-ql> SELECT OBJECT(a)

FROM ProductBean As a WHERE a.name = ?1 </ejb-ql> </query> <query> <query-method> <method-name>findAllProducts</method-name> <method-params> </method-params> </query-method> <ejb-ql> SELECT OBJECT(a) FROM ProductBean As a WHERE a.productID IS NOT NULL </ejb-ql> </query> </entity> </enterprise-beans> <assembly-descriptor> <container-transaction> <method> <ejb-name>Product</ejb-name> <method-intf>Remote</method-intf> <method-name>*</method-name> </method> <trans-attribute>Required</trans-attribute> </container-transaction> </assembly-descriptor> </ejb-jar>

Deployment Descriptor: jDeployment Descriptor: jDeployment Descriptor: jDeployment Descriptor: jbosscmpbosscmpbosscmpbosscmp----jdbc.xmljdbc.xmljdbc.xmljdbc.xml

<jbosscmp-jdbc> <defaults> <datasource>java:/DefaultDS</datasource> <datasource-mapping>mySQL</datasource-mapping> <create-table>true</create-table> <remove-table>true</remove-table> </defaults> <enterprise-beans> <entity> <ejb-name>Product</ejb-name> <table-name>ProductTable</table-name> </entity> </enterprise-beans> </jbosscmp-jdbc>

CliCliCliClient Application: ProductClient.javaent Application: ProductClient.javaent Application: ProductClient.javaent Application: ProductClient.java

package client;

import javax.naming.*; import javax.rmi.PortableRemoteObject; import java.util.*; import beans.*;

public class ProductClient {

Page 176: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 176 von total 218 Seiten

public static void main(String[] args) throws Exception { ProductHome home = null; System.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory"); System.setProperty("java.naming.provider.url", "localhost:1099"); try { Context ctx = new InitialContext(); home = (ProductHome) PortableRemoteObject.narrow(ctx.lookup("Product"), ProductHome.class); home.create("p1", "HD", 180.50); home.create("p2", "CPU", 220.30); home.create("p3", "Ram", 160); Iterator i = home.findAllProducts().iterator(); while (i.hasNext()) { Product prod = (Product) PortableRemoteObject.narrow(i.next(), Product.class); System.out.println(prod.getName() + "\t" + prod.getPrice()); prod.remove(); } } catch (Exception e) { } } }

Output:Output:Output:Output:

HD 180.5 CPU 220.3 Ram 160.0

Page 177: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 177 von total 218 Seiten

29.8 Lösung zu Übung ee61 : CMP2.0 Local Interface - Summe aller Produkte

Local Home Interface: ProductLocalHome.javaLocal Home Interface: ProductLocalHome.javaLocal Home Interface: ProductLocalHome.javaLocal Home Interface: ProductLocalHome.java

package beans;

import javax.ejb.*; import java.util.Collection;

public interface ProductLocalHome extends EJBLocalHome {

ProductLocal create(String pid, String name, double base) throws CreateException;

public ProductLocal findByPrimaryKey(ProductPK key) throws FinderException;

public Collection findByName(String n) throws FinderException;

public Collection findAllProducts() throws FinderException;

public double getAllPriceTotal(); }

Local Remote Interface: Local Remote Interface: Local Remote Interface: Local Remote Interface: ProductLocaProductLocaProductLocaProductLocal.javal.javal.javal.java

package beans;

import javax.ejb.*;

public interface ProductLocal extends EJBLocalObject {

public String getName(); public void setName(String name);

public double getPrice(); public void setPrice(double price);

public String getProductID(); }

Home Interface: Home Interface: Home Interface: Home Interface: ProductHomeProductHomeProductHomeProductHome.java.java.java.java

package beans;

import javax.ejb.*; import java.rmi.RemoteException; import java.util.Collection;

public interface ProductHome extends EJBHome {

Product create(String pid, String name, double base) throws CreateException, RemoteException;

public Product findByPrimaryKey(ProductPK key) throws FinderException, RemoteException;

public Collection findByName(String n) throws FinderException, RemoteException;

public Collection findAllProducts() throws FinderException, RemoteException;

public double getAllPriceTotal() throws RemoteException; }

Page 178: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 178 von total 218 Seiten

Remote Interface: Remote Interface: Remote Interface: Remote Interface: Product.javaProduct.javaProduct.javaProduct.java

package beans;

import javax.ejb.*; import java.rmi.RemoteException;

public interface Product extends EJBObject {

public String getName() throws RemoteException; public void setName(String name) throws RemoteException;

public double getPrice() throws RemoteException; public void setPrice(double price) throws RemoteException;

public String getProductID() throws RemoteException; }

Primary Key Class: ProductPK.javaPrimary Key Class: ProductPK.javaPrimary Key Class: ProductPK.javaPrimary Key Class: ProductPK.java

package beans;

public class ProductPK implements java.io.Serializable {

public String productID;

public ProductPK(String pid) { productID = pid; }

public ProductPK() { }

public String toString() { return productID.toString(); }

public int hashCode() { return productID.hashCode(); }

public boolean equals(Object obj) { return ((ProductPK) obj).productID.equals(productID); } }

Bean Class: ProductBean.javaBean Class: ProductBean.javaBean Class: ProductBean.javaBean Class: ProductBean.java

package beans;

import javax.ejb.*; import java.util.*;

public abstract class ProductBean implements EntityBean {

protected EntityContext ctx;

public ProductBean() { }

public abstract String getName(); public abstract void setName(String name);

public abstract double getPrice(); public abstract void setPrice(double price);

public abstract String getProductID(); public abstract void setProductID(String pid);

public abstract Collection ejbSelectAllPrices() throws FinderException;

public double ejbHomeGetAllPriceTotal() { double sum = 0.0;

Page 179: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 179 von total 218 Seiten

try { Collection c = this.ejbSelectAllPrices(); Iterator i = c.iterator(); while (i.hasNext()) { sum += ((ProductLocal) i.next()).getPrice(); } } catch (Exception e) { e.printStackTrace(); } return sum; }

public ProductPK ejbCreate(String pid, String n, double price) throws CreateException { setProductID(pid); setName(n); setPrice(price); return new ProductPK(pid); }

public void ejbPostCreate(String pid, String n, double price) { }

public void setEntityContext(EntityContext ctx) { this.ctx = ctx; }

public void unsetEntityContext() { this.ctx = null; }

public void ejbActivate() { }

public void ejbPassivate() { }

public void ejbRemove() { }

public void ejbLoad() { }

public void ejbStore() { } }

Deployment Descriptor: ejbDeployment Descriptor: ejbDeployment Descriptor: ejbDeployment Descriptor: ejb----jar.xml jar.xml jar.xml jar.xml

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/j2ee/dtds/ejb-jar_2_0.dtd"> <ejb-jar> <description>Product Business Model</description> <display-name>Product Bean</display-name> <enterprise-beans> <entity> <description>Models a productline</description> <ejb-name>Product</ejb-name> <home>beans.ProductHome</home> <remote>beans.Product</remote> <local-home>beans.ProductLocalHome</local-home> <local>beans.ProductLocal</local> <ejb-class>beans.ProductBean</ejb-class> <persistence-type>Container</persistence-type> <reentrant>False</reentrant> <prim-key-class>beans.ProductPK</prim-key-class> <cmp-version>2.x</cmp-version> <abstract-schema-name>ProductBean</abstract-schema-name> <cmp-field> <field-name>productID</field-name> </cmp-field> <cmp-field> <field-name>name</field-name> </cmp-field>

Page 180: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 180 von total 218 Seiten

<cmp-field> <field-name>price</field-name> </cmp-field> <query> <query-method> <method-name>findByName</method-name> <method-params> <method-param>java.lang.String</method-param> </method-params> </query-method> <ejb-ql> SELECT OBJECT(a) FROM ProductBean As a WHERE a.name = ?1 </ejb-ql> </query> <query> <query-method> <method-name>findAllProducts</method-name> <method-params> </method-params> </query-method> <ejb-ql> SELECT OBJECT(a) FROM ProductBean As a WHERE a.productID IS NOT NULL </ejb-ql> </query> <query> <query-method> <method-name>ejbSelectAllPrices</method-name> <method-params> </method-params> </query-method> <result-type-mapping>Local</result-type-mapping> <ejb-ql> SELECT OBJECT(p) FROM ProductBean As p </ejb-ql> </query> </entity> </enterprise-beans> <assembly-descriptor> <container-transaction> <method> <ejb-name>Product</ejb-name> <method-intf>Remote</method-intf> <method-name>*</method-name> </method> <trans-attribute>Required</trans-attribute> </container-transaction> </assembly-descriptor> </ejb-jar>

Deployment Descriptor: jboDeployment Descriptor: jboDeployment Descriptor: jboDeployment Descriptor: jbosscmpsscmpsscmpsscmp----jdbc.xml jdbc.xml jdbc.xml jdbc.xml

<jbosscmp-jdbc> <defaults> <datasource>java:/DefaultDS</datasource> <datasource-mapping>mySQL</datasource-mapping> <create-table>true</create-table> <remove-table>true</remove-table> <read-only>false</read-only> <pk-constraint>true</pk-constraint> </defaults> <enterprise-beans> <entity> <ejb-name>Product</ejb-name> <table-name>ProductTable</table-name> </entity> </enterprise-beans> </jbosscmp-jdbc>

Page 181: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 181 von total 218 Seiten

Client ApplicClient ApplicClient ApplicClient Application: ProductClient.javaation: ProductClient.javaation: ProductClient.javaation: ProductClient.java

package client;

import javax.naming.*; import javax.rmi.PortableRemoteObject; import java.util.*; import beans.*;

public class ProductClient {

public static void main(String[] args) throws Exception { ProductHome home = null; System.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory"); System.setProperty("java.naming.provider.url", "localhost:1099"); try { Context ctx = new InitialContext(); home = (ProductHome) PortableRemoteObject.narrow(ctx.lookup("Product"), ProductHome.class); home.create("p1", "HD", 180.50); home.create("p2", "CPU", 220.30); home.create("p3", "Ram", 160); System.out.println("Price:\t" + home.getAllPriceTotal()); Iterator i = home.findAllProducts().iterator(); while (i.hasNext()) { Product prod = (Product) PortableRemoteObject.narrow(i.next(), Product.class); System.out.println(prod.getName() + "\t" + prod.getPrice()); prod.remove(); } } catch (Exception e) { } } }

Output:Output:Output:Output:

Price: 560.8 HD 180.5 CPU 220.3 Ram 160.0

Der (Remote) Client muss somit nur noch "einen" Zugriff auf den EJB-Kontainer per RMI-IIOP machen um das Total aller Produkte zu bestimmen.

Page 182: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 182 von total 218 Seiten

29.9 Lösung zu Übung ee62: BMP Entity Bean - PersonBean

Home Interface: BMPPersonHome.javaHome Interface: BMPPersonHome.javaHome Interface: BMPPersonHome.javaHome Interface: BMPPersonHome.java

package beans;

import java.rmi.RemoteException; import javax.ejb.CreateException; import javax.ejb.EJBHome; import javax.ejb.FinderException;

public interface BMPPersonHome extends EJBHome { public BMPPerson create(int year, int month, int day, String name, String city) throws CreateException, RemoteException; public BMPPerson findByPrimaryKey(String name) throws FinderException, RemoteException; }

Remote Interface: BMPPerson.javaRemote Interface: BMPPerson.javaRemote Interface: BMPPerson.javaRemote Interface: BMPPerson.java

package beans;

import java.rmi.RemoteException; import javax.ejb.EJBObject;

public interface BMPPerson extends EJBObject { public int getAge() throws RemoteException; public String getCity() throws RemoteException; public void setCity(String city) throws RemoteException; }

Bean Class: BMPPersonBean.javaBean Class: BMPPersonBean.javaBean Class: BMPPersonBean.javaBean Class: BMPPersonBean.java

package beans;

import java.rmi.RemoteException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Calendar; import java.util.GregorianCalendar;

import javax.ejb.CreateException; import javax.ejb.EJBException; import javax.ejb.EntityBean; import javax.ejb.EntityContext; import javax.ejb.FinderException; import javax.ejb.RemoveException;

public class BMPPersonBean implements EntityBean { //persistent fields private String name; private GregorianCalendar birthdate; private String city; public BMPPersonBean() { } //methods which are part of the remote interface public int getAge() { return ( new GregorianCalendar().get(Calendar.YEAR) - birthdate.get(Calendar.YEAR)); } public String getCity() { return city; }

Page 183: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 183 von total 218 Seiten

public void setCity(String city) throws RemoteException { if (city.length() <= 30) { this.city = city; } else { throw new RemoteException("cannot update city"); } } // ------------------------------------------------------------------ public String ejbCreate( int year, int month, int day, String name, String city) throws CreateException { if (year > 1900 && month >= 1 && month <= 12 && day >= 1 && day <= 31 && name.length() <= 20 && city.length() <= 30) { this.name = name; this.birthdate = new GregorianCalendar(year, month, day); this.city = city; Statement stmt = getStatement(); String s = new String( "INSERT INTO BMPPERSON VALUES ('" + name + "','" + birthdate.get(Calendar.YEAR) + "-" + birthdate.get(Calendar.MONTH) + "-" + birthdate.get(Calendar.DATE) + "'," + "'" + city + "'" + ");"); try { stmt.executeUpdate(s); } catch (SQLException e) { e.printStackTrace(); } } else { throw new CreateException("Invalid values supplied"); } return name; } public void ejbPostCreate( int year, int month, int day, String name, String city) { } // ------------------------------------------------------------------ public int ejbHomeGetAge() { return 0; } public String ejbHomeGetCity() { return new String(); }

Page 184: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 184 von total 218 Seiten

// public void ejbHomeSetCity(String city) { // } public Statement getStatement() { try { Class.forName("org.gjt.mm.mysql.Driver"); } catch (ClassNotFoundException e) { e.printStackTrace(); } Connection con = null; try { con = (Connection) DriverManager.getConnection( "jdbc:mysql://localhost/ee", "root", ""); } catch (SQLException e1) { e1.printStackTrace(); } try { return ((Statement) con.createStatement()); } catch (SQLException e2) { e2.printStackTrace(); } return null; //never gets here } // ------------------------------------------------------------------ public void setEntityContext(EntityContext ectx) throws EJBException, RemoteException { } public void unsetEntityContext() throws EJBException, RemoteException { } public void ejbRemove() throws RemoveException, EJBException, RemoteException { Statement stmt = getStatement(); String s = new String( "DELETE FROM BMPPERSON WHERE Name='" + name + "';"); try { stmt.executeUpdate(s); } catch (SQLException e) { e.printStackTrace(); } } public void ejbActivate() throws EJBException, RemoteException { } public void ejbPassivate() throws EJBException, RemoteException { } public void ejbLoad() throws EJBException, RemoteException { }

Page 185: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 185 von total 218 Seiten

public void ejbStore() throws EJBException, RemoteException { Statement stmt = getStatement(); String s = new String( "UPDATE BMPPERSON SET Name='" + name + "', Birthdate='" + birthdate.get(Calendar.YEAR) + "-" + birthdate.get(Calendar.MONTH) + "-" + birthdate.get(Calendar.DATE) + "', City = '" + city + "' WHERE Name = '" + name + "';"); try { stmt.executeUpdate(s); } catch (SQLException e) { e.printStackTrace(); } } public String ejbFindByPrimaryKey(String name) throws FinderException { Statement stmt = getStatement(); String s = new String("SELECT Name FROM BMPPERSON WHERE Name='" + name + "';"); try { ResultSet rs = stmt.executeQuery(s); rs.first(); return rs.getString("Name"); } catch (SQLException e) { e.printStackTrace(); } return null; //never gets here } }

Client Application: BMPPersonClient.javaClient Application: BMPPersonClient.javaClient Application: BMPPersonClient.javaClient Application: BMPPersonClient.java

package client;

import java.rmi.RemoteException; import java.util.Properties;

import javax.ejb.CreateException; import javax.ejb.FinderException; import javax.ejb.RemoveException; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.rmi.PortableRemoteObject;

import beans.BMPPerson; import beans.BMPPersonHome;

public class BMPPersonClient{ protected static Properties getInitialProperties() { Properties props = new Properties();

props.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory"); props.put(Context.PROVIDER_URL, "localhost:1099"); props.put("java.naming.factory.url.pkgs", "org.jboss.naming;org.jnp.interfaces"); return props; }

public static void main(String[] args) {

Page 186: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 186 von total 218 Seiten

try { Context initial = new InitialContext(getInitialProperties()); Object objRef = initial.lookup("ejb/bmpperson"); BMPPersonHome home = (BMPPersonHome) PortableRemoteObject.narrow( objRef,BMPPersonHome.class); BMPPerson p1 = home.create(1981, 1, 1, "Leonie", "cityA"); BMPPerson p2 = home.create(1972, 2, 2, "Lukas", "cityB"); System.out.println("Leonies Alter: " + p1.getAge()); System.out.println("Leonies PK: "+p1.getPrimaryKey()); p1.remove(); BMPPerson p3 = home.findByPrimaryKey("Lukas"); System.out.println( "Lukas wohnt in: " + p3.getCity()); p3.setCity("cityC"); System.out.println("Lukas neuer Wohnort: " + p3.getCity()); System.out.println("Lukas alter Wohnort: " + p2.getCity()); System.out.println( "sind p2 und p3 das gleiche Java Object ? "+ (p2==p3)); System.out.println( "sind p2 und p3 das gleiche EJBObject ? "+p2.isIdentical(p3));

} catch (NamingException ne) { ne.printStackTrace(); } catch (RemoteException re) { re.printStackTrace(); } catch (CreateException ce) { ce.printStackTrace(); } catch (RemoveException e) { e.printStackTrace(); } catch (FinderException e) { e.printStackTrace(); } } }

Output:Output:Output:Output:

Leonies Alter: 25 Leonies PK: Leonie Lukas wohnt in: cityB Lukas neuer Wohnort: cityC Lukas alter Wohnort: cityC sind p2 und p3 das gleiche Java Object ? false sind p2 und p3 das gleiche EJBObject ? true

Page 187: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 187 von total 218 Seiten

29.10 Lösung zu Übung ee7 : Servlet - WorkingServlet

Servlet: WorkingServlet.javaServlet: WorkingServlet.javaServlet: WorkingServlet.javaServlet: WorkingServlet.java

package mypackage;

import java.io.IOException; import java.io.Writer; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;

/** * Sample Servlet showing a HTML page with a message. * Call Servlet via: http://localhost:8080/ee7/start */ public class HelloServlet extends HttpServlet {

public void service(HttpServletRequest inRequest, HttpServletResponse inResponse) throws IOException, ServletException { // Get Writer object of response Writer aResponseWriter = inResponse.getWriter(); // Specify content as HTML page inResponse.setContentType("text/html"); // Write HTML content to response aResponseWriter .write("<html><head><title>1st WorkingServlet</title></head>\n"); aResponseWriter .write("<html><head><title>1st WorkingServlet</title></head>\n"); aResponseWriter.write("<body>\n"); aResponseWriter .write("<h1>My first SampleServlet is working great!</h1>\n"); aResponseWriter.write("</body></html>"); // Force sending of response aResponseWriter.flush(); } }

- notwendige Library : servlet.jar

- Source Path : .../WEB-INF/src/

- Build Path .../WEB-INF/classes/

- server.xml

Die Datei server.xml automatisch konfigurieren mit: Kontext-Menü > Tomcat Projekt > Kontext in server.xml aktualisieren

ergibt folgenden Eintrag in der Datei [TOMCAT_HOME]/conf/server.xml:

<Context path="/ee7" reloadable="true" docBase="C:\sbb\workspace\ee7" workDir="C:\sbb\workspace\ee7\work" />

Page 188: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 188 von total 218 Seiten

web.xmlweb.xmlweb.xmlweb.xml

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>

<display-name>Servlet Test Application</display-name> <description>Schreibt eine Begrüssung</description>

<servlet> <servlet-name>Hello</servlet-name> <servlet-class>mypackage.HelloServlet</servlet-class> </servlet>

<servlet-mapping> <servlet-name>Hello</servlet-name> <url-pattern>/start</url-pattern> </servlet-mapping>

</web-app>

Browser:Browser:Browser:Browser:

Page 189: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 189 von total 218 Seiten

29.11 Lösung zu Übung ee71: Servlet mit EJB Client - Web Shop

Servlet: BasketServlet.javaServlet: BasketServlet.javaServlet: BasketServlet.javaServlet: BasketServlet.java

package servlet;

import java.io.IOException; import java.io.Writer; import java.util.Collection; import java.util.Iterator; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import beans.Product; import client.ProductClientBean;

public class BasketServlet extends HttpServlet {

public void service(HttpServletRequest inRequest, HttpServletResponse inResponse) throws IOException, ServletException { // Get Writer object of response Writer aResponseWriter = inResponse.getWriter(); // Specify content as HTML page inResponse.setContentType("text/html"); String headContent = "<html>\n<head>\n <title> Products From Shop" + "</title>\n\t</head>\n <body>\n"; String outContent = "<table cellspacing=\"5\" cellpadding=\"5\"" + "border=\"0\" bgcolor=\"#dddddd\">\n" + "<tr>\n" + "<td colspan=\"3\">All Current Products in Shop</td>\n" + "</tr>\n" + "<tr bgcolor=\"#bbbbbb\">\n"; Product aProduct = null; ProductClientBean pcb = new ProductClientBean(); try { Collection c = pcb.getProducts(); Iterator p = c.iterator(); outContent += " <td><b>Id</td><td>Name</b></td><td>Price</b></td>\n" + "</tr>\n" + "<tr bgcolor=\"#cccccc\">\n "; while (p.hasNext()) { aProduct = (Product) p.next(); outContent += "<td>" + aProduct.getProductID() + "</td>"; outContent += "<td>" + aProduct.getName() + "</td>"; outContent += "<td>" + aProduct.getPrice() + "</td>\n"; outContent += "</tr>\n<tr bgcolor=\"#cccccc\">\n"; } } catch (Exception e) { Throwable t = e; while (t != null) { outContent += " <td><b>Error</td><td>Class</b>" + "</td><td>Message</b></td>\n" + "</tr>\n" + "<tr bgcolor=\"#cccccc\">\n"; outContent += "<td>Error:</td>"; outContent += "<td>" + t.getClass().getName() + "</td>"; outContent += "<td>" + t.getMessage() + "</td>\n"; outContent += "</tr>\n<tr bgcolor=\"#cccccc\">\n "; t = t.getCause(); } } outContent += "&nbsp;\n</tr>\n</table>\n"; String buttonContent = "</body>\n</html>"; // Write HTML content to response aResponseWriter.write(headContent + outContent + buttonContent); aResponseWriter.flush(); } }

Page 190: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 190 von total 218 Seiten

Java Bean (TierJava Bean (TierJava Bean (TierJava Bean (Tier----Interface): ProductClientBean.javaInterface): ProductClientBean.javaInterface): ProductClientBean.javaInterface): ProductClientBean.java

package client;

import java.util.Collection; import javax.naming.Context; import javax.naming.InitialContext; import javax.rmi.PortableRemoteObject; import beans.ProductHome;

public class ProductClientBean {

public Collection getProducts() throws Exception { System.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory"); System.setProperty("java.naming.provider.url", "localhost:1099"); ProductHome home = null; Collection products = null; try { Context ctx = new InitialContext(); home = (ProductHome) PortableRemoteObject.narrow(ctx.lookup("Product"), ProductHome.class); products = home.findAllProducts(); } catch (Exception e) { System.err.println("Error establishing bean connection"); Throwable t = e; while (t != null) { System.err.println("Type: " + t.getClass().getName()); System.err.println("Message: " + t.getMessage()); t = t.getCause(); } } return products; } }

Deployment Descriptor: web.xmlDeployment Descriptor: web.xmlDeployment Descriptor: web.xmlDeployment Descriptor: web.xml

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app> <display-name>Product Shop</display-name> <description> Listet alle Producte auf </description> <servlet> <servlet-name>Products</servlet-name> <servlet-class> servlet.BasketServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>Products</servlet-name> <url-pattern>/shop</url-pattern> </servlet-mapping> </web-app>

Die Klassen des Product EJB sind identisch zu Übung ee6.

Page 191: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 191 von total 218 Seiten

Browser:Browser:Browser:Browser:

Page 192: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 192 von total 218 Seiten

29.12 Lösung zu Übung ee8 : JSP mit JDBC, Taglib und EJB - Währungsrechner

JavaServerPage: Currency.jspJavaServerPage: Currency.jspJavaServerPage: Currency.jspJavaServerPage: Currency.jsp

<%--@ page errorPage="CurrencyNA.jsp"--%>

<jsp:useBean id="currency" class="client.MoneyExchangeClientBean" scope="page"/>

<% String amount = ""; String from = "1"; String to = "1";

if (request.getParameter("amount") != null) amount = request.getParameter("amount"); if (request.getParameter("from") != null) from = request.getParameter("from"); if (request.getParameter("to") != null) to = request.getParameter("to"); %>

<html> <head> <title>W&auml;hrungsumrechner</title> </head> <body> <h1>W&auml;hrungsumrechner (ee8)</h1> <p>Betrag und W&auml;hrungen ausw&auml;hlen:</p> <form action="Currency.jsp"> <input type="text" name="amount" size="10" value=<%=amount%> > <select name="from"> <jsp:include page="/src/jsp/Currency_DBTags.jsp"/> </select> umrechnen in <select name="to"> <jsp:include page= "/src/jsp/Currency_DBTags.jsp"/> </select> <input type=SUBMIT value="Go!"> </form>

<p><font size='1'>SELECT erstellt mit DB-TAGS&nbsp;&nbsp; ( see : Currency_DBTags.jsp )</font></p>

<%@ include file="Currency_JDBC.jsp"%>

<hr>

<table> <tr> <td width = 300>Umrechnungskurs ist:</td> <td width = 100><b><%=exch_rate%></b></td> <td width = 600><font size='1'>&nbsp;&nbsp; ( see : Currency_JDBC.jsp )</fomt> </td> </tr> </table> <hr>

<% if (amount.equals("")) { %>

Bitte Betrag eingeben !

<% } else { %> <table> <tr> <td width = 300>Berechnetes Resultat:</td> <td width = 100><b><%= currency.calculate(amount, exch_rate) %></b></td>

Page 193: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 193 von total 218 Seiten

<td width = 600><font size='1'>&nbsp;&nbsp; ( see : MoneyExchangeBean )</fomt> </td> </tr> </table>

<% } %>

<hr> </body> </html>

JavaServerPage: Currency_JDBC.jspJavaServerPage: Currency_JDBC.jspJavaServerPage: Currency_JDBC.jspJavaServerPage: Currency_JDBC.jsp

<%@ page import="java.sql.*" %>

<% String jdbc_amount = "0"; String jdbc_from = "1"; String jdbc_to = "1";

if (request.getParameter("amount") != null) jdbc_amount = request.getParameter("amount"); if (request.getParameter("from") != null) jdbc_from = request.getParameter("from"); if (request.getParameter("to") != null) jdbc_to = request.getParameter("to");

String SQLQuerry = ""; ResultSet rs = null; String base = ""; float exch_rate = 0.0f;

String con = "jdbc:mysql://localhost:3306/ee"; String user = "root"; String pass = ""; Class.forName("org.gjt.mm.mysql.Driver"); Connection connection = DriverManager.getConnection(con,user,pass); Statement statement = connection.createStatement();

SQLQuerry = "select basecur,rate from rates where id = " + jdbc_from; rs = statement.executeQuery(SQLQuerry); rs.next(); base = rs.getString(1); exch_rate = rs.getFloat(2);

SQLQuerry = "select basecur,rate from rates where id = " + jdbc_to; rs = statement.executeQuery(SQLQuerry); rs.next(); base = rs.getString(1); exch_rate = exch_rate / rs.getFloat(2);

statement.close(); connection.close(); %>

Page 194: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 194 von total 218 Seiten

JavaServerPage: Currency_DBTags.jspJavaServerPage: Currency_DBTags.jspJavaServerPage: Currency_DBTags.jspJavaServerPage: Currency_DBTags.jsp

<%@ taglib uri="http://jakarta.apache.org/taglibs/dbtags" prefix="sql" %>

<%-- open a database connection --%> <sql:connection id="conn1"> <sql:url>jdbc:mysql://localhost:3306/ee</sql:url> <sql:driver>org.gjt.mm.mysql.Driver</sql:driver> <sql:userId>root</sql:userId> <sql:password> </sql:password> </sql:connection>

<%-- get the requestet parameter --%> <sql:statement id="stmt1" conn="conn1"> <sql:query> select id, basecur from rates order by 2 </sql:query> <sql:resultSet id="rset1"> <option value="<sql:getColumn position="1"/>"> <sql:getColumn position="2"/> </sql:resultSet> </sql:statement>

<%-- close a database connection --%> <sql:closeConnection conn="conn1"/>

JavaServerJavaServerJavaServerJavaServerPage: CurrencyNA.jspPage: CurrencyNA.jspPage: CurrencyNA.jspPage: CurrencyNA.jsp

<%@ page isErrorPage="true" %> <html> <head> <title>Ausf&uuml;hrungsfehler</title> </head> <body> <h1>Fehler</h1> <p>Service ist nicht verf&uuml;gbar.</p> </body> </html>

Java Bean (TierJava Bean (TierJava Bean (TierJava Bean (Tier----Interface): MoneyExchangeCliInterface): MoneyExchangeCliInterface): MoneyExchangeCliInterface): MoneyExchangeClientBean.javaentBean.javaentBean.javaentBean.java

package client;

import javax.naming.Context; import javax.naming.InitialContext; import javax.rmi.PortableRemoteObject; import beans.MoneyExchange; import beans.MoneyExchangeHome; import java.util.Properties;

public class MoneyExchangeClientBean {

protected static Properties getInitialProperties() { Properties props = new Properties(); props.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory"); props.put("java.naming.provider.url", "jnp://localhost:1099"); props.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces"); return props; }

Page 195: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 195 von total 218 Seiten

public String calculate(String betrag, float exchangerate) { float amount = Float.parseFloat(betrag); String result = ""; try { Context initial = new InitialContext(getInitialProperties()); MoneyExchangeHome home = (MoneyExchangeHome) PortableRemoteObject .narrow(initial.lookup("moneyexchange"), MoneyExchangeHome.class); MoneyExchange aMoneyExchange = home.create(); result = aMoneyExchange.change(amount, exchangerate); } catch (Exception e) { e.printStackTrace(); } // Trace Information - Erscheint auf Tomcat Konsole System.out.println("Resultat : " + result); return result; } }

Home Interface: MoneyExchanHome Interface: MoneyExchanHome Interface: MoneyExchanHome Interface: MoneyExchangeHome.javageHome.javageHome.javageHome.java

package beans;

import javax.ejb.EJBHome; import java.rmi.RemoteException; import javax.ejb.CreateException;

public interface MoneyExchangeHome extends EJBHome { public MoneyExchange create() throws RemoteException, CreateException; }

RemoteRemoteRemoteRemote Interface: MoneyExchange.java Interface: MoneyExchange.java Interface: MoneyExchange.java Interface: MoneyExchange.java

package beans;

import java.rmi.RemoteException; import javax.ejb.EJBObject;

public interface MoneyExchange extends EJBObject { public String change(float amount, float rate) throws RemoteException; }

Bean Class: MoneyExchBean Class: MoneyExchBean Class: MoneyExchBean Class: MoneyExchangeBean.javaangeBean.javaangeBean.javaangeBean.java

package beans;

import javax.ejb.*; import javax.naming.*;

public class MoneyExchangeBean implements SessionBean {

private InitialContext ictx;

public String change(float amount, float rate) { System.out.println("amount : " + amount); System.out.println("amount : " + rate); System.out.println("amount : " + amount * rate); return "" + (amount * rate); }

public void setSessionContext(SessionContext sc) { } public void ejbCreate() { } public void ejbRemove() { } public void ejbActivate() { } public void ejbPassivate() { } }

Page 196: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 196 von total 218 Seiten

Deployment Descriptor: web.xmlDeployment Descriptor: web.xmlDeployment Descriptor: web.xmlDeployment Descriptor: web.xml

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">

<web-app> <description> Example web application illustrating the use of tags in the DBTags custom tag library, from the JAKARTA-TAGLIBS project. </description> <welcome-file-list> <welcome-file>src/jsp/Currency.jsp</welcome-file> </welcome-file-list> <taglib> <taglib-uri> http://jakarta.apache.org/taglibs/dbtags</taglib-uri> <taglib-location> /WEB-INF/taglibs-dbtags.tld</taglib-location> </taglib> </web-app>

Deployment Descriptor: ejbDeployment Descriptor: ejbDeployment Descriptor: ejbDeployment Descriptor: ejb----jar.xmljar.xmljar.xmljar.xml

<ejb-jar> <description> Money Exchange </description> <display-name> MoneyExchange </display-name> <enterprise-beans> <session>

<ejb-name> moneyexchange </ejb-name>

<home> beans.MoneyExchangeHome </home>

<remote> beans.MoneyExchange </remote>

<ejb-class> beans.MoneyExchangeBean </ejb-class>

<session-type> Stateless </session-type>

<transaction-type> Bean </transaction-type>

</session> </enterprise-beans> </ejb-jar>

Page 197: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 197 von total 218 Seiten

29.13 Lösung zu Übung ee91 : EJB Security

Home Interface: SecurityTestHome.javaHome Interface: SecurityTestHome.javaHome Interface: SecurityTestHome.javaHome Interface: SecurityTestHome.java

package beans;

import javax.ejb.EJBHome; import java.rmi.RemoteException; import javax.ejb.CreateException;

public interface SecurityTestHome extends EJBHome {

public SecurityTest create() throws RemoteException, CreateException; }

Remote Interface: SecurityTest.javaRemote Interface: SecurityTest.javaRemote Interface: SecurityTest.javaRemote Interface: SecurityTest.java

package beans;

import java.rmi.RemoteException; import javax.ejb.EJBObject; import javax.security.auth.login.FailedLoginException;

public interface SecurityTest extends EJBObject {

public String doSomething(String role) throws FailedLoginException, RemoteException;

public String getPrincipalInfo(String role) throws RemoteException; }

Bean Class: SecurityTestBean.javaBean Class: SecurityTestBean.javaBean Class: SecurityTestBean.javaBean Class: SecurityTestBean.java

package beans;

import java.security.Principal;

import javax.ejb.SessionBean; import javax.ejb.SessionContext; import javax.security.auth.login.FailedLoginException;

public class SecurityTestBean implements SessionBean { private SessionContext sc;

public void ejbCreate() { System.out.println("ejbCreate() called"); } public void ejbActivate() { System.out.println("ejbActivate() called"); } public void ejbPassivate() { System.out.println("ejbPassivate() called");} public void ejbRemove() { System.out.println("ejbRemove() called"); } public void setSessionContext(SessionContext context) { sc = context; }

public String doSomething(String role) throws FailedLoginException { Principal p = sc.getCallerPrincipal(); if (sc.isCallerInRole(role)) { return "Principal (" + p + ") identifies as Role \"" + role + "\""; } else { throw new FailedLoginException("wrong Principal / wrong Role"); } }

public String getPrincipalInfo(String role) { Principal p = sc.getCallerPrincipal(); boolean r = sc.isCallerInRole(role); System.out.println("callerPrincipal=" + p); System.out.println("callerRole(" + role + ") = " + r); return "Principal = " + p + " Role(" + role +") = " + r; } }

Page 198: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 198 von total 218 Seiten

Deployment Descriptor: ejbDeployment Descriptor: ejbDeployment Descriptor: ejbDeployment Descriptor: ejb----jar.xmljar.xmljar.xmljar.xml

<ejb-jar> <display-name>JaasSecurityTest</display-name> <enterprise-beans> <session> <ejb-name>EJBSecurity</ejb-name> <home>beans.SecurityTestHome</home> <remote>beans.SecurityTest</remote> <ejb-class>beans.SecurityTestBean</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> <security-role-ref> <role-name>admin</role-name> <role-link>staff</role-link> </security-role-ref> <security-role-ref> <role-name>user</role-name> <role-link>customer</role-link> </security-role-ref> </session> </enterprise-beans>

<assembly-descriptor> <security-role> <role-name>guest</role-name> </security-role> <security-role> <role-name>customer</role-name> </security-role> <security-role> <role-name>staff</role-name> </security-role>

<method-permission> <role-name>guest</role-name> <method> <ejb-name>EJBSecurity</ejb-name> <method-intf>Home</method-intf> <method-name>*</method-name> </method> <method> <ejb-name>EJBSecurity</ejb-name> <method-intf>Remote</method-intf> <method-name>getPrincipalInfo</method-name> </method> </method-permission>

<method-permission> <role-name>customer</role-name> <method> <ejb-name>EJBSecurity</ejb-name> <method-intf>Home</method-intf> <method-name>*</method-name> </method> <method> <ejb-name>EJBSecurity</ejb-name> <method-intf>Remote</method-intf> <method-name>getPrincipalInfo</method-name> </method> <method> <ejb-name>EJBSecurity</ejb-name> <method-intf>Remote</method-intf> <method-name>doSomething</method-name> </method> </method-permission>

<method-permission> <role-name>staff</role-name> <method> <ejb-name>EJBSecurity</ejb-name> <method-name>*</method-name> </method> </method-permission> </assembly-descriptor> </ejb-jar>

Page 199: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 199 von total 218 Seiten

Client ApplClient ApplClient ApplClient Application: SecurityTestClient.javaication: SecurityTestClient.javaication: SecurityTestClient.javaication: SecurityTestClient.java

package client;

import java.io.FileInputStream; import java.util.Properties; import javax.naming.InitialContext; import javax.security.auth.callback.*; import javax.security.auth.login.LoginContext; import beans.*;

public class SecurityTestClient {

static class AppCallbackHandler implements CallbackHandler { private String username; private char[] password;

public AppCallbackHandler(String username, char[] password) { this.username = username; this.password = password; }

public void handle(Callback[] callbacks) throws java.io.IOException, UnsupportedCallbackException { for (int i = 0; i < callbacks.length; i++) { if (callbacks[i] instanceof NameCallback) { NameCallback nc = (NameCallback) callbacks[i]; nc.setName(username); } else if (callbacks[i] instanceof PasswordCallback) { PasswordCallback pc = (PasswordCallback) callbacks[i]; pc.setPassword(password); } else { throw new UnsupportedCallbackException(callbacks[i],"Unrecognized Callback"); } } } }

public static void main(String args[]) throws Exception {

/* usernames : admin, user, guest * passwords : admin, user, guest * roles : staff, customer, guest */

String name = "admin"; String pass = "admin"; String role = "staff"; char[] password = pass.toCharArray();

System.setProperty("java.security.auth.login.config", "[JBoss-Home]/client/auth.conf");

// [JBoss-Home]/client/auth.conf: // SecurityTest { // org.jboss.security.ClientLoginModule required debug=false; // };

try { AppCallbackHandler handler = new AppCallbackHandler(name, password); LoginContext lc = new LoginContext("SecurityTest", handler); lc.login();

Properties env = new Properties(); env.load(new FileInputStream("resources/jndi.properties")); InitialContext initial = new InitialContext(env);

SecurityTestHome home = (SecurityTestHome) initial.lookup("ejb/Security"); SecurityTest st = home.create();

System.out.println( "Principal : " + name + " wants to getPrincipalInfo : " + st.getPrincipalInfo(role)); System.out.println( "Principal : " + name + " wants to doSomething : " + st.doSomething(role));

st.remove(); lc.logout();

Page 200: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 200 von total 218 Seiten

} catch (Exception e) { System.err.println("Failed :"); Throwable t = e; while (t != null) { System.err.println("Type: " + t.getClass().getName()); System.err.println("Message: " + t.getMessage()); System.err.println("-----"); t = t.getCause(); } } } }

User Policy File: users.propertiesUser Policy File: users.propertiesUser Policy File: users.propertiesUser Policy File: users.properties

admin=admin user=user guest=guest

Role Policy File: roles.propertiesRole Policy File: roles.propertiesRole Policy File: roles.propertiesRole Policy File: roles.properties

admin=staff guest=guest user=customer

Deployment Descriptor: jboss.xmlDeployment Descriptor: jboss.xmlDeployment Descriptor: jboss.xmlDeployment Descriptor: jboss.xml

<?xml version="1.0" encoding="UTF-8"?> <jboss> <!-- All bean containers use this security manager by default --> <security-domain>java:/jaas/EJBSecurityTest</security-domain> <enterprise-beans> <session> <ejb-name>EJBSecurity</ejb-name> <jndi-name>ejb/Security</jndi-name> </session> </enterprise-beans> </jboss>

Authentification Configuration File: [JBossAuthentification Configuration File: [JBossAuthentification Configuration File: [JBossAuthentification Configuration File: [JBoss----Home]/client/auth.confHome]/client/auth.confHome]/client/auth.confHome]/client/auth.conf

...

other { // jBoss LoginModule org.jboss.security.ClientLoginModule required ;

// Put your login modules that need jBoss here }; EJBSecurityTest { // EJBSecurityTest JBoss Login MOdule org.jboss.security.ClientLoginModule required debug=false; };

Output:Output:Output:Output:

Principal : admin wants to getPrincipalInfo : Principal = admin Role(staff) = true

Principal : admin wants to doSomething :

Principal (admin) identifies as Role "staff"

Page 201: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 201 von total 218 Seiten

29.14 Lösung zu Übung ee10 : EJB Transaction

Home Interface: AccountHome.javaHome Interface: AccountHome.javaHome Interface: AccountHome.javaHome Interface: AccountHome.java

package beans;

import java.rmi.RemoteException; import javax.ejb.*;

public interface AccountHome extends EJBHome {

public Account create(String id, String owner) throws RemoteException, CreateException;

public Account findByPrimaryKey(String id) throws FinderException, RemoteException; }

Remote Interface: Account.javaRemote Interface: Account.javaRemote Interface: Account.javaRemote Interface: Account.java

package beans;

import javax.ejb.EJBObject; import java.rmi.RemoteException;

public interface Account extends EJBObject { public double getBalance() throws RemoteException;

public String getOwner() throws RemoteException;

public void deposit(double amount) throws RemoteException, IllegalOperationException;

public void withdraw(double amount) throws RemoteException, IllegalOperationException; }

Bean Class: AccountBean.javaBean Class: AccountBean.javaBean Class: AccountBean.javaBean Class: AccountBean.java

package beans;

import java.sql.*; import javax.ejb.CreateException; import javax.ejb.EJBException; import javax.ejb.EntityBean; import javax.ejb.EntityContext; import javax.ejb.FinderException; import javax.ejb.NoSuchEntityException; import javax.ejb.ObjectNotFoundException; import javax.naming.NamingException;

public class AccountBean implements EntityBean {

private EntityContext context; private Connection con; private String id; private String owner; private double balance;

public double getBalance() { log(); return balance; }

public String getOwner() { log(); return owner; }

public void deposit(double amount) throws IllegalOperationException { log(); balance += amount; if (balance < 0) throw new IllegalOperationException("balance becomes less than 0"); }

Page 202: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 202 von total 218 Seiten

public void withdraw(double amount) throws IllegalOperationException { log(); balance -= amount; if (balance < 0) throw new IllegalOperationException("balance becomes less than 0"); }

public String ejbCreate(String id, String owner) throws CreateException { log(); try { insertRow(id, owner, 0.0); } catch (Exception ex) { throw new EJBException("ejbCreate: " + ex.getMessage()); }

this.id = id; this.owner = owner;

return id; }

public String ejbFindByPrimaryKey(String primaryKey) throws FinderException { log(); boolean result;

try { result = selectByPrimaryKey(primaryKey); } catch (Exception e) { throw new EJBException("ejbFindByPrimaryKey: " + e.getMessage()); } if (result) { return primaryKey; } else { throw new ObjectNotFoundException("Row for id " + primaryKey + " not found."); } }

public void ejbRemove() { log(); try { deleteRow(id); } catch (Exception ex) { throw new EJBException("ejbRemove: " + ex.getMessage()); } }

public void setEntityContext(EntityContext context) { log(); this.context = context; try { makeConnection(); } catch (Exception ex) { throw new EJBException("Unable to connect to database. " + ex.getMessage()); } }

public void unsetEntityContext() { log(); try { con.close(); } catch (SQLException e) { throw new EJBException("unsetEntityContext: " + e.getMessage()); } }

public void ejbActivate() { log(); id = (String) context.getPrimaryKey(); }

public void ejbPassivate() { log(); id = null; }

public void ejbLoad() { log();

Page 203: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 203 von total 218 Seiten

try { loadRow(); } catch (Exception ex) { throw new EJBException("ejbLoad: " + ex.getMessage()); } }

public void ejbStore() { log(); try { storeRow(); } catch (Exception ex) { throw new EJBException("ejbStore: " + ex.getMessage()); } }

public void ejbPostCreate(String id, String owner) { log(); }

public AccountBean() { log(); }

private void log() { StackTraceElement ste = new Exception().getStackTrace()[1]; System.out.println(this + "[" + Thread.currentThread().hashCode() + "]: " + ste.getMethodName()); }

/** ********************* Database Routines ************************ */

private void makeConnection() throws NamingException, SQLException { log(); final String userName = "root"; final String password = ""; final String databaseUrl = "jdbc:mysql://localhost/ee"; try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException cnfe) { System.err.println("Driver not found: " + cnfe.getMessage()); }

try { con = DriverManager.getConnection(databaseUrl, userName, password); } catch (SQLException sqle) { throw new SQLException("Could not get connection to db:" + sqle.getMessage()); } }

private void insertRow(String id, String owner, double balance) throws SQLException { String insertStatement = "insert into accounts values ( ? , ? , ? )"; PreparedStatement prepStmt = con.prepareStatement(insertStatement);

prepStmt.setString(1, id); prepStmt.setString(2, owner); prepStmt.setDouble(3, balance);

prepStmt.executeUpdate(); prepStmt.close(); }

private void deleteRow(String id) throws SQLException { String deleteStatement = "delete from accounts where id = ? "; PreparedStatement prepStmt = con.prepareStatement(deleteStatement);

prepStmt.setString(1, id);

prepStmt.executeUpdate(); prepStmt.close(); }

private boolean selectByPrimaryKey(String primaryKey) throws SQLException { log();

String selectStatement = "select id from accounts where id = ? "; PreparedStatement prepStmt = con.prepareStatement(selectStatement); prepStmt.setString(1, primaryKey); ResultSet rs = prepStmt.executeQuery();

boolean result = rs.next(); prepStmt.close();

return result; }

Page 204: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 204 von total 218 Seiten

private void loadRow() throws SQLException { String selectStatement = "select owner, balance from accounts where id = ? "; PreparedStatement prepStmt = con.prepareStatement(selectStatement); prepStmt.setString(1, this.id);

ResultSet rs = prepStmt.executeQuery(); if (rs.next()) { this.owner = rs.getString(1); this.balance = rs.getDouble(2); prepStmt.close();

} else { prepStmt.close(); throw new NoSuchEntityException("Row for id " + id + " not found in database."); } }

private void storeRow() throws SQLException { String updateStatement = "update accounts set owner = ? , balance = ? where id = ?"; PreparedStatement prepStmt = con.prepareStatement(updateStatement); prepStmt.setString(1, owner); prepStmt.setDouble(2, balance); prepStmt.setString(3, id); int rowCount = prepStmt.executeUpdate(); prepStmt.close(); if (rowCount == 0) { throw new EJBException("Storing row for id " + id + " failed."); } } }

Home Interface: BankHome.javaHome Interface: BankHome.javaHome Interface: BankHome.javaHome Interface: BankHome.java

package beans;

import java.rmi.RemoteException; import javax.ejb.*;

public interface BankHome extends EJBHome { public Bank create() throws RemoteException, CreateException; }

Remote Interface: Bank.javaRemote Interface: Bank.javaRemote Interface: Bank.javaRemote Interface: Bank.java

package beans;

import javax.ejb.EJBObject; import java.rmi.RemoteException;

public interface Bank extends EJBObject {

public Account getAccount(String number) throws RemoteException;

public void transfer(Account from, Account to, double amount) throws RemoteException, IllegalOperationException; }

Page 205: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 205 von total 218 Seiten

Bean Class: BankBean.javaBean Class: BankBean.javaBean Class: BankBean.javaBean Class: BankBean.java

package beans;

import javax.ejb.CreateException; import javax.ejb.EJBException; import javax.ejb.SessionBean; import javax.ejb.SessionContext; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.rmi.PortableRemoteObject;

public class BankBean implements SessionBean {

private SessionContext context; private AccountHome accountHome;

public void ejbCreate() throws CreateException { log(); try { InitialContext initial = new InitialContext(); Object objref = initial.lookup("java:comp/env/ejb/AccountHome"); accountHome = (AccountHome) PortableRemoteObject.narrow(objref, AccountHome.class); } catch (NamingException e) { throw new EJBException(e.getMessage()); } }

public void ejbRemove() { log(); }

public void ejbActivate() { log(); }

public void ejbPassivate() { log(); }

public void setSessionContext(SessionContext context) { log(); this.context = context; }

public Account getAccount(String number) { log(); try { return accountHome.findByPrimaryKey(number); } catch (Exception e) { throw new EJBException(e.getMessage()); } }

public void transfer(Account from, Account to, double amount) throws IllegalOperationException { log(); try { to.deposit(amount); from.withdraw(amount); } catch (IllegalOperationException e) { context.setRollbackOnly(); } catch (Exception e) { throw new EJBException(e.getMessage()); } }

private void log() { StackTraceElement ste = new Exception().getStackTrace()[1]; System.out.println(this + "[" + Thread.currentThread().hashCode() + "]: " + ste.getMethodName()); } }

Page 206: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 206 von total 218 Seiten

Exception Class: IllegalOperationException.javaException Class: IllegalOperationException.javaException Class: IllegalOperationException.javaException Class: IllegalOperationException.java

package beans;

public class IllegalOperationException extends Exception { public IllegalOperationException(String reason) { System.out.println(reason); } }

Deployment Descriptor: ejbDeployment Descriptor: ejbDeployment Descriptor: ejbDeployment Descriptor: ejb----jar.xml.javajar.xml.javajar.xml.javajar.xml.java

<ejb-jar> <enterprise-beans> <entity> <display-name>AccountEJB</display-name> <ejb-name>AccountEJB</ejb-name> <home>beans.AccountHome</home> <remote>beans.Account</remote> <ejb-class>beans.AccountBean</ejb-class> <persistence-type>Bean</persistence-type> <prim-key-class>java.lang.String</prim-key-class> <reentrant>False</reentrant> <resource-ref> <res-ref-name>jdbc/BankDB</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> <res-sharing-scope>Shareable</res-sharing-scope> </resource-ref> </entity> <session> <display-name>BankEJB</display-name> <ejb-name>BankEJB</ejb-name> <home>beans.BankHome</home> <remote>beans.Bank</remote> <ejb-class>beans.BankBean</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> <ejb-ref> <ejb-ref-name>ejb/AccountHome</ejb-ref-name> <ejb-ref-type>Entity</ejb-ref-type> <home>beans.AccountHome</home> <remote>beans.Account</remote> <ejb-link>AccountEJB</ejb-link> </ejb-ref> </session> </enterprise-beans> <assembly-descriptor> <!-- BankEJB --> <container-transaction> <method> <ejb-name>BankEJB</ejb-name> <method-name>transfer</method-name> </method> <trans-attribute>Required</trans-attribute> </container-transaction> <!-- AccountEJB --> <container-transaction> <method> <ejb-name>AccountEJB</ejb-name> <method-name>deposit</method-name> </method> <method> <ejb-name>AccountEJB</ejb-name> <method-name>withdraw</method-name> </method> <trans-attribute>Required</trans-attribute> </container-transaction> <container-transaction> <method> <ejb-name>AccountEJB</ejb-name> <method-name>getBalance</method-name> </method> <method> <ejb-name>AccountEJB</ejb-name> <method-name>getOwner</method-name> </method> <trans-attribute>Required</trans-attribute> </container-transaction> </assembly-descriptor> </ejb-jar>

Page 207: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 207 von total 218 Seiten

29.15 Lösung zu Übung ee11 : MDB - WetterTopic

Bean Class: WetterBean.javaBean Class: WetterBean.javaBean Class: WetterBean.javaBean Class: WetterBean.java

package beans;

import javax.ejb.MessageDrivenContext; import javax.jms.MapMessage;

public class WetterBean implements javax.ejb.MessageDrivenBean, javax.jms.MessageListener { private MessageDrivenContext ejbContext;

public void onMessage(javax.jms.Message message) { try { MapMessage mapMessage = (MapMessage) message; System.out.println("WetterMDB: Wetter=" + mapMessage.getString("Wetterlage") + " Wind=" + mapMessage.getString("Windrichtung") + " Temp=" + mapMessage.getDouble("Temperatur") + "C"); } catch (Exception ex) { System.out.println(ex.getMessage()); ex.printStackTrace(); } }

public void ejbCreate() { }

public void ejbRemove() { ejbContext = null; }

public void setMessageDrivenContext(MessageDrivenContext messageDrivenContext) { this.ejbContext = messageDrivenContext; } }

Client Application: WetterClient.javaClient Application: WetterClient.javaClient Application: WetterClient.javaClient Application: WetterClient.java

package client;

import javax.naming.*; import java.util.Hashtable; import javax.jms.*;

public class WetterClient { public static void main(String[] args) throws Exception { Hashtable props = new Hashtable(); props.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory"); props.put("java.naming.provider.url", "jnp://localhost:1099"); props.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces"); props.put("jnp.socket.Factory", "org.jnp.interfaces.TimedSocketFactory"); Context ctx = new InitialContext(props); TopicConnectionFactory qcf = (TopicConnectionFactory) ctx .lookup("ConnectionFactory"); Topic topic = (Topic) ctx.lookup("topic/WetterTopic"); TopicConnection connect = qcf.createTopicConnection(); TopicSession session = connect.createTopicSession(false, TopicSession.AUTO_ACKNOWLEDGE); connect.start(); TopicPublisher publisher = session.createPublisher(topic);

String[] wetterlagen = { "Sonnig", "Wolkig", "Regen" }; String[] windrichtungen = { "Nord", "West", "Sued", "Ost" }; for (int i = 0; i < 10; i++) { int rndm = (int) (Math.random() * 300); String sWetterlage = wetterlagen[rndm % 3]; String sWindrichtung = windrichtungen[rndm % 4]; double dTemperatur = (double) (rndm - 50) / 10; MapMessage msg = session.createMapMessage(); msg.setString("Wetterlage", sWetterlage); msg.setString("Windrichtung", sWindrichtung); msg.setDouble("Temperatur", dTemperatur); publisher.publish(msg);

Page 208: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 208 von total 218 Seiten

System.out.println("Sending Wetterlage=" + sWetterlage + " Windrichtung=" + sWindrichtung + " Temparatur=" + dTemperatur + "C"); // System.out.println( "Sending " + msg.toString() ); }

session.close(); connect.close(); } }

Deployment Descriptor: ejbDeployment Descriptor: ejbDeployment Descriptor: ejbDeployment Descriptor: ejb----jar.xmljar.xmljar.xmljar.xml

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd"> <ejb-jar> <enterprise-beans> <message-driven> <ejb-name>WetterBean</ejb-name> <ejb-class>beans.WetterBean</ejb-class> <transaction-type>Container</transaction-type> <acknowledge-mode>Auto-acknowledge</acknowledge-mode> <message-driven-destination> <destination-type>javax.jms.Topic</destination-type> <subscription-durability>NonDurable</subscription-durability> </message-driven-destination> </message-driven> </enterprise-beans> </ejb-jar>

Deployment Descriptor: jboss.xmlDeployment Descriptor: jboss.xmlDeployment Descriptor: jboss.xmlDeployment Descriptor: jboss.xml

<?xml version="1.0"?> <jboss> <enterprise-beans> <message-driven> <ejb-name>WetterBean</ejb-name> <configuration-name>Standard Message Driven Bean</configuration-name> <destination-jndi-name>topic/WetterTopic</destination-jndi-name> </message-driven> </enterprise-beans> </jboss>

Output:Output:Output:Output: Sending Wetterlage=Wolkig Windrichtung=Ost Temparatur=24.5C Sending Wetterlage=Regen Windrichtung=Sued Temparatur=15.6C Sending Wetterlage=Regen Windrichtung=West Temparatur=0.3C Sending Wetterlage=Wolkig Windrichtung=Sued Temparatur=24.8C Sending Wetterlage=Regen Windrichtung=Sued Temparatur=14.4C Sending Wetterlage=Wolkig Windrichtung=West Temparatur=2.3C Sending Wetterlage=Sonnig Windrichtung=Sued Temparatur=16.0C Sending Wetterlage=Regen Windrichtung=Sued Temparatur=1.2C Sending Wetterlage=Sonnig Windrichtung=Sued Temparatur=2.8C Sending Wetterlage=Wolkig Windrichtung=West Temparatur=4.7C

ServerLog:ServerLog:ServerLog:ServerLog: 11:48:36,375 INFO [STDOUT] WetterMDB: Wetter=Wolkig Wind=Ost Temp=24.5C 11:48:36,406 INFO [STDOUT] WetterMDB: Wetter=Regen Wind=Sued Temp=15.6C 11:48:36,406 INFO [STDOUT] WetterMDB: Wetter=Regen Wind=West Temp=0.3C 11:48:36,406 INFO [STDOUT] WetterMDB: Wetter=Wolkig Wind=Sued Temp=24.8C 11:48:36,421 INFO [STDOUT] WetterMDB: Wetter=Regen Wind=Sued Temp=14.4C 11:48:36,421 INFO [STDOUT] WetterMDB: Wetter=Wolkig Wind=West Temp=2.3C 11:48:36,421 INFO [STDOUT] WetterMDB: Wetter=Sonnig Wind=Sued Temp=16.0C 11:48:36,421 INFO [STDOUT] WetterMDB: Wetter=Regen Wind=Sued Temp=1.2C 11:48:36,437 INFO [STDOUT] WetterMDB: Wetter=Sonnig Wind=Sued Temp=2.8C 11:48:36,437 INFO [STDOUT] WetterMDB: Wetter=Wolkig Wind=West Temp=4.7C

Page 209: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 209 von total 218 Seiten

GGGG GlossarGlossarGlossarGlossar ObjectObjectObjectObject VersionVersionVersionVersion BeschreibungBeschreibungBeschreibungBeschreibung

Annotation EJB 3.0

Die Programmiersprache Java stellt mit Javadoc und den Annotationen zwei Mechanismen zum Einbinden von Metadaten zur Verfügung. Diese werden insbesondere im J2EE-Umfeld eingesetzt, um verschiedene Dateien automatisiert zu erzeugen. Dazu zählen beispielsweise SQL-Dateien, Deployment-Deskriptoren und die mit Enterprise Java Beans verbundenen Schnittstellen (Remote Interface, Home Interface, ...). Mit der Sprachversion Java 5 wurden Annotationen als ein eigenes Sprachelement geschaffen. Annotationen werden im Quelltext durch ein @-Zeichen gefolgt vom Namen der Annotation gekennzeichnet. Zusätzlich ist es auch möglich, Annotationen Parameter zu übergeben. Ausserdem können den vorgegebenen Annotationen auch eigene hinzugefügt werden. Annotationen können mittels des Annotation Processing Toolkits (APT) direkt im Quelltext oder mittels Reflexion zur Laufzeit eines Programms ausgewertet werden. Dadurch entstehen unter anderem weitere Einsatzmöglichkeiten im Vergleich zu Javadoc. So wertet beispielsweise der Compiler selbst einige Annotationen aus. Das folgende Beispiel zeigt, wie man eine Compiler-Warnung mittels der entsprechenden Annotation unterdrückt: public class A { @SuppressWarnings("unchecked") public void meineMethode() {} }

Attached Object EJB 3.0 Bezeichnet eine vom Entity Manager aktuelle verwaltete Instanz einer Entity Bean mit den darin enthaltenen Daten aus einer Datenbank.

Bean-Klasse EJB 1.x EJB 2.x EJB 3.0

Die Bean-Klasse ist das Software-Artefakt einer EJB-Komponente, in der die eigentliche Implementierung der Geschäftslogik vorhanden ist. In der gängigen OO-Schreibweise würde man diese Klasse als Implementations-Klasse bezeichnen (z.B. KundeImpl). Im EJB-Bereich wird der Begriff Bean-Klasse verwendet (z.B. KundeBean).

Bean-Managed Persistence EJB 2.x EJB 3.0

Einer der beiden Persistenzmechanismen für Entity Beans vor EJB 3.0

Bei den Entity Beans, die Bean-Managed Persistence (BMP) verwenden, sind Sie als Entwickler dafür verantwortlich, diese Aufgabe durch Implementierung des entsprechenden Java-Codes zu lösen. Das bedeutet im Wesentlichen, dass der Entwickler die persistenten Attribute der Entity Bean in geeigneter Weise der Persistenzschicht (z.B. den Feldern einer Datenbanktabelle) zuordnen muss. Hierzu implementiert er die Logik für den Zugriff auf die Persistenzschicht (z.B. Datenbank per JDBC oder Legacy-System wie SAP per JCA ) in der Bean-Klasse.

Der EJB-Container entscheidet, wann etwas passiert; der Entwickler entscheidet, was passiert

BMP EJB 2.x EJB 3.0

Akronym für Bean-managed Persistence

Business-Logik EJB 1.x EJB 2.x EJB 3.0

Anwendungslogik, die den Teil des Source-Codes einer Anwendung oder einer EJB bezeichnet, welche die Funktionen bereitstellt, für die die Anwendung (Enterprise Bean) entwickelt wurde.

Business Interface EJB 3.0

Business Interface bezeichnet in EJB 3 POJI-Typ Interfaces. D.h. diese Interfaces dürfen nicht mehr von EJB[Local]Object erben wie dies bei den so genannten Component Interfaces der Fall war.

Session Beans erfordern ein Business Interface. Im Gegensatz zu Entity Beans müssen EJB 3 Entitys kein Business Interface mehr aufweisen.

Callback-Methoden EJB 2.x EJB 3.0

Bei EJB 2.x wird bei der Implementierung der Bean-Klasse einer EJB-Komponente verlangt, dass eben diese Klassen entsprechend dem Typ der EJB-Komponente das entsprechende Callback Interface (javax.ejb.SessionBean, javax.ejb.MessageDrivenBean oder javax.ejb.EntityBean) implementiert. Zum einen kennzeichnen diese Interfaces, um was für einen Typ einer EJB es sich handelt. Zum anderen definieren diese Interfaces Callback Methoden, die vom EJB-Container im Lebenszyklus einer EJB-Komponente aufgerufen werden. Der Entwickler ist verpflichtet, die im jeweiligen Interface deklarierten Callback-Methoden in seiner Bean-Klasse zu implementieren.

Bei EJB 3.0 müssen die zuvor genannten Callback Interfaces nicht mehr von der Bean-Klasse implementiert werden. Da man nun nicht mehr gezwungen ist, die entsprechenden Callback-Methoden zu implementieren, führt dies zu einer Reduzierung von Entwicklungszeiten und -aufwänden. Um es zu ermöglichen, sich in den Ablauf der Steuerung des Lebenszyklus einer EJB-Komponente einzuklinken, gibt es ein Set von vordefinierten Meta-Annotationen. Diese erlauben, beliebige Methoden in der Bean-Klasse zu kennzeichnen, sodass diese in Abhängigkeit der verwendeten Meta-Annotation zu definierten Zeitpunkten aufgerufen werden. Angewendet werden können diese Meta-Annotationen auf alle EJB-Typen. Für das Einklinken in die Steuerung des Lebenszyklus von Session Beans und Message-driven Beans stehen die Meta-Annotationen

Page 210: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 210 von total 218 Seiten

ObjectObjectObjectObject VersionVersionVersionVersion BeschreibungBeschreibungBeschreibungBeschreibung @PostConstruct, @PreDestroy, @PostActivate und @PrePassivate zur Verfügung. Für das Einklinken in die Steuerung des Lebenszyklus von Entity Beans stehen folgende Meta-Annotationen zur Verfügung: @PrePersist, @PostPersist, @PreRemove, @PostRemove, @PreUpdate, @PostUpate, @PostLoad.

CMP EJB 2.x EJB 3.0

Akronym für Container-managed Persistence

Component Interface EJB 1.x EJB 2.x EJB 3.0

Das Component Interface ist die Geschäftsschnittstelle einer EJB-Komponente. Diese kann es in zwei Ausprägungen geben: als lokale Schnittstelle (Zugriffe sind hierbei nur innerhalb des selben Prozesses möglich --> siehe Local Interface) und/oder als remote Schnittstelle (hierbei können die Client über Rechner- und Prozessgrenzen hinweg auf die EJB-Komponente zugreifen --> siehe Remote Interface).

Configuration by Exception EJB 3.0

Container-Managed Persistence EJB 2.x EJB 3.0

Einer der beiden Persistenzmechanismen für Entity Beans vor EJB 3.0

Bei der Verwendung von Container-Managed Persistence (CMP) brauchen Sie als Entwickler die Logik zur Synchronisation zwischen Entity Beans und Persistenzschicht nicht zu implementieren. Sie wird durch Werkzeuge des Applikationsservers generiert. Die Aufgabe des Entwicklers beschränkt sich auf die Deklaration der persistenten Attribute sowie der Beziehungen zwischen Entity Beans. Die Synchronisation zur Laufzeit wird durch einen speziellen Teil des EJB-Containers - den sogenannten Persistenz-Manager - sichergestellt.

DTO Data Transfere Object

EJB 2.x EJB 3.0

Ab JEE Version 5 unterstützt das System ein Attachment, Detachment und Reattachment. Die Entity Bean ist nun ein POJO, dessen Persistenz mit Hilfe des EntityManagers gesteuert werden kann. Das bekannte JEE Design Pattern "Datentransferobjekt" (englisch DataTransferObjekt, kurz: DTO) ist somit obsolet, da nun das Geschäftsobjekt selbst über verschiedene Schichten beispielsweise zu einem Client transportiert werden kann. Datentransferobjekte dienten der Kapselung von Geschäftsobjekten (also die reinen Daten, ohne Verhalten), und dessen Entkopplung von technischem Code. Gewöhnlich ist mit JEE 5 die recht umständliche und mühselige Nutzung von "Datentransferobjekten" ein Anti-Pattern.

DD EJB 1.x EJB 2.x EJB 3.0

Akronym für Deployment Descriptor

Detached Entity Detached Object

EJB 3.0

Bezeichnet eine Instanz einer EJB 3 Entity, die nicht mehr mit ihrem originären Persistence Context assoziiert ist. Damit ist eine Synchronisierung ihrer Daten mit der Datenbank nicht mehr gegeben. Ein solches Objekt wird nicht mehr durch den EntityManager verwaltet; es ist also eine vom EntityManager nicht mehr gemanagte Instanz einer EJB 3 Entity.

Detached Objects können durch verschiedene Umstände entstehen. U.a. beispielsweise dann, wenn eine Instanz einer EJB 3 Entity serialisiert wird. In diesem Fall ist die serialisierte Form der EJB 3 Entity ein Detached Object.

Dependency Injection EJB 3.0

Der Begriff Dependency Injection (DI) ist eine spezialisierte Version des Inversion of Control-Musters. Martin Fowler hat diesen Begriff in http://martinfowler.com/articles/injection.html eingeführt, da die Charakteristik der Verwendung der Inversion of Control in den aktuell in den Medien stark vertretenen leichtgewichtigen Container/Frameworks eher den Charakter der Injektion von Referenzen über benötigte Objekte/Klassen hat.

Die Motivation für die Einführung von DI in EJB 3 ist es, für EJB-Komponenten den Zugriff auf Ressourcen bzw. den Erhalt von Referenzen auf Ressourcen zu vereinfachen und damit letztlich auch die Notwendigkeit des Implementierens von Code für den Zugriff über die JNDI API. Dependency Injection bedeutet für die EJB-Technologie, dass der Entwickler den Code für den Erhalt von Referenzen auf Ressourcen mittels der Nutzung der JNDI API nicht mehr selbst implementieren muss, sondern die benötigten Referenzen durch die Verwendung von Annotationen bzw. die Hinterlegung in XML anfordert. Der Container stellt dann zur Laufzeit die benötigten Referenzen auf Ressourcen zur Verfügung. D.h. EJB-Komponenten fragen nicht mehr aktiv den sie umgebenden Container nach Referenzen, sondern bekommen Referenzen auf Ressourcen von außen - vom Container - injiziert.

Der Entwickler annotiert dazu mittels Meta-Annotation wahlweise Instanzvariablen oder Setter-Methoden einer EJB-Komponente, wo der EJB-Container die gewünschten Referenzen injizieren (einfügen) soll. Optional kann der Entwickler diese Informationen auch in XML hinterlegen. Der Container sorgt automatisch dafür, dass spätestens vor der Ausführung der ersten Methode der EJB-Komponente die entsprechenden Referenzen der EJB-Komponente zur Verfügung gestellt werden.

Die für EJB 3 bevorzugte Variante ist die Nuztung von Annotationen.

Deployment EJB 1.x EJB 2.x EJB 3.0

Prozess der Integration einer Komponente in den J2EE-Server.

Page 211: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 211 von total 218 Seiten

ObjectObjectObjectObject VersionVersionVersionVersion BeschreibungBeschreibungBeschreibungBeschreibung

Deployment Descriptor EJB 1.x EJB 2.x EJB 3.0

Der Deployment Deskriptor enthält im XML-Format Laufzeit- und Kompilierungszeitinformationen für die Generierung und Ausführung von EJB-Komponenten. Hierbei handelt es sich um deklarative Programmierung, da der Entwickler Features/Funktionalitäten der EJB-Komponenten durch "einfaches" angeben bestimmter Schlüsselwörter innerhalb eines Deployment Deskriptors erreichen kann, ohne programmieren zu müssen. Beispielsweise lässt sich darüber die Transaktionalität von EJB-Komponenten steuern.

Eager Load EJB 3.0

Bezeichnet eine Fetching-Strategie der Java Persistence API. Einfach gesagt bedeutet Eager Load, dass die Daten einer EJB 3 Entity sofort vollständig aus der Datenbank gelesen und in die entsprechenden Attribute einer Instanz geschrieben werden. Alle anderen innerhalb der Instanz/des Objektes referenzierten persistenten Objekte (Objektnetze/Objektbäume) werden ebenfalls sofort instanziiert und vollständig geladen.

Bei größeren Objektnetzen oder Objektbäumen kann dieser Ansatz in Verbindung mit einer großen Datenmenge schnell zu langen Ladezeiten und hohem Speicherverbrauch durch eine entsprechende Anzahl an mit Daten gefüllten Objekten führen.

Die Eager Load Fetching-Strategie wird, wenn durch den Entwickler keine Fetching-Strategie angegeben oder als Fetching-Strategie explizit Eager Load angegeben worden ist, von der Persistence Provider Runtime angewendet.

EJB EJB 1.x EJB 2.x EJB 3.0

Akronym für Enterprise JavaBeans, der Bezeichnung des serverseitigen Komponentenmodells der Java EE-Plattform.

EJB 3 Entity

EJB 3.0

In EJB 3 wird der EJB-Typ zur Abbildung und Umsetzung von persistenten Entitäten als EJB 3 Entity und manchmal auch einfach als Persistent Entity bezeichnet. Letzteres ist dem Ansatz geschuldet, dass die Persistenz nicht mehr nur für Java EE, sondern auch für Java SE nutzbar sein soll.

EJB-Komponente EJB 1.x EJB 2.x EJB 3.0

Generelle Bezeichnung der Komponenten.

EJB-Typen

EJB 1.x EJB 2.x EJB 3.0

EJB stellt ab EJB 2.x drei EJB-Typen zur Verfügung:

- Session Bean (in den zwei Ausprägungen Stateful und Stateless) - Message-driven Bean - Entity Bean

Ab EJB 3 gibt es die EJB-Typen oder Ausprägungen:

- Session Bean (in den zwei Ausprägungen Stateful und Stateless) - Message-driven Bean - EJB 3 Entity oder Persistent Entity

Anzumerken ist, dass Session Bean und Message-driven Bean mit EJB 3 genereller gesprochen als Enterprise Beans bezeichnet werden und die EJB 2.x Enity Beans nun als EJB 3 Entity oder auch als Persitent Entity bezeichnet werden.

EJB QL EJB 1.x

EJB 2.x Akronym für EJB Query Language. Beschreibung siehe EJB Query Language

Entity Manager EJB 3.0

Neues Element in der Java EE bzw. Java SE, welches mit EJB 3.0 eingeführt worden ist. Hierbei handelt es sich (analog zu Ansätzen aus JDO und Hibernate) um den zentralen Persistenzmanager. Der Entity Manager ist dafür zuständig, die gesamte Persistenzabbildung von Entitäten (POJOs) zur Verfügung zu stellen. Der Entity Manager kümmert sich um das persistente Neuanlegen von Entitäten in Datenbanken, das Laden, Speichern, Löschen, Suchen, und sorgt für die konsistenten Datenzustände bei konkurrierenden Zugriffen (Concurrency Handling) auf Entitäten.

EJB-Spezifikation EJB 1.x EJB 2.x EJB 3.0

Beschreibung der Regeln, nach denen die Schnittstellen der einzelnen Komponenten bezüglich der EJB-Technologie zu entwerfen sind, damit die Modularität des Systems stets gewährleistet ist.

EJB-Kontainer EJB 1.x EJB 2.x EJB 3.0

Komponente, die den Enterprise JavaBeans eine Laufzeitumgebung zur Verfügung stellt. Die Beans laufen innerhalb eines Containers. Der EJB-Kontainer selbst ist Bestandteil des J2EE Servers und hat folgende Aufgaben:

Lebenszyklus-Management Das Objekt einer EJB-Klasse kann sich in unterschiedlichen Zuständen (Lebenszyklen) befinden. Der Container kann eine durch einen Clientaufruf instanzierte EJB passivieren und zeitweise aus dem Arbeitsspeicher entfernen, ohne es komplett zu verwerfen (löschen).

Sicherheit überwacht sämtliche Zugriffe auf die Methoden von EJBs. Falls im Deploymentdescriptor einer Bean entsprechende, sicherheitsrelevante Angaben gemacht werden, erzwingt der Container vom

Page 212: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 212 von total 218 Seiten

ObjectObjectObjectObject VersionVersionVersionVersion BeschreibungBeschreibungBeschreibungBeschreibung Client die Autorisierung vor der Ausführung der aufgerufenen Methode.

Transaktionsmanagement Clients können die Methoden von EJBs nicht ohne die Kontrolle des Containers aufrufen. Durch die Angaben im Deployment Descriptor einer EJB kennt der Container die transaktionalen Erfordernisse für jede Methode der Beans.

Verbindungsmanagement für Clients ( remote client connectivity ) Clients können die Methoden von EJBs nicht direkt aufrufen. Sie bekommen vom Container ein Remote-Object, dessen Methoden-Signatur identisch mit der Signatur der Bean-Methoden ist. Die Methodenaufrufe am Remote-Object werden unter Kontrolle des Containers an die Bean-Methoden weitergeleitet. Ausserdem importiert der Client die Stub-Klasse für das Remote Objekt. Dem Client erscheint somit das Remote-Objekt als würde es sich im gleichen Adressraum (VM) befinden.

Verbindungsmanagement für Datenbanken (database connection pooling) Das erstmalige Herstellen einer Datenbankverbindung ist, verglichen mit anderen Operationen, immer ein sehr zeitintensiver (teurer) Vorgang. Der Container übernimmt diese Aufgabe und sammelt die Verbindungen in einem Pool. Über diesen Pool stellt er die Datenbankverbindungen den EJBs zur Verfügung.

Enterprise-Anwendung EJB 1.x EJB 2.x EJB 3.0

beinhaltet EnterpriseBeans wie auch Bestandteile einer WEB-Anwendung (HTML-Dateien, Servlets, JSPs) und kann über einen J2EE-Server verteilt sein.

Enterprise JavaBean EJB 1.x EJB 2.x EJB 3.0

Komponente, welche innerhalb eines EJB-Kontainers ausgeführt wird und dabei die Business-Logik enthält oder die Daten einer Datenbank repräsentiert.

Home Interface EJB 1.x EJB 2.x

Das Home Interface einer EJB-Komponente enthält alle Methoden zur Steuerung des Le-benszyklus der EJB-Komponente. Da Clients rein technisch keine Möglichkeiten besitzen, Instanzen von EJB-Komponenten über Rechner- und/oder Prozessgrenzen hinweg erzeugen, löschen oder laden zu können, müssen sie sich dazu an das jeweilige Home Interface der gewünschten EJB-Komponente wenden. Dieses stellt die entsprechenden Funktionalitäten zur Verfügung. Durch die Verwendung vom Home Interface wird eine Entkopplung von Clients und EJB-Komponenten erreicht. Das Home Interface entspricht dem Entwurfsmuster der "Factory Method".

Konkret gibt es von einem Home Interface zwei Varianten:

Remote Home Interface für entfernte Zugriffe über Rechner- und/oder Prozessgrenzen hinweg

Local Home Interface für lokale Kommunikation durch In-Prozess-Methodenaufrufe

Interceptor EJB 3.0

Mit EJB 3.0 ist es möglich - analog CORBA-basierten Systemen, in denen Interceptor-Mechanismen seit langem bekannt sind und eingesetzt werden - Methodenaufrufe von Geschäftsmethoden abzufangen, die darin enthaltenen Parameterwerte zu untersuchen, bei Bedarf zu manipulieren und die Aufrufe weiterzuleiten oder bei Bedarf abzubrechen bzw. zu verhindern.

Mit dem Interceptor-Mechanismus hält die aspektorientierte Programmierung - zumindest in Ansätzen - Einzug in die EJB-basierte Entwicklung. Interceptors ermöglichen das transparente Einflechten von Funktionalitäten (z.B. Logging, Tracing, Zeitmessung, Sicherheitsprüfungen), die fachliche Entwickler von technischen Aspekten entkoppelt.

Der Entwickler eines Interceptors kann für eine abgefangene Methode innerhalb des aktivierten Interceptors beliebigen von ihm hinterlegten Code ausführen zu lassen.

Page 213: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 213 von total 218 Seiten

ObjectObjectObjectObject VersionVersionVersionVersion BeschreibungBeschreibungBeschreibungBeschreibung

Inversion of Control EJB 3.0

Inversion of Control (IoC) ist eine allgemeine Eigenschaft von Frameworks, wird gemeinhin gerne mit dem Satz "don't call us, we call you" umschrieben und soll ausdrücken, dass die Verantwortlichkeiten bei der Programmausführung beim Framework liegen und nicht bei den Komponenten, die auf Basis eines Frameworks entwickelt und ausgeführt werden. D.h. das die Komponenten umgebende Framework verlangt von den Komponenten, dass bestimmte Callback-Methoden durch sie implementiert werden, über die das Framework bzw. der Container zur Laufzeit Informationen in die Komponenten injiziert ober bestimmtes Verhalten (über Methodenaufrufe) auslöst.

Im Kontext von EJB 3.0 wird IoC und Dependency Injection vielfach synonym verwendet, auch wenn es im Detail sehr wohl Unterschiede gibt (siehe hierzu auch Dependency Injection). Das, was bei EJB 3.0 zum Einsatz kommt, ist eine spezialisierte Form von Inversion of Control und wird als Dependency Injection bezeichnet.

Local Home Interface EJB 2.x

Die lokale Variante des Home Interfaces ist das Local Home Interface. Es ist sozusagen die "Hochgeschwindigkeits-Variante" des Home Interfaces. Das Local Home Interface kommt ausschließlich dann zum Einsatz, wenn sich Client und zu rufende EJB-Komponente im selben EJB-Container (bzw. Prozess) befinden. Analog dem Remote Home Interface dient auch das Local Home Interface dazu, EJB-Komponenten erzeugen, löschen und ggf. laden zu lassen.

Das Local Home Interface ist "schlanker" als das Remote Home Interface, da es nicht über RMI angesprochen werden kann und keine Funktionalitäten für das Packen, Entpacken und Transferieren von Methodenaufrufen zum Transport über das Netzwerk zur Verfügung stellen muss. Die Kommunikation zwischen Client und EJB-Komponente erfolgt mittels In-Prozess-Methodenaufrufen und ist somit schneller als unter Verwendung eines Remote Home Interfaces. Das Local Home Interface ist nicht in der Lage, entfernte Methodenaufrufe zu empfangen.

<insert Grafik Local Home Interface>

Local Interface EJB 2.x

Die technische Ausprägung der Geschäftsschnittstelle (Component Interface) einer EJB-Komponente, die ausschließlich die lokale Kommunikation - die Kommunikation zwischen Client und EJB-Komponente erfolgt im selben Prozessraum - ermöglicht, wird als Local Interface bezeichnet. Wenn eine EJB-Komponente nur ein Local Interface besitzt, so ist es nicht möglich, dass ein Remote-Client auf die entfernte EJB-Komponente zugreifen kann.

Managed Object EJB 3.0 Bezeichnet eine vom Entity Manager überwachte Entity Bean bzw. Entität. Überwacht bezieht sich hierbei auf die Steuerung des Persistenzverhaltens der Entität.

Multi-Table Mapping EJB 3.0

Das Multi-table Mapping bezeichnet die Fähigkeit einer EJB 3.0 Entity Bean, auf mehrere physikalische (normalisierte) Datenbanktabellen gemappt zu werden. Diese Fähigkeit gab es in EJB 2.x - ohne expliziten Programmieraufwand - nicht. In EJB 3.0 ist eine Entity Bean kein stumpfes 1:1 Mapping einer Tabelle mehr, sondern vielmehr die technische Hülle für ein logisches Geschäftsobjekt, dessen Daten physikalisch über mehrere Tabellen verteilt sein können. Es wird innerhalb der Entity Bean über Annotationen einfach angegeben, aus welchen Tabellen/Feldern die entsprechenden Daten stammen. Der Entity Manager sorgt dafür, das relationale Modell zur Laufzeit aufzulösen und die Daten in die Entity Bean zu übertragen (siehe Abbildung).

Page 214: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 214 von total 218 Seiten

ObjectObjectObjectObject VersionVersionVersionVersion BeschreibungBeschreibungBeschreibungBeschreibung

Logisches Geschäftsobjekt (Entity Bean), bestehend aus drei Tabellen

@Entity @Table(name = "KUNDE") @SecondaryTables({ @SecondaryTable(name = "ADRESSE") @SecondaryTable(name = "TYP") }) public class Kunde implements java.io.Serializable { private int id; private String name; // Aus Tabelle "KUNDE" private String vorname ; // Aus Tabelle "KUNDE" private String strasse; // Aus Sekundärtabelle "ADRESSE" ... // Attribut aus der Haupttabelle "Kunde" @Column(name = "NAME") public String getName() { return name; } ... // Attribut aus der Sekundärtabelle "ADRESSE" @Column(name = "STRASSE", secondaryTable = "ADRESSE") public String getStrasse() { return strasse; } ... // Per Default wird, wenn kein @Column angeben ist, // davon ausgegangen, dass der Spaltenname gleich dem // Attributnamen ist. public String getVorname() { return vorname ; } }

Plain Old Java Interface EJB 3.0

Der Begriff taucht verstärkt seit 2004 in Fachzeitschriften und eZines im Java-Bereich auf. Mit Plain Old Java Interface bzw. POJI wird ein normales - nicht durch technischen oder infrastrukturellen Code verschmutztes - Java Interface bezeichnet.

Im Kontext von EJB 3.0 wird der Begriff Plain Old Java Interface bzw. POJI nun auch angewandt. Eine Kernidee von EJB 3.0 ist, dass die EJB-Komponenten aus Sicht des Entwicklers - in ihrer Nutzung und in ihrer Mikroarchitektur so weit vereinfacht werden, dass Component Interfaces (also die Geschäftsschnittstellen)

Plain Old Java Object EJB 3.0

Der Begriff taucht verstärkt seit 2004 in Fachzeitschriften und im Java-Bereich auf. Mit Plain Old Java Object wird eine normale, einfache Java-Klasse (na ja, vielleicht sollte POJO dann lieber POJC heissen ;-) bezeichnet, die nicht durch infrastrukturellen Code, technische Code etc. "verschmutzt" ist, wie dies beispielsweise bei komplexeren Komponenten vorkommt.

Im Kontext von EJB 3.0 wird der Begriff Plain Old Java Object bzw. POJO nun auch angewandt. Eine Kernidee von EJB 3.0 ist, dass die EJB-Komponenten - aus Sicht des Entwicklers - in ihrer Nutzung und in ihrer Mikroarchitektur so weit vereinfacht werden, dass die Bean-Klassen (die Implementierungs-Klassen der EJB-Komponenten) von ihrem Typ her - im Vergleich zu EJB-Vorgängerversionen - als POJOs bezeichnet werden können.

POJO EJB 3.0 Akronym für Plain Old Java Object

POJI EJB 3.0 Akronym für Plain Old Java Interface

Remote Home Interface EJB 1.x EJB 2.x

Das Remote Home Interface ermöglicht es entfernten Clients, über das Netzwerk Anfragen zum Erzeugen, Laden und Löschen von Instanzen zu stellen. Clients kommunizieren mit einem Remote Home Interface über entfernte Methodenaufrufe, die über das RMI/IIOP-Protokoll transferiert werden. Diese Art der Kommunikation ist langsamer als die Kommunikation mittels In-Prozess-Methodenaufrufe innerhalb eines Prozesses. Die Verwendung dieser Ausprägung des Home Interfaces ist notwendig, wenn man Clients, die sich in einem verteilten System auf einem beliebigen Rechner in einem Netzwerk befinden können, eine EJB-Komponente offerieren möchte.

<insert Grafik Remote Home Interface>

Remote Interface EJB 1.x EJB 2.x

Die technische Ausprägung der Geschäftsschnittstelle (Component Interface) einer EJB-Komponente, welche die Remote-Kommunikation (also entfernte Kommunikation) ermöglicht, wird als Remote Interface bezeichnet. Wenn eine EJB-Komponente ein Remote Interface besitzt, ist es Clients in anderen

Page 215: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Lösungen zu Übungen aus dem Skript Seite 215 von total 218 Seiten

ObjectObjectObjectObject VersionVersionVersionVersion BeschreibungBeschreibungBeschreibungBeschreibung Prozessräumen möglich über das Netzwerk und Rechner- und Prozessgrenzen hinweg auf eben diese EJB-Komponete zuzugreifen. Die Kommunikation erfolgt dabei über RMI/IIOP.

Selbst wenn sich Client und EJB-Komponente im selben Prozessraum befinden (z.B. ist der Client auch eine EJB-Komponente, die eine andere EJB-Komponente verwendet), und der Client die EJB-Komponente über ihr Remote Interface anspricht, so erfolgt die Kommunikation für gewöhnlich über RMI/IIOP, was in diesem Fall eine unnötige Verlangsamung des Zugriffs wäre, der durch zur Verfügungstellen einer lokalen Geschäftsschnittstelle (Local Interface) sehr einfach behoben werden kann und zu Performanzsteigerungen führt.

Page 216: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Quellenangaben Seite 216 von total 218 Seiten

HHHH ReferenzenReferenzenReferenzenReferenzen

30303030 Quellenangaben Quellenangaben Quellenangaben Quellenangaben

Die Liste der Quellenangaben stellt ein Ausschnitt der vorhandenen Literatur und Onlinequellen dar. Bei der Beschaffung von weiterführenden Informationen ist auf die Kompatibilität zu der verwendeten AS Version und zur EJB Technologie zu achten.

30.1 Bücher

J2EE, Einstieg für AnspruchsvolleJ2EE, Einstieg für AnspruchsvolleJ2EE, Einstieg für AnspruchsvolleJ2EE, Einstieg für Anspruchsvolle

Thomas Stark

Addison-Wesley

ISBN 3-8273-2184-0

Core J2EE PatCore J2EE PatCore J2EE PatCore J2EE Patterns, Best Practices and Design Strategiesterns, Best Practices and Design Strategiesterns, Best Practices and Design Strategiesterns, Best Practices and Design Strategies

Deepak Alur, Joh Crupi, Dan Malks

Pearson Professional Education

ISBN 0-13-142246-4

J2EE Patterns, Entwurfsmuster für die J2EEJ2EE Patterns, Entwurfsmuster für die J2EEJ2EE Patterns, Entwurfsmuster für die J2EEJ2EE Patterns, Entwurfsmuster für die J2EE

Adam Bien

Addison-Wesley

ISBN 3-8273-2124-7

Entwurfsmuster, Elemente wiederverwendbarEntwurfsmuster, Elemente wiederverwendbarEntwurfsmuster, Elemente wiederverwendbarEntwurfsmuster, Elemente wiederverwendbarer objektorientierter Softwareer objektorientierter Softwareer objektorientierter Softwareer objektorientierter Software

Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides

Addison-Wesley

ISBN 3-8273-1862-9

Mastering Enterprise JavaBeansMastering Enterprise JavaBeansMastering Enterprise JavaBeansMastering Enterprise JavaBeans

Ed Roman, Rima Patel Sriganesh, Gerald Brose

Wiley

ISBN 0-7645-7682-8

Enterprise Java SecurityEnterprise Java SecurityEnterprise Java SecurityEnterprise Java Security

Marco Pistoia, Nataraj Nagaratnam, Larry Koved, Anthony Nadalin

Addison-Wesley

ISBN 9-780321-118899

Page 217: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Quellenangaben Seite 217 von total 218 Seiten

J2EE SecurityJ2EE SecurityJ2EE SecurityJ2EE Security

Pankaj Kumar

Addison-Wesley

ISBN 0-13-140264-1

30.2 Online Quellen

SUNSUNSUNSUN

The J2EE™ 1.4 Tutorial

For Sun Java System Application Server Platform Edition 8.1 2005Q2 UR2

http://java.sun.com/j2ee/1.4/docs/tutorial/doc/index.html

The J2EE™ 1.4 Tutorial is a guide to developing enterprise applications for the Java 2 Platform, Enterprise Edition (J2EE) version 1.4

weitereweitereweitereweitere

http://developers.sun.com

http://www.j2ee-develop.de

http://forum.java.sun.com

http://www.galileocomputing.de/openbook/java2

http://www.unix.org.ua/orelly/java-ent

http://www.jeckle.de

http://www.ejbkomplett.net

http://www.theserverside.com/tt/books/wiley/masteringEJB3/index.tss

http://www-306.ibm.com/software/websphere

http://www.pc-ware.de/de/PC-Ware/ssl/oracle/appl_server.htm

TechnologienTechnologienTechnologienTechnologien

http://ch.sun.com

http://www.jboss.com

http://tomcat.apache.org

http://ant.apache.org

http://www.mysql.de

Page 218: › j2ee › j2ee.pdf · J2EE – EJB 2.x © 2008 Stephan Metzler Version 3.0 Seite 2 von total 218 Seiten Prolog Dieses Skript vermittelt die Theorie von Enterprise JavaBeans als

J2EE – EJB 2.x

© 2008 Stephan Metzler Version 3.0 Installierte Software Seite 218 von total 218 Seiten

31313131 Installierte SoftwareInstallierte SoftwareInstallierte SoftwareInstallierte Software

Die für die Ausführung der Beispiele verwendeten Softwareversionen sind:

Java SDKJava SDKJava SDKJava SDK

- jdk-1_5_0_07-windows-i586-p

Java EEJava EEJava EEJava EE

- j2eesdk-1_4_03-windows

Applikation ServerApplikation ServerApplikation ServerApplikation Server

- j2eesdk-1_4_03-windows

- jboss-4.0.4.GA

WebWebWebWeb Server Server Server Server

- apache-tomcat-5.5.17

mySQLmySQLmySQLmySQL

- mysql-noinstall-5.0.24-win32

- mysql-gui-tools-noinstall-5.0-r2-win32

- mysql-connector-java-5.0.3

EntwicklungsumgebungEntwicklungsumgebungEntwicklungsumgebungEntwicklungsumgebung

- eclipse-SDK-3.2-win32

- plugin : Quantum_2.4.5_for_Eclipse_3

- plugin : xmlbuddy_2.0.72

- plugin: tomcatPluginV31