e Inklusiv ng in Einführu JPA 2.0 werner EBERLING jan LESSNER ENTERPRISE JavaBeans 3.1 DAS EJB-PRAXISBUCH FÜR EIN- UND UMSTEIGER 2. Auflage Inhalt Einführung ........................................................................................................................... 1 Bevor es losgeht ...................................................................................................................................1 Zielgruppe und Leseregeln ...................................................................................................................2 Application-Server, Tools und Codebeispiele ......................................................................................3 Formatierungen und Sprachgebrauch ...................................................................................................4 Danksagung ..........................................................................................................................................5 Feedback...............................................................................................................................................5 1 1.1 1.2 1.3 1.4 1.5 Technische Grundlagen und historische Entwicklungen .................................... 7 Client-Server-Systeme .............................................................................................................7 Die 3-Schichten-Architektur ..................................................................................................10 Ein bisschen Komponenten-Theorie ......................................................................................13 EJBs und die Java Enterprise Edition.....................................................................................16 Handwerkszeug aus der Java Standard Edition 5 ...................................................................18 1.5.1 Annotationen ............................................................................................................18 1.5.2 Generics....................................................................................................................19 1.5.3 Autoboxing...............................................................................................................20 2 2.1 2.2 Erste Schritte.......................................................................................................... 21 Die Neuheiten kurz gefasst ....................................................................................................21 Hello World ...........................................................................................................................24 2.2.1 Installation der JEE-Plattform ..................................................................................24 2.2.2 Implementierung einer EJB ......................................................................................25 2.2.3 Installation der EJB (Deployment) ...........................................................................26 2.2.4 Implementierung des Clients ....................................................................................28 2.2.5 Aufräumen................................................................................................................31 Spielregeln .............................................................................................................................32 2.3.1 Rollen .......................................................................................................................32 2.3.2 Einschränkungen im Programmiermodell ................................................................33 Wie es weitergeht...................................................................................................................36 2.3 2.4 VII Inhalt 3 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 4 4.1 4.2 4.3 4.4 4.5 4.6 VIII SessionBeans ........................................................................................................ 37 Einführung ............................................................................................................................. 37 Stateless SessionBeans........................................................................................................... 39 3.2.1 Bestandteile einer Stateless SessionBean ................................................................. 41 3.2.2 Implementierung im Detail ...................................................................................... 44 3.2.3 Lokaler Zugriff auf Stateless SessionBeans ............................................................. 50 3.2.4 Stateless SessionBeans als Webservice-Endpunkt ................................................... 54 3.2.5 Asynchrone Bean-Methoden.................................................................................... 58 3.2.6 Neue Beans und alte Clients – EJB2-Sicht auf EJB3-SessionBeans ........................ 60 Stateful SessionBeans ............................................................................................................ 61 3.3.1 Bestandteile einer Stateful SessionBean................................................................... 63 3.3.2 Lifecycle und Event-Callback-Methoden................................................................. 65 3.3.3 Abschließende Bemerkungen................................................................................... 69 Singleton SessionBeans ......................................................................................................... 69 3.4.1 Bestandteile einer Singleton SessionBean................................................................ 70 3.4.2 Steuerung des parallelen Zugriffs............................................................................. 72 Paralleler Zugriff auf SessionBeans....................................................................................... 76 Session-Context ..................................................................................................................... 77 Exceptions.............................................................................................................................. 79 3.7.1 Applikations- und System-Exception....................................................................... 79 Alternative zur Annotation: Der XML-Deskriptor................................................................. 81 Entities.................................................................................................................... 85 Das Problem mit der Persistenz ............................................................................................. 85 Einige Grundlagen ................................................................................................................. 87 4.2.1 Die Data-Source ....................................................................................................... 87 4.2.2 Die wichtigsten Begriffe vorweg.............................................................................. 89 Eine erste Datenbankanwendung ........................................................................................... 94 4.3.1 Der Lebenszyklus von Entities................................................................................. 98 4.3.2 Grundfunktionen des Entity-Managers .................................................................. 102 O/R-Mapping ....................................................................................................................... 104 4.4.1 Abbildung von Klassen auf Tabellen ..................................................................... 104 4.4.2 Abbildung von Attributen auf Spalten.................................................................... 108 4.4.3 Abbildung von Vererbungen .................................................................................. 123 4.4.4 Steuerung des Persistence-Providers ...................................................................... 131 Beziehungen ........................................................................................................................ 134 4.5.1 Bi- und unidirektionale Beziehungen verstehen..................................................... 134 4.5.2 Beziehungstypen .................................................................................................... 136 4.5.3 1:1-Beziehungen .................................................................................................... 137 4.5.4 1:N-Beziehungen.................................................................................................... 141 4.5.5 N:1-Beziehungen.................................................................................................... 147 4.5.6 N:M-Beziehungen .................................................................................................. 149 4.5.7 Noch mehr Beziehungen ........................................................................................ 152 Validierung .......................................................................................................................... 155 4.6.1 Validierte Entities in 5 Minuten ............................................................................. 155 4.6.2 Bean Validation und die persistence.xml ............................................................... 156 Inhalt 4.7 4.8 4.9 4.10 5 5.1 5.2 5.3 5.4 5.5 6 6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8 7 7.1 7.2 4.6.3 APIs verheiraten .....................................................................................................158 Abfragen ..............................................................................................................................159 4.7.1 JPA-Schnittstellen für Abfragen.............................................................................162 4.7.2 Alles Wesentliche auf einen Blick..........................................................................163 4.7.3 GROUP-BY und HAVING ....................................................................................170 4.7.4 SELECT .................................................................................................................171 4.7.5 ORDER-BY ...........................................................................................................172 4.7.6 Unterabfragen.........................................................................................................172 4.7.7 Massenlöschungen und -aktualisierungen ..............................................................173 4.7.8 SQL-Abfragen ........................................................................................................174 4.7.9 Benannte Abfragen.................................................................................................176 4.7.10 Einfach typisierte Abfragen....................................................................................177 Das Criteria-API ..................................................................................................................177 4.8.1 Das Metamodell .....................................................................................................179 Noch mehr Entities...............................................................................................................183 Entities im Rückblick...........................................................................................................185 Message-Driven Beans........................................................................................ 187 Einführung ...........................................................................................................................187 Nachrichtenbasierte Systeme mit JMS.................................................................................188 5.2.1 Der Nachrichtenserver als Kommunikationsbus.....................................................189 5.2.2 Einer sendet, einer empfängt – das Punkt-zu-Punkt-Modell...................................189 5.2.3 Einer sendet, viele hören zu – das Publish-Subscribe-Modell ................................194 Bestandteile einer Message-Driven Bean.............................................................................196 5.3.1 Lebenszyklus einer Message-Driven Bean.............................................................196 5.3.2 Bestandteile einer Message-Driven Bean ...............................................................197 Alternative zur Annotation: Der XML-Deskriptor...............................................................200 Abschließende Bemerkungen...............................................................................................201 EJB-Konfiguration ............................................................................................... 203 Einführung ...........................................................................................................................203 Der lokale JNDI-Kontext .....................................................................................................203 6.2.1 Dependency-Lookup ..............................................................................................205 6.2.2 Dependency Injection.............................................................................................205 EJB-Referenzen ...................................................................................................................206 Konfigurations-Parameter ....................................................................................................210 Ressourcen-Manager-Fabriken ............................................................................................211 Nachrichtenziele...................................................................................................................214 Noch mehr referenzierte Objekte .........................................................................................216 Abschließende Bemerkungen zum Deployment-Deskriptor ................................................217 Transaktionen ...................................................................................................... 221 Systemkonsistenz in Komponentenarchitekturen.................................................................221 7.1.1 Ressourcen .............................................................................................................223 Container-verwaltete Transaktionen ....................................................................................226 7.2.1 Zurückrollen von CMTs .........................................................................................227 IX Inhalt 7.3 7.4 7.5 8 8.1 8.2 8.3 8.4 9 9.1 9.2 9.3 9.4 10 10.1 10.2 X 7.2.2 Deklaration von CMTs........................................................................................... 230 7.2.3 CMTs in Message-Driven Beans............................................................................ 234 7.2.4 Situationen mit unspezifiziertem Transaktionskontext........................................... 234 Bean-verwaltete Transaktionen............................................................................................ 235 Transaktionale Ressourcen .................................................................................................. 238 7.4.1 Persistenzkontexte.................................................................................................. 238 7.4.2 Data-Sources .......................................................................................................... 238 7.4.3 JMS-Verbindungen ................................................................................................ 240 7.4.4 Stateful SessionBeans und SessionSynchronization............................................... 241 Client-verwaltete Transaktionen .......................................................................................... 244 Sicherheit ............................................................................................................. 247 Einführung ........................................................................................................................... 247 Wer klopft denn da? – Die Authentifizierung ...................................................................... 247 8.2.1 Erste Schritte .......................................................................................................... 247 8.2.2 Der Caller-Principal ............................................................................................... 249 8.2.3 Principal Delegation............................................................................................... 249 8.2.4 Technische Details der Authentifizierung des Clients............................................ 250 8.2.5 Serverseitige Authentifizierung.............................................................................. 256 Rollenbasierte Autorisierung ............................................................................................... 260 8.3.1 Deklaratives Sicherheitsmanagement..................................................................... 261 8.3.2 Programmatisches Sicherheitsmanagement............................................................ 263 8.3.3 Abbildung der logischen Rollen............................................................................. 264 8.3.4 Grenzen des rollenbasierten Ansatzes .................................................................... 265 Datenverschlüsselung und Integrität .................................................................................... 265 Noch mehr EJBs .................................................................................................. 269 Timed Objects...................................................................................................................... 269 Einfache Aspektorientierung mit EJB3................................................................................ 274 9.2.1 Interceptor-Methoden............................................................................................. 275 9.2.2 Interceptor-Klassen ................................................................................................ 278 9.2.3 Interceptoren für Timer-Methoden......................................................................... 282 9.2.4 Aspekte über XML-Deskriptoren........................................................................... 282 Ein alternativer Weg zur Remote-Referenz: Der Handle ..................................................... 284 EJBs ohne Application-Server betreiben ............................................................................. 285 Blick über den Tellerrand.................................................................................... 287 Testen von EJBs................................................................................................................... 287 10.1.1 Warum Testen? ...................................................................................................... 287 10.1.2 Unit-Tests mit Entities und Dependency-Injection ................................................ 289 10.1.3 EJB lite als Test-Umgebung................................................................................... 290 10.1.4 Weitere Test-Alternativen ...................................................................................... 291 Wichtige EJB-Entwurfmuster .............................................................................................. 292 10.2.1 Evtl. bekannte Muster sind weiter gültig................................................................ 292 10.2.2 Neue Muster mit EJB 3.0 ....................................................................................... 295 10.2.3 Was es nicht mehr gibt ........................................................................................... 296 Inhalt 10.3 Migration auf EJB3 ..............................................................................................................297 10.3.1 Drei (und eine) Migrations-Strategien....................................................................298 10.3.2 Migrieren, aber wie?...............................................................................................300 11 11.1 11.2 11.3 EinStein würfelt nicht .......................................................................................... 305 Zum Spiel.............................................................................................................................305 Funktionsweise der Spielplattform.......................................................................................307 Technisches Modell .............................................................................................................308 11.3.1 Versuchungen.........................................................................................................308 11.3.2 Design-Entscheidungen..........................................................................................309 11.3.3 Das Komponentenmodell .......................................................................................311 11.3.4 Das Entitätenmodell ...............................................................................................312 11.3.5 Die Package-Struktur..............................................................................................313 Hingucker.............................................................................................................................314 Erweiterungsmöglichkeiten..................................................................................................317 Einige Anmerkungen zum Schluss.......................................................................................318 11.4 11.5 11.6 12 12.1 12.2 12.3 12.4 Kochrezepte ......................................................................................................... 321 Ein einfacher lokaler Read-Only-Cache...............................................................................322 Getaktete Datenquelle ..........................................................................................................323 Vereinfachtes EJB Deployment ...........................................................................................325 EJB und JSF.........................................................................................................................326 12.4.1 ManagedBeans als EJB-Client ...............................................................................326 12.4.2 SessionBeans als ManagedBeans ...........................................................................327 12.5 Fehler aus Webservices melden ...........................................................................................329 12.6 Stateless SessionBean als RESTful Webservice ..................................................................331 12.7 Dateiexport...........................................................................................................................333 12.8 Eine Basis-Entität.................................................................................................................336 12.9 Suchfunktion ........................................................................................................................339 12.10 Bitte umblättern....................................................................................................................343 12.10.1 Variante 1 – Alles dem Client überlassen...............................................................343 12.10.2 Variante 2 – Verwaltung im Application-Server ....................................................343 12.10.3 Variante 3 – Verwaltung in der Datenbank ............................................................345 12.10.4 Noch eine Variante aus dem Internet......................................................................347 12.11 Lokale Tests mit OpenEJB...................................................................................................348 12.11.1 SessionBeans testen................................................................................................348 12.11.2 JPA-Tests ...............................................................................................................349 Literatur............................................................................................................................ 353 Register............................................................................................................................ 355 XI 1.1 Client-Server-Systeme 1 1 Technische Grundlagen und historische Entwicklungen 1.1 Client-Server-Systeme Will man es ganz kurz machen, dann dienen Enterprise JavaBeans (EJBs) als zentraler Bestandteil der so genannten Java Enterprise Edition (JEE) einzig und allein dazu, verteilte Client-Server-Systeme auf der Basis von Java zu bauen. Somit stellt sich eine wichtige Frage, bevor es richtig losgeht: Warum bauen wir überhaupt Client-Server-Systeme? Den Leidgeplagten unter den langjährigen EJB-Nutzern liegt außerdem die zynische Bemerkung auf der Zunge: „Warum ausgerechnet mit EJBs?“ Obwohl wir hier von einem Praxisbuch sprechen, sind einige philosophische Grundgedanken nach dem „Woher“ und „Wohin“ sehr hilfreich, um zu verstehen, warum manche Dinge in der Java-EnterpriseWelt so sind, wie sie sind. Der ganz ungeduldige Leser darf natürlich gerne erst einmal alles ausprobieren und danach wieder hierhin zurückkehren. Von einem „verteilten System“ sprechen wir immer dann, wenn sich die Gesamtheit einer Applikation nicht in einem einzelnen Programm manifestiert, wie z.B. in einer einfachen Textverarbeitung, sondern sich auf verschiedene, gleichzeitig aktive, interagierende Programme verteilt. Client-Server-Systeme sind eine weit verbreitete, spezielle Form verteilter Systeme, in denen ein agierendes (Client) mit einer Reihe reagierender Programme (Server) in Verbindung steht und die Initiative immer vom Client ausgeht. Diese Form hat sich bewährt, weil sie viel leichter zu verstehen ist als etwa ein System kooperierender Server, in dem alle kreuz und quer durcheinanderreden, obwohl dies die Wirklichkeit vielleicht viel besser abbilden würde. Außerdem ist es eine gut beherrschbare Grundlage für die Kommunikation im latent unsicheren Internet, und um nicht zu viele verschiedene Architekturen lernen zu müssen, hat das Internet-fähige Konzept auch Einzug in die meisten anderen Netzwelten gefunden. Es gibt sehr unterschiedliche Gründe für den Bau einer Client-Server-Architektur, z.B. den Wunsch nach weitgehender Unabhängigkeit der ein- 7 1 Technische Grundlagen und historische Entwicklungen zelnen Programme und ihrer Daten in Bezug auf Programmiersprache, Verfügbarkeit, Installationsort, Sicherheitsregeln usw. In Kapitel 1.2 werfen wir einen Blick auf die historische Entwicklung des Konzepts. Heutzutage ist die bekannteste Art der Client-ServerKommunikation sicherlich das World Wide Web, wo Browser verschiedener Hersteller die Daten von Webservern beliebiger anderer Hersteller abfragen und zur Anzeige bringen. Webbrowser Webbrowser HTTP HTTP Internet Webserver File-I/O Dateisystem HTML HTML HTML Abbildung 1.1 Client-Server-Kommunikation im World Wide Web In jedem Falle gibt es aber immer einen Hauptgrund gegen einen verteilten Ansatz, nämlich die damit verbundene technische Kompliziertheit. Befindet man sich allerdings in der Situation, auf eine verteilte Architektur nicht verzichten zu können, wollen die diesbezüglichen Probleme natürlich adäquat gelöst sein. Die EJB-Spezifikation stellt nun nichts anderes dar als ein Modell standardisierter Lösungen für wiederkehrende Herausforderungen in diesem Zusammenhang. „Modell“ klingt dabei erst einmal unangenehm theoretisch für jemanden, der schnell in die Vollen gehen will. Tatsächlich ist die Java Enterprise Edition im Gegensatz zur Java Standard Edition nicht irgendetwas, das man sich bei Sun kostenlos von der Website herunterlädt, um draufloszuprogrammieren. Hier spricht man mit anderen Anbietern, die sich ihre Arbeit meist mit richtig viel Geld bezahlen lassen. Gottlob gibt es inzwischen auch hier Open-Source-Angebote, von denen wir in diesem Buch Gebrauch machen. Verwunderlich ist das Preisniveau im JEE-Bereich nicht, führt man sich vor Augen, was es alles zu berücksichtigen gilt, wenn man verteilte Systeme programmiert. Unmittelbar evident ist die Notwendigkeit einer Interprozesskommunikation, wofür es schon deutlich vor dem Aufkommen der EJB-Spezifikation Lösungen gab. Wie wir sehen werden, erfindet der Standard hier auch nichts Neues, sondern bezieht vorhandene Technologien mit ein. Auf den zweiten Blick fallen dann schon etwas subtilere Herausforderungen auf, z.B. die Frage, wie sich ein konsistenter Systemzustand sicherstellen lässt, auch wenn eines der vielen Programme mitten in der Arbeit auf Grund eines unvorhergesehenen Fehlers den Dienst verweigert. Hier wird ein verteiltes Transaktions-Management benötigt, und der 8 1.1 Client-Server-Systeme Kenner der Materie weiß das Schlagwort „2-Phase-Commit“ zu nennen. Das Konzept dahinter ist schnell erklärt und leicht nachvollziehbar (wir kommen in Kapitel 7 darauf zu sprechen), aber die Implementierung eines entsprechenden Transaktionsmonitors stellt sich in der Praxis als ziemlich kompliziert dar. Der EJB-Standard definiert daher ein Modell, das es erlaubt, diese Aspekte von der Implementierung der Programme fernzuhalten, so dass sich nur die Hersteller der JEE-Frameworks damit herumschlagen müssen und nicht die EJB-Entwickler. Auf den dritten Blick kommen noch weitere Dinge hinzu, wie z.B. der Wunsch nach vernünftiger Testbarkeit der Applikation und nach Wiederverwendung von Komponenten. Für viele dieser Fragestellungen hat die EJB-Spezifikation eine Lösung parat, die gegenüber vielen vorher existierenden Insellösungen auch den Vorteil der Standardisierung mit sich bringt. Entwickler, die in einem Projekt gelernt haben, basierend auf der Java Enterprise Edition ein verteiltes System zu entwickeln, können ihr Wissen in völlig anderen Projekten weiter nutzen. Die Versionen 1.x und 2.x des EJB-Standards zielten vor allem darauf ab, die dringlichsten der oben erwähnten Probleme überhaupt irgendwie in den Griff zu bekommen. Die Entwicklung stabiler, verteilter Systeme war ohnehin eine unheimlich teure Angelegenheit, da konnte es mit einem Standard eigentlich nur besser werden. Das war eine gewisse Zeit lang auch ausreichend, und für die meisten Unzulänglichkeiten des Standards ließen sich mit etwas Gehirnschmalz verträgliche Workarounds schaffen. Nichtsdestotrotz ist ein Standard mit Macken – sowohl konzeptionell als auch von der Handhabung her – auf Dauer unbefriedigend. Ein wesentlicher Druckfaktor bei der Weiterentwicklung der Spezifikation waren die Einflüsse namhafter Open-Source-Projekte, die sich ihres besseren Komforts und der geringen Kosten wegen trotz fehlender Standardisierung in jenen Bereichen durchsetzen, wo die EJB-Spezifikation lückenhaft oder sperrig in der Anwendung war. Im Bereich Persistenz-Management waren die Open-Source-Toolkits [HIBERNATE] und [OJB] sowie der konkurrierende Standard [JDO] federführend. Darin besteht dementsprechend eine der fundamentalen Neuerungen bei EJB 3. Bezüglich Konfiguration, Test und Wiederverwendung von Komponenten hat sich das Framework [SPRING] hervorgetan, sowie in Teilen das Toolkit [XDOCLET]. Diesen Entwicklungen hat der Standard augenscheinlich und maßgeblich die deutliche Steigerung im Entwicklerkomfort in der Version 3 zu verdanken. Tatsächlich lässt sich guten Gewissens behaupten, dass die Entwicklung skalierbarer Client-Server-Systeme auf Basis des EJB-Standards nicht mehr nur möglich ist, sondern auch richtig Spaß macht, weil sie so einfach geworden ist. Natürlich gibt es trotzdem einige kleine, aber feine Fußangeln. Und was wäre ein anständiges EJB-Buch, würde es diese Fallstricke nicht aufzeigen ... 9 1 Technische Grundlagen und historische Entwicklungen 1.2 Die 3-Schichten-Architektur Betrachten man genauer den Wirkungsbereich von Enterprise JavaBeans, dann taucht in der Literatur eine spezielle Form der Client-Server-Systeme auf, und zwar die so genannte „3-Schichten-Architektur“ (englisch: 3 Tier Architecture). Interprozesskommunikation Präsentation (z.B. Webbrowser oder GUI) Interprozesskommunikation Geschäftslogik Persistenz (z.B. SQL-DB) Abbildung 1.2 Drei-Schichten-Architektur Wie in Abbildung 1.2 zu sehen ist, wird hier eine physische Gliederung des Systems in 3 Schichten vorgenommen, die in unterschiedlichen Prozessen implementiert sind – eine Präsentationsebene, eine Persistenzebene und, dazwischen eingebettet, eine zentrale Geschäftslogik. Der EJB-Standard deckt die mittlere Schicht dieser Architektur ab und beinhaltet auch die Verfahren, wie EJBs von der Präsentationsebene aus angesprochen werden können und wie die Persistenzebene zu integrieren ist. Um zu verstehen, wofür die 3-Schichten-Architektur gut ist, werfen wir am besten einen Blick auf die historische Entwicklung. Am Anfang stand die Idee, eine zentrale Datenbasis für weit verstreut sitzende Interessenten nutzbar zu machen, ohne die Daten duplizieren zu müssen. Die Vervielfältigung von Daten ist nämlich teuer und hat den unangenehmen Beigeschmack, dass die dezentralen Daten zu rasch ihre Aktualität verlieren. Man kann sich dies sehr gut an einem Wörterbuch klarmachen. Ein gedrucktes Deutsch-Englisch-Wörterbuch hat zwar den Charme, jederzeit greifbar zu sein und ohne Strom zu funktionieren, aber es entwickelt sich nicht weiter und ist folglich nach kurzer Zeit nicht mehr aktuell. Ein altes Langenscheidt-Wörterbuch weiß noch nichts von der Rechtschreibreform, und neue Begriffe wie „Flachbildschirm“ und „Mehrwertdienst“ kennt es natürlich nicht. Viel besser ist es da um ein Online-Wörterbuch bestellt, z.B. http://dict.leo.org, mit dem der Anwender auf eine permanent gepflegte, zentrale Datenbasis zugreifen kann und so immer auf dem neuesten Stand ist. Nur mit Strom und Internet, versteht sich. So weit so gut, das hätte zur Not auch mit einem freigegebenen Netzlaufwerk und einer Volltextsuche auf Übersetzungsdateien bewerkstelligt werden können – nicht schön natürlich, aber irgendwie machbar, wobei sich das Angebot auf die Rohdaten beschränken würde und nicht die praktischen Abfragefunktionen mit sich brächte. Richtig abenteuerlich würde es schließlich, wenn die Anwender auch noch manipulierenden Zugriff auf die Daten bekommen sollen – und zwar kontrolliert und mit einer sauberen Auflösung von Zugriffskonflikten. Hier sind 10 1.2 Die 3-Schichten-Architektur die Möglichkeiten eines Dateisystems oder auch anderer Massenspeicher erschöpft. Es muss also eine zusätzliche steuernde Instanz ins Spiel gebracht werden, und die erste Antwort auf diese Anforderung waren Datenbanken, oder besser gesagt: Datenbankserver. Diese Serverprozesse regeln nun an zentraler Stelle, wer welche Daten sehen und ändern darf und wie mit Situationen umgegangen werden soll, in denen zwei Benutzer gleichzeitig dieselben Daten bearbeiten wollen. Hier werden also nicht mehr nur Daten, sondern Dienste auf Daten angeboten, daher der Begriff „Service“ und „Server“. Der Client kann große Teile seiner Funktionalität an den Server abgeben und sich vornehmlich auf Visualisierungsaspekte konzentrieren. Damit war die 2-Schichten-Architektur geboren, und es etablierte sich schon relativ bald ein Standard für Datenbanken: SQL. Client-Anwendungen Interprozesskommunikation zentraler Datenbankserver Abbildung 1.3 Zwei-Schichten-Architektur Dieser Standard stellte sich als eine derart praktische Datenzugriffssprache heraus, dass sie bis heute aus dem Enterprise Computing nicht wegzudenken ist. Wir haben da so unsere Theorien, worauf die Langlebigkeit dieses über 30 Jahre alten Konzepts fußt, doch ist das Thema wohl eher etwas für die Kaffeeküche als für ein EJB-Buch. Nun ist SQL zwar eine Sprache, aber wie der Name „Structured Query Language“ schon sagt, war sie als Abfragesprache und nicht als Programmiersprache gedacht.1 Folglich stößt eine mit SQL formulierbare Programmlogik sehr schnell an ihre Grenzen, so dass sich (neben anderen Problemen) in der 2-Schichten-Architektur ein Dilemma auftat. Entweder wird die Logik einer Anwendung zentral gehalten und beschränkt sich auf die rudimentären Programmiermittel der Datenbanken, oder sie verbleibt im Client und muss ggf. ständig neu programmiert und verteilt werden, will man z.B. neue Betriebssysteme erschließen oder erweiterte Funktionen anbieten. Beide Wege erwiesen sich auf Dauer als unattraktiv und führten in der Folge zur Idee der 3-Schichten-Architektur. Neben der reinen Datenhaltung auf der Basis von SQL wird hier eine weitere Server-Ebene, die ebenfalls nur an zentraler Stelle installierte „Geschäftslogik“, unterschieden, die sich aber höherer, moderner Programmiersprachen bedient und dadurch mächtiger und besser wartbar ist. 1 Wenn man es ganz genau nehmen will, geht der Name SQL auf einen Vorläufer SEQUEL von IBM aus den frühen 70ern zurück, der für Structured English Query Language steht. Nicht, dass das hier wichtig wäre, aber man kann prima damit angeben, wenn man so etwas weiß. 11 1 Technische Grundlagen und historische Entwicklungen Clients können weiterhin und sogar noch stärker auf den Bereich der Präsentation reduziert werden, während die beschränkten Fähigkeiten der Datenbank-Ebene von der Geschäftslogik gekapselt und angereichert werden, um höherwertige Dienste anzubieten. Damit steht die Geschäftslogik natürlich erneut vor einigen Problemen, die von Datenbankanbietern schon einmal gelöst wurden. Hier hätten in der Vergangenheit sicher einige Räder weniger neu erfunden werden müssen, wenn sich die Programmierbarkeit und Kombinierbarkeit von Datenbanken schneller entwickelt hätte. Aber so ist es nun einmal nicht gelaufen, und deshalb haben sich andere kluge Leute Gedanken darüber gemacht, wie eine geeignete Infrastruktur für die Programmierung einer transaktionssicheren und mehrbenutzerfähigen Geschäftslogik aussehen könnte. Im Java-Umfeld lautet die Antwort: „Enterprise JavaBeans“ als ursprünglich kleinster gemeinsamer Nenner bewährter Muster für den Bau der mittleren Ebene von 3-Schichten-Architekturen. Dieser Nenner war leider zu Beginn wirklich sehr, sehr klein und die ersten EJB-Versionen so gut wie unanwendbar. Aber diese Pionierzeit, die sicherlich auch ihre spannenden Seiten hatte, ist zum Glück längst vorbei. Natürlich haben 3-Schichten-Architekturen auch erhebliche Nachteile. Augenscheinlich ist dabei die aus der starken Verteilung der Gesamtapplikation resultierende Kompliziertheit. Debugging macht in so einer Umgebung keine Freude mehr, ganz zu schweigen von den Kommunikations-Overheads. Es ist daher in jedem Projekt völlig berechtigt zu analysieren, ob diese Architektur dem zu lösenden Problem angemessen ist. Es ergibt beispielsweise meistens keinen Sinn, ein nächtlich laufendes Massenverarbeitungsprogramm ohne Oberfläche auf drei Prozesse zu verteilen. Trotzdem geschieht das oft genug, weil man dafür Logik benötigt, die in Form von EJBs bereits vorliegt und der Einfachheit halber im Server aufgerufen wird. Verständlich zwar, aber doch irgendwo eine Kapitulation vor der Technik. Nun ist zu sagen, dass – ganz unabhängig vom Aspekt der Verteilung – eine Schichtenarchitektur in Enterprise-Systemen grundsätzlich nicht verkehrt ist, um Abstraktionsebenen zu schaffen und Austauschbarkeit von Ebenen durch verminderte Kopplung zu ermöglichen. Viele Aspekte des EJB-Standards sind für so etwas sehr hilfreich, auch wenn gar keine Prozessgrenzen zu überwinden sind. Und selbst in kompliziert verteilt arbeitenden Projekten gibt es mindestens einen Grund für eine unverteilte Anwendung von EJBs, und zwar das automatische Unit-Testen, dem wir einen eigenen Abschnitt gewidmet haben (siehe Kapitel 10.1). Es gibt zwar schon lange Frameworks, die dafür Lösungen anbieten (siehe [OPENEJB] und [CUBA]), aber mit den Vereinfachungen der Version 3 des Standards rückt diese Option viel stärker als früher ins Bewusstsein der JEE-Gemeinde. Das traditionelle Bild der unumgänglichen Schwergewichtigkeit einer 3-Schichten-Architektur im Zusammenhang mit Enterprise JavaBeans lässt sich also weitgehend revidieren, wie sich im Laufe dieses Buchs zeigen wird. 12 1.3 Ein bisschen Komponenten-Theorie 1.3 Ein bisschen Komponenten-Theorie Nun gut, EJBs sollen es also einfach machen, etwas so Kompliziertes wie eine 3-Schichten-Architektur aufzubauen. Dazu bedarf es natürlich eines trickreichen, aber griffigen Konzepts, und in diesem Zusammenhang kommt der Begriff der Komponente ins Spiel. Für sich allein betrachtet ist der Ausdruck leider inzwischen völlig verwässert. Im EJBBereich wird er aber im Zusammenhang mit dem Container-Component-Architekturmuster verwendet, in dem eine deutlich klarere Vorstellung besteht. Die Idee dabei ist eine Zerlegung der Verantwortlichkeiten einer Server-Applikation in eher technisch, infrastrukturell geprägte Aufgaben einerseits und die eigentliche Logik andererseits. Die Implementierung der Logik liegt in den Komponenten und ist Aufgabe des Anwendungsentwicklers, während die Infrastruktur von einem Container zur Verfügung gestellt wird. Der Container bildet den Lebensraum der Komponenten und sorgt dafür, dass der Entwickler derselben möglichst wenig davon mitbekommt, dass er überhaupt ein verteiltes System programmiert. Das zugrunde liegende Prinzip bei dieser Architektur ist als „Separation of Concerns“ bekannt. Einen kleinen Vorgeschmack dieses Prinzips bekommt eigentlich jeder, der überhaupt mit Java arbeitet. Eine Java-Klasse ist ja im Grunde noch kein lauffähiges Programm wie etwa das Ergebnis einer C++-Kompilation, selbst wenn sie eine Main-Methode hat. Eine JavaKlasse braucht eine Java Virtual Machine als Laufzeitumgebung – also eine Art Container, der dem Entwickler der Klasse schon eine Reihe von Sorgen abnimmt im Vergleich zu C++. So muss sich in Java z.B. niemand um eine Portierung kümmern, wenn die Klasse auf einem anderen Betriebssystem ablaufen soll. Man braucht auch die Instanzen von Klassen nicht selbst programmatisch freizugeben, weil das schon die Garbage Collection der JVM besorgt. Dieses Prinzip wird im EJB-Standard und darüber hinaus in der gesamten JEE-Welt weiter fortgeführt und um Aspekte ergänzt, die speziell für den Entwurf verteilter Systeme von Bedeutung sind. Als Container einer EJB fungiert ein so genannter Application-Server, der sich nun um weit mehr kümmert als um Garbage Collection und Portierbarkeit. Er stellt z.B. sicher, dass Komponenten nur so aufgerufen werden, wie es die Berechtigungen der Aufrufer erlauben. Er sorgt auch dafür, dass jede Komponenteninstanz immer nur von einem Thread gleichzeitig durchlaufen wird und trotzdem viele Clients gleichzeitig von einem Server bedient werden können. Damit das alles funktioniert, muss es dem Application-Server ermöglicht werden, überall dort koordinierend einzugreifen, wo eine Komponente aufgerufen wird oder eine Komponente selbst eine andere aufruft. Diese Notwendigkeit hat zwei Konsequenzen: Zum einen sprechen sich Komponenten gegenseitig üblicherweise über wohl definierte (Java) Interfaces statt über direkte Objekt-zu-Objekt-Aufrufe an. Zum anderen übernimmt der Application-Server auch die Instanziierung der Komponenten, damit er sich bei Bedarf an den Schnittstellen über so genannte Proxies in die Kommunikation einschalten kann, um unbemerkt Infrastrukturaufgaben für die Komponenten wahrzunehmen. 13 1 Technische Grundlagen und historische Entwicklungen Client Komponente Proxy Proxy Datenbanken Komponente Naming Annotationen Container Ressourcen Security … andere Fremdsysteme Abbildung 1.4 ContainerKomponentenArchitektur Wie diese Aufgaben konkret aussehen, ist nicht durch den Code der Komponenten bestimmt, sondern durch Konfigurations-Informationen, die separat von der Implementierung verfasst werden. Im EJB-Standard konnten diese Informationen bis zur Version 2.x ausschließlich durch XML-Dateien formuliert werden – so genannte Deskriptoren. Seit EJB 3 lassen sich alternativ oder ergänzend auch Java-Annotationen im Code verwenden (siehe dazu auch das Kapitel 1.5.1), wobei hier bereits auffällt, dass dies dem Grundkonzept der Konfiguration ohne Code-Änderung widerspricht. Dieser Widerspruch ist zum Teil dem Pragmatismus geschuldet, der EJBs nach dem aktuellen Standard so einfach macht. Wir werden im Rahmen dieses Buches hin und wieder darauf eingehen, wo Annotationen sinnvoll sind und wo vielleicht auch nicht. Das Container-Komponenten-Muster unterscheidet grob drei Arten von Komponenten, die sich auch im EJB-Standard wiederfinden: Service-Komponenten Sie stellen Dienstfunktionen zur Verfügung, für welche die Komponente keine Informationen über den Zustand des Aufrufers kennen muss. Sie merkt sich auch von einem Aufruf zum anderen keinerlei client-spezifische Kontextinformationen und kann daher auch abwechselnd von verschiedenen Clients verwendet werden. So lassen sich solche Komponenten vom Server auch sehr ressourcenschonend verwalten. Die Entsprechung im EJB-Standard sind die Stateless SessionBeans, die wir in Kapitel 3.2 en détail besprechen. Session-Komponenten Im Gegensatz zu Service-Komponenten ist diese Art in der Lage, sich Client-spezifische Statusinformationen zu merken. Dadurch kann sich ein Interaktionsvorgang mit dem Client über mehrere Aufrufe hinweg erstrecken, ohne dass die Komponente dabei „den Faden verliert“. Die Verwaltung stellt den Server schon vor größere Herausforderungen, weil sich in diesen Komponenten serverseitig für etwas längere Zeit transiente Daten ansammeln, die das System belasten können und Auslagerungsstrategien notwendig machen. Im EJB-Standard wird diese Art von Komponenten durch Stateful SessionBeans abgebildet, um die es im Kapitel 3.3 geht. Entity-Komponenten Sie bilden die Geschäftsobjekte, auf denen die Anwendung operiert. Üblicherweise werden sie nicht direkt von außerhalb des Servers angesprochen, sondern über den Umweg der Service- und Session-Komponenten, welche die Prozesslogik enthalten. 14 1.3 Ein bisschen Komponenten-Theorie Sie sind persistent und besitzen ein eindeutiges Identifikationsmerkmal, über das erkennbar ist, welchen Datensatz einer zugrunde liegenden Datenbank sie gerade repräsentieren. Arbeiten zwei Clients gleichzeitig auf denselben Daten, greifen sie dafür auf dieselbe Entity-Komponente zu. Der Server hat die Aufgabe, die dabei potenziell entstehenden Zugriffskonflikte sowie die Synchronisation der Applikationsdaten mit der Datenbank zu regeln. Der entsprechende EJB-Typ sind die Entities (bis EJB 2.1 die Entity Beans), wobei man hier nur noch sehr bedingt von Komponenten nach dem allgemeinen Muster sprechen kann. In Kapitel 4 gehen wir diesen Dingen auf den Grund. Die erwähnte Trennung von Interface und Implementierung der Komponenten dient noch einem anderen Zweck, und zwar der Umsetzung des Broker-Architekturmusters. Es stellt ein leicht anwendbares Konzept für die Interprozesskommunikation dar, wie es auch außerhalb der JEE-Welt in CORBA2 und RMI3 wiederzufinden ist. Dabei arbeitet der Client ausschließlich gegen das Interface der Komponente, als handele es sich dabei um ein Objekt wie jedes andere, das im lokalen Prozessraum des Aufrufers liegt. Tatsächlich verbirgt sich clientseitig aber ein Stellvertreterobjekt hinter dem Interface (Stub oder Proxy genannt), das die Aufrufe über eine Kommunikationsinfrastruktur an die eigentliche Implementierung weiterleitet. Diese kann dabei in einem ganz anderen Prozess auf einem anderen Rechner vorliegen. Logischer Aufruf Clientobjekt clientseitiger Proxy tatsächlicher Aufruf Serverobjekt serverseitiger Proxy Broker Abbildung 1.5 Broker-Architekturmuster Der Client kann nach diesem Prinzip mit der entfernt liegenden Komponente auf sehr einfache und objektorientierte Weise durch Methodenaufrufe und die Auswertung von Rückgabewerten umgehen. Er braucht sich nicht darum zu kümmern, wie und wohin im Hintergrund die Weiterleitung erfolgt, daher spricht man hier auch von „Ortstransparenz“. In der Praxis ist diese meist nicht vollständig gegeben, weil sich Client und Komponente zu Beginn erst einmal irgendwie finden müssen, bevor es zu Aufrufen kommen kann. Und bei dieser Initiierung scheint der Remote-Aspekt meistens doch ein wenig durch. So ganz schlimm ist das aber nicht, da sich der Entwickler bei allem Komfort in der Anwendung schon im Klaren darüber sein sollte, wo seine Applikation die Prozessgrenzen verlässt. Remote-Kommunikation ist immer eine höchst zeitraubende und mit zusätzlichen Fehlerpotenzialen verbundene Angelegenheit im Vergleich zu lokalen Methodenaufrufen innerhalb einer JVM. 2 3 Common Object Request Broker Architecture … Remote Method Invocation … 15 1 Technische Grundlagen und historische Entwicklungen Wer noch mehr über das Container-Component- oder das Broker-Muster wissen möchte, dem sei das Buch Server Component Patterns (siehe [VSW02]) empfohlen. Für die EJBPraxis soll es an dieser Stelle reichen – außer der Erwähnung, dass sich die Prinzipien durchaus nicht nur im EJB-Standard wiederfinden. Auch das CORBA Component Model (CCM) verfolgt diese Ansätze, wobei es im Gegensatz zu Enterprise JavaBeans leider keine verbreiteten Implementierungen gibt, sondern vor allem eine Spezifikation. Auch Microsofts DCOM-Infrastruktur geht in diese Richtung. 1.4 EJBs und die Java Enterprise Edition Wie schon gesagt, dienen EJBs nur zur Implementierung einer einzigen, wenn auch zentralen Ebene einer 3-Schicht-Architektur. Und was ist mit dem nicht unerheblichen Rest? Die Antwort darauf gibt die Java Enterprise Edition, eine Sammlung von Java Standards, die in Summe alle drei Ebenen abdeckt und den EJB-Standard mit einschließt. Der Begriff „Enterprise“ kommt nicht von ungefähr, denn die JEE ist nicht dafür ausgelegt, jegliche Art von verteilten Systemen zu schaffen. Sie orientiert sich an nicht-funktionalen Anforderungen, die sich im E-Commerce-Sektor und in verwandten Bereichen als typisch herausstellten, aber auf andere Branchen nicht unbedingt übertragbar sind. Ein Aspekt ist z.B. die Vorstellung, dass eine Serveranwendung vielleicht von Tausenden von Benutzern gleichzeitig mit Anfragen bombardiert wird, so dass sich die Forderung nach Skalierbarkeit herausgebildet hat. Wenn z.B. am Ende eines Monats allen Mitarbeitern eines Großkonzerns einfällt, dass sie noch schnell ein paar Stunden in der zentralen Zeiterfassung buchen müssen, dann darf diese Zeiterfassung unter einem solchen plötzlichen Ansturm nicht zusammenbrechen. Für den Bremscomputer eines Autos stellt sich ein derartiges Problem gar nicht, dafür erwarten wir von ihm, dass er immer garantiert innerhalb einer zehntel Sekunde reagiert, wenn er gebraucht wird. Hier zählt also eher die knallharte Performance, für die der JEE-Standard beispielsweise nicht gemacht ist.4 Dafür bietet er aber zum Beispiel ein ausgefeiltes Konzept, um mit anderen Systemen transaktionssicher zu kommunizieren, was in Geschäftsanwendungen eine immer wiederkehrende Notwendigkeit darstellt – die oben erwähnte Zeiterfassung wäre beispielsweise ohne Anschluss an die Personalstammverwaltung ziemlich sinnlos. Abbildung 1.6 vermittelt einen Eindruck von den wichtigsten Standards und an welcher Stelle einer Client-Server-Architektur sie angesiedelt sind. Der EJB-Standard 3.1 ist Teil der Java Enterprise Edition 6, die wiederum auf der Java Standard Edition 6 aufsetzt. Dass die Versionsnummern für Standard und Enterprise gleich sind, ist reiner Zufall. In jedem Fall ist aber mindestens die Standard Edition 1.5 zwingend notwendig, weil die Enterprise Edition bestimmte Neuerungen ausnutzt, die es vorher nicht gab. Das betrifft vor allem die Verwendung von Code-Annotationen, die gerade im EJB-Be4 16 Ein ehemaliger Kollege hat diese Tatsache einmal auf die Formel gebracht, JEE sorge nicht dafür, dass die Performance gut sei, sondern immer gleich schlecht. 1.4 EJBs und die Java Enterprise Edition Webservice Client JSF HTTP HTTP HTTP Web Client JNDI JAAS (IIOP) EJB Client JSP JAX-RCP Servlets EJB JTA JPA ? SQL-Datenbanken JCA ? JMS ? andere Fremdsysteme Abbildung 1.6 JEE-Standards für verteilte Architekturen reich wichtig sind. Was die Betrachtung der anderen Standards angeht, so werden wir uns in diesem Buch auf die Darstellung des Zusammenspiels mit Enterprise JavaBeans beschränken. Die folgende Tabelle ordnet aber jedem Begriff und jeder Abkürzung schon mal eine Bedeutung zu. Tabelle 1.1 Übersicht über die wichtigsten JEE-Technologien Standard Funktion Version Servlets Javas Basistechnologie für den Aufbau dynamischer Webseiten 3.0 JSP JavaServer Pages, ein Template-Ansatz für die Webseitengestaltung, aufbauend auf der Servlet-Technologie. Schon lange im Einsatz. 2.2 JSF JavaServer Faces. Eine noch recht junge, leistungsstärkere Alternative für den Bau von Websites. 2.0 JAAS Java Authentication and Authorization Service. Dient zur Vergabe und Prüfung von Berechtigungen nach einem Rollen-Konzept. 1.0 JAX-RPC Java API für XML-basierte Remote Procedure Calls. Gehört streng genommen nicht zur JEE, ist aber die Basis für Webservice-Interfaces für EJBs. 1.1 JNDI Java Naming & Directory Service. Dient dem Auffinden entfernter Serverdienste. Gehört eigentlich zur Java Standard Edition, wird aber vor allem in der JEE intensiv genutzt. 1.2 JMS Java Messaging Service. Erlaubt asynchrone Kommunikation und ist außerdem als Brücke zur Hostwelt konzipiert. 1.1 JPA Java Persistence API. Schnittstelle zu SQL-Datenbanken. Das JPA gilt nominell als Teil der EJB-Spezifikation, ist aber de facto getrennt zu sehen. Dazu später mehr in Kapitel 4. 2.0 17 1 Technische Grundlagen und historische Entwicklungen Standard Funktion Version JCA Java Connector Architecture. Dient als transaktionssicherer Kommunikationskanal für alles, was keine SQL-Datenbank ist und nicht asynchron über JMS gekoppelt werden soll. 1.6 JTA Java Transaction API. Basis für verteiltes Transaktions-Management. 1.1 Es gibt noch eine ganze Reihe zusätzlicher, unterstützender Spezifikationen, die aber für das Verständnis von Enterprise JavaBeans nicht so wichtig sind. Eine vollständige Liste der Standards, die in der JEE 6 enthalten sind, lässt sich in der Spezifikation nachlesen (siehe [JEE]). 1.5 Handwerkszeug aus der Java Standard Edition 5 Als EJB 3.0 veröffentlicht wurde, geschah dies auf Basis der damals noch taufrischen Version 5 der Java Standard Edition. Inzwischen ist Java 6 die gängige Version, aber der eine oder andere Umsteiger aus der EJB-2-Welt saß vielleicht über seinen Application-Server noch auf ganz alten Ständen der Standard Edition fest. Für diese Leser gilt es zunächst ein paar wichtige Dinge nachzuholen, von denen die Spezifikation von EJB 3 Gebrauch macht. Die folgenden Erläuterungen geben den allernötigsten Abriss, wobei wir dem Leser empfehlen, sich auch darüber hinaus mit diesen Aspekten vertraut zu machen. 1.5.1 Annotationen Generell gesprochen handelt es sich bei Annotationen um eine Möglichkeit, Java-Code mit deklarativen Metadaten anzureichern. Durch ein vorangestelltes @-Zeichen können z.B. auf Klassen-, Methoden- und Attributebene beschreibende Informationen erfasst werden, die der Steuerung generativer oder interpretativer Werkzeuge dienen. Ein bekanntes Beispiel ist die Annotation @SuppressWarnings, mit der dem Java Compiler mitgeteilt werden kann, dass er an bestimmten Stellen im Code keine Warnungen auszugeben braucht. Z.B. würde die Angabe @SuppressWarnings(value="unchecked") public void myMethod(Collection c) { c.add("foo"); } vermeiden, dass der Compiler die typunsichere Verwendung einer Collection anmahnt. Ein solches Feature passt für einen Komponenten-Standard wie Enterprise JavaBeans natürlich wie die Faust aufs Auge, da eine Komponente, wie in Kapitel 1.3 dargestellt, Konfigurationsinformationen benötigt, die beschreiben, wie sie sich in eine Applikation und in den Container einfügt. Statt über separate XML-Deskriptoren lassen sich diese Informationen auch in Form von Annotationen ausdrücken. Z.B. macht allein die Annotation @Stateless eine einfache Klasse zu einer Stateless SessionBean. Die Java Standard Edition stellt die Möglichkeit zur Deklaration beliebiger Annotationstypen zur Verfügung 18 1.5 Handwerkszeug aus der Java Standard Edition 5 sowie ein API, um diese zur Übersetzungs- oder zur Laufzeit auszuwerten. Die Java Enterprise Edition nutzt dieses Feature, um eine ganze Reihe verbindlicher, von den Herstellern der Application-Server zu unterstützender Annotationen zu definieren, die für den Aufbau verteilter Systeme nützlich sind. 1.5.2 Generics Der Sinn von Generics wird besonders im Zusammenhang mit dem Collection-Framework von Java deutlich. Collections erlauben von Haus aus die Verwaltung beliebiger Objekte, was immer dann störend ist, wenn man eigentlich gar nicht beliebige Dinge in eine Collection hineinstecken will. In den meisten Fällen ist es ziemlich ärgerlich, wenn einer Collection von ihrer Deklaration im Code her nicht anzusehen ist, dass nur eine bestimmte Art von Objekten darin vorkommt. Beim Auslesen des Inhalts muss deshalb auch mit Typecasts gearbeitet werden, was nicht nur unschön ist, sondern auch die Gefahr birgt, dass Fehler bei der Verwendung einer Collection erst zur Laufzeit auffallen. Das folgende Codebeispiel für die Ausgabe der Daten einer String-Collection macht dieses Problem deutlich. /** Erwartet Collection, die nur Strings enthält. Nicht typsicher! */ public void printStrings(Collection c) { Iterator iter = c.iterator(); while (iter.hasNext()) { /* Extraction über Typecast */ String element = (String)iter.next(); System.out.println(element); } } In Java 5 ist das Collection-Interface nun ein generischer Typ (ein Generic), der an einen konkreten Typen gebunden werden kann. Dieser konkrete Typ wird in spitzen Klammern angefügt, also z.B. Collection<String>, um auszudrücken, dass es sich um eine Kollektion von Strings handelt. Das obige Beispiel ändert sich mit der Verwendung der Typbindung wie folgt: public void printStrings(Collection<String> c) { Iterator<String> iter = c.iterator(); while (iter.hasNext()) { /* Extraction benötigt keinen Typecast */ String element = iter.next(); System.out.println(element); } } Der Code wird durch diese Typbindung verständlicher und sicherer, und Typprüfungen können außerdem bereits vom Compiler zur Übersetzungszeit vorgenommen werden. Es ist sicher nicht ganz zufällig, dass die Notation mit spitzen Klammern an den TemplateMechanismus von C++ erinnert. Trotzdem gibt es erhebliche Unterschiede zwischen beiden Konzepten, zu denen sich reichlich Diskussionsstoff im Internet findet, wenn man es ganz genau wissen will. Der Vollständigkeit halber sei hinzugefügt, dass sich ein Iterationsvorgang in Java 5 sogar noch eleganter formulieren lässt, indem man die Erweiterung für For-Schleifen verwendet. Was an dieser Stelle allerdings nebensächlich ist. 19 1 Technische Grundlagen und historische Entwicklungen Für Enterprise JavaBeans sind Generics im Zusammenhang mit Entities von Interesse, wo sie als Mittel zur Darstellung von 1:N- und N:M-Beziehungen hilfreich sind (siehe Kapitel 4.5). 1.5.3 Autoboxing Autoboxing und Autounboxing erlauben die Zuweisung primitiver Datentypen zu ihren entsprechenden Objekttypen und umgekehrt. Betrachtet man z.B. einen ganzzahligen Wert, lässt sich dieser in Java durch den primitiven Typ int oder die Klasse Integer repräsentieren. Den primitiven Typ benötigt man, um in Java leicht verständliche mathematische Ausdrücke hinzuschreiben, z.B. etwas wie i3 = (i1 + 5) * i2. Das ist mit IntegerObjekten nicht möglich, weil Java keine Operatorüberladung unterstützt. Dafür kann man ein Integer-Objekt z.B. in eine Collection stecken, was wiederum mit einem int nicht funktioniert, weil es sich dabei um kein Objekt handelt. Beide Repräsentationen werden also gebraucht. Daher war es bis Java 1.4 des Öfteren notwendig, ein int in ein Integer zu verpacken (Boxing) oder, umgekehrt, ein int aus einem Integer zu extrahieren (Unboxing). Mit Java 5 geschieht dies automatisch, wie das folgende Codebeispiel verdeutlicht. Integer i1 = 5; /* Autoboxing */ int i2 = i1; /* Autounboxing */ Vector<Integer> ivec = new Vector<Integer>(); ivec.add(i2); /* Autoboxing */ Im EJB-Standard kommt Autounboxing zum Tragen, wenn Komponenten vom Container mit Konfigurationsparametern versorgt werden. Wir kommen darauf im Kapitel 6.4 zu sprechen. 20 Register @ @Access 131 @AccessTimeout 73, 77 @ActivationConfigProperty 199 @AfterCompletion 242 @ApplicationException 80, 228 @AroundInvoke 275 @AroundTimeout 282 @AssertFalse 157 @AssertTrue 157 @AssociationOverride 131 @Asynchronous 58 @AttributeOverride 114 @Basic 111 @BeanLocal 53 @BeforeBegin 242 @BeforeCompletion 242 @Cacheable 133 @CollectionTable 117 @Column 109 @ColumnResult 175 @ConcurrencyManagement 72 @DecimalMax 157 @DecimalMin 157 @DeclareRoles 264 @DenyAll 261 @DependsOn 71 @Digits 157 @DiscriminatorColumn 127 @DiscriminatorValue 127 @EJB 207 @EJBs 208 @ElementCollection 114 @Embeddable 113 @Embedded 113 @EmbeddedId 119 @Entity 91, 155 @EntityListeners 101 @EntityResult 175 @Enumerated 112 @ExcludeClassInterceptors 279 @ExcludeDefaultInterceptors 280 @FieldResult 175 @Future 157 @GeneratedValue 98, 119 @Id 119 @IdClass 119 @Inheritance 126 Joined 127 Single-Table 126 Table-Per-Class 129 @Init 66 @Interceptors 279 @JoinColumn 139, 148 @JoinColumns 149 @JoinTable 146, 151 @Lob 112 @Local 50 @LocalHome 60 @Lock 73 355 Register @ManyToMany 150 @ManyToOne 141, 147 @MapKey 119, 147 @MapKeyClass 118, 147 @MapKeyColumn 118 @MapKeyEnumerated 118 @MapKeyJoinColumn 119 @MapKeyJoinColumns 119 @MapKeyTemporal 118 @MappedSuperclass 130 @MapsId 154 @Max 157 @MessageDriven 199 @Min 157 @NamedNativeQuery 176 @NamedQuery 176 @NotNull 157 @Null 157 @OneToMany 141 @OneToOne 138 @OrderBy 116 @OrderColumn 115 @Past 157 @Pattern 157 @PermitAll 261 @PersistenceContext 95, 216 @PersistenceUnit 183, 216 @PostActivate 67 @PostConstruct 46 @PreDestroy 47 @PrePassivate 67 @PrimaryKeyJoinColumn 107, 129 @PrimaryKeyJoinColumns 107 @Remote 45 @RemoteHome 60 @Remove 64 @Resource 210, 212 @Resources 213 @RolesAllowed 261 @Schedule 273 @Schedules 274 @SecondaryTable 105 @SecondaryTables 105 356 @SequenceGenerator 121 @Singleton 71 @Size 157 @SqlResultSetMapping 175 @Startup 71 @Stateful 64 @Stateless 44 @Table 105 @TableGenerator 121 @Temporal 112 @Timeout 273 @TransactionAttribute 230 @TransactionManagement 230 @Transient 122 @UniqueConstraint 107, 147 @Version 123 @WebMethod 55 @WebService 55 @WebServiceRef 217 2 2-Phase-Commit 224 2-Schichten-Architektur 11 3 3-Schichten-Architektur 10 A Abfrage 159 Aktualisierungs- 173 benannt 176 Lösch- 173 parametrisiert 168 SQL 174 streng typisiert 177 typisiert 177 Abfragesprache 163 Bedingung 166 DELETE 173 FROM 163 Funktion 168, 171 GROUP-BY 170 HAVING 170 Register Join 164 Konstruktorausdruck 171 Literal 167 NEW 171 Operator 166 ORDER BY 172 Pfadausdruck 164 SELECT 171 Unterabfrage 172 UPDATE 173 WHERE 166 ACID 222 Annotation 18 Application-Assembler 33, 81 Application-Client 205, 251 Application-Server 13 Applikations-Exception 79 Architektur 2-Schichten 11 3-Schichten 10 Broker 15 Container-Component 13 Aspekt 275 Deployment-Deskriptor 282 Asynchrone Methoden 58 Exceptions 60 Future 59 Authentifizierung 247 anonymer Aufruf 248 Callback-Handler 251, 252 Caller-Principal 249 Clientseite 250 Java Authentication and Authorization Service 251 Login-Konfiguration 255 Passwortübermittlung 251, 252 Principal-Delegation 249 Principal-Propagation 249 Realm 256 Run-As 249 Serverseite 256 Sicherheits-Domäne 256 Autoboxing 20 Autorisierung 247, 260 deklarativ 261 Deployment-Deskriptor 262, 264 EJBContext 263 Method-Permission 261 programmatisch 263 Rollenabbildung 264 Sicherheitsrolle 260 B bean-managed transaction 235 Bean Validation Standard 155 Bean-verwaltete Transaktion 235 Beziehung 134 1 zu 1 137 1 zu N 141 bidirektional 134 N zu 1 147 N zu M 149 unidirektional 134 BMT 235 siehe auch bean-managed transaction C Cache First-Level 93, 132 Read-Only 322 Second-Level 132 CacheRetrieveMode 133 CacheStoreMode 133 Caching 132 Callback-Interceptor 48, 281 Callback-Methode 46, 65, 197 CascadeType 140 CDI 327 siehe auch Contexts and Dependency Injection checked Exception 79 Client-Server-System 7 Client-verwaltete Transaktion 244 Clusterbetrieb 33 CMT 226 siehe auch container-managed transaction Collection Table 117 Commit 224 357 Register Configuration-by-Exception 42, 51 Container 13 container-managed transaction 226 container-verwaltete Transaktion 226 Message-Driven Bean 234 Contexts and Dependency-Injection 327 Copy-Deployment 27 Criteria-API 177, 179 AbstractQuery 178 CollectionJoin 179 CompoundSelection 178 CriteriaBuilder 178 CriteriaQuery 178 Expression 178 Fetch 179 FetchParent 179 Join 179 ListJoin 179 MapJoin 179 Order 179 ParameterExpression 179 Path 178 PluralJoin 179 Predicate 178 Root 179 Selection 178 SetJoin 179 Subquery 178 CriteriaBuilder 178 D DAO 91 siehe auch Data-Access-Object Data-Access-Object 91 DataSource 87, 89, 238 XA-fähig 239 Dateisystem 34, 333 Datenbank 87 Datenintegrität 266 Datenverschlüsselung 265 Dependency-Injection 46, 205, 289 Dependency-Lookup 205 Deployer 33 Deployment 26 358 vereinfacht 325 Deployment-Deskriptor 81, 200, 217 <activation-config> 201 <activation-config-property> 201 <business-local> 82 <business-remote> 82 <ejb-class> 82, 201 <ejb-link> 208 <ejb-local-ref> 208 <ejb-name> 82, 201 <ejb-ref> 209 <ejb-ref-name> 208 <ejb-ref-type> 208 <enterprise-beans> 81, 200 <env-entry> 210 <env-entry-name> 210 <env-entry-type> 211 <exclude-default-interceptors> 283 <home> 82 <injection-target> 209 <interceptor-binding> 283 <interceptor-class> 283 <interceptor-order> 284 <interceptors> 283 <lifecycle-callback-method> 83 <local> 82 <local-home> 82 <message-destination> 216 <message-destination-name> 216 <message-destination-ref> 214 <message-destination-ref-name> 215 <message-destination-res-type> 215 <message-destination-usage> 215 <message-driven> 200 <messaging-type> 201 <method> 283 <method-name> 283 <method-params> 283 <method-permission> 262 <post-activate> 83 <post-construct> 83, 201 <pre-destroy> 83, 201 <pre-passivate> 83 Register <remote> 82 <res-auth> 214 <resource-env-ref> 217 <resource-ref> 214 <res-ref-name> 214 <res-sharing-scope> 214 <res-type> 214 <role-link> 264 <role-name> 262 <security-role-ref> 264 <security-roles> 262 <service-endpoint> 82 <session> 81 <session-type> 83 Aspekt 282 Autorisierung 262, 264 EJB-Referenz 208 Hersteller-Deskriptor 217 Interceptor 282 Konfigurations-Parameter 210 Nachrichtenziele 214 Ressourcen-Manager-Referenz 214 Deskriptor 14, 81 siehe auch Deployment-Deskriptor Diskriminatorspalte 126 E EinStein 305 EJB-Container-Provider 33 EJBContext 77, 263, 269 EJBException 80 EJB-Jar 27 ejb-jar.xml 81 EJB-Konfiguration EJB-Referenz 206 Environment-Entry 210 siehe auch Konfigurations-Parameter Konfigurations-Parameter 210 Link 209, 215 Lokaler JNDI-Kontext 204 Message-Destination 214 siehe auch Nachrichtenziel Nachrichtenziel 214 Object-Request-Broker 217 Persistence-Context 216 siehe auch Persistenzkontext Persistence-Unit 216 Persistenzkontext 216 Resource Manager Factory 211 siehe auch Ressourcen-Manager-Fabrik Resource-Environment-Referenz 217 Ressourcen-Manager-Fabrik 211 Webservice 217 EJB lite 286, 290 EJBObject 284 EJB-Referenz 51, 206 EJB-Server-Provider 33 Element Collection 114 Embeddable Container 285, 290 Enterprise-Archive 27, 325 Enterprise-Bean-Provider 32, 81 Entity 85, 90 Beziehung 134 Lebenszyklus 98 Lifecycle-Callback-Methoden 100 sperren 184 Validierung 155 EntityManager 92 Abfragefunktionen 162, 174, 176 applikationsverwaltet 183 Grundfunktionen 102 EntityManagerFactory 183 EntityTransaction 184, 237 Entwurfsmuster 292 Business-Delegate 292, 301 Business-Interface 296, 301 Composite-Entity 295 Data-Access-Object 294, 302 Data-Transfer-Object 294 Data-Transfer-Object-Factory 295 Domain-Object 296 Message-Façade 293 Service-Locator 293 Session-Façade 293 Session-Wraps-Entity 297 Value-List-Handler 69, 294, 343 359 Register Value-Object 294 Value-Object-Assembler 295 F Fetch-Typ 111, 139, 144 First-Level-Cache 93, 132 Flush-Modus 103, 163, 175 Fremdschlüssel 138 G Generics 19 H HomeHandle 285 Home-Interface 21, 42 I InitialContext 29, 89 Installation Application-Server 24 EJB 26 JEE-Plattform 24 Interceptor 275 Default-Interceptor 280 Deployment-Deskriptor 282 Interceptor-Klasse 278 Interceptor-Methode 275 InvocationContext 275 Lebenszyklus 281 Lifecycle-Callback 48, 281 Timer-Methoden 282 Inversion-Of-Control 205 J JAAS 251 siehe auch Java Authentication and Authorization Service Java Authentication and Authorization Service 251 Callback-Handler 251, 252 LoginContext 253 Login-Konfiguration 255 LoginModule 257 Login-Vorgang 259 360 Java Connector Architecture 18, 196, 217, 223 Inbound-Connector 196 Java Enterprise Edition 7, 16 Java Message Service 188 Asynchroner Nachrichtenempfang 194 ByteMessage 191 MapMessage 191 Nachrichten-Filter 193 ObjectMessage 191 StreamMessage 192 Synchroner Nachrichtenempfang 193 TextMessage 192 Java Naming and Directory Interface 29 Java Persistence API 86 Java Standard Edition 18 Java Transaction API 18 JavaServer Faces 17 JavaServer Pages 17 JAX-RPC 17 JCA 18 siehe auch Java Connector Architecture JEE 16 siehe auch Java Enterprise Edition JEE-Modul 27 JMS 188 siehe auch Java Message Service JNDI 29 siehe auch Java Naming and Directory Interface Portable JNDI-Namen 29 JNDI-Kontext global 204 lokal 204 Subkontext 204 JNP-Protokoll 30 Join 164 fetch 165 inner 165 kartesisch 164 outer 165 JPA 86 siehe auch Java Persistence API JSF 326 JSF 17 siehe auch JavaServer Faces JSP 17 siehe auch JavaServer Pages JTA 18 siehe auch Java Transaction API Register K Kalender-Ausdruck 270 Attribute 271 Kaskadierung 140 Komponente 13 Entity 14 Service 14 Session 14 Theorie 13 L Lebenszyklus Callback 46 Entity 98 Interceptor 281 Message-Driven Bean 196 Stateful SessionBean 62 Stateless SessionBean 39 Lifecycle-Callback-Interceptor 48 Lifecycle-Callback-Methoden Entity 100 Stateful SessionBean 65 Stateless SessionBean 46 Lifecycle-Event 46 Local-Home-Interface 61 M Managed-Object 87 Massenaktualisierung 173 Massenlöschung 173 MDB 188 siehe auch Message-Driven Bean Message-Driven Bean 188, 196 Callback-Methode 197 Deployment-Deskriptor 200 Lebenszyklus 196 MessageDrivenContext 197 MessageListener 198 Pool 197 Timed Object 269 Message-Oriented-Middleware 187 siehe auch Nachrichtenbasierte Middleware Metamodell 179 Attribute 182 BasicType 182 Bindable 182 CollectionAttribute 182 EmbeddableType 182 EntityType 182 IdentifiableType 182 ListAttribute 182 ManagedType 182 MapAttribute 182 MappedSuperclassType 182 Metamodel 182 PluralAttribute 182 SetAttribute 182 SingularAttribute 182 Type 182 Migration 297 Abwärtskompatibilität 298 Modell-getrieben 300 Refakturierung 301 Unit-Test 301 Modul 27 MOM 187 siehe auch Nachrichtenbasierte Middleware N Nachrichtenbasierte Middleware 187 administered Objects 189 siehe auch bereitgestellte Objekte bereitgestellte Objekte 189 Empfänger 187 Empfangsbestätigung 191 Message-Consumer 188 siehe auch Nachrichten-Verbraucher Message-Producer 188 siehe auch Nachrichten-Erzeuger Nachrichten-Client 188 Nachrichten-Erzeuger 188, 192 Nachrichten-Server 188 Nachrichten-Verbraucher 188, 193 Publish-Subscribe-Modell 194 Punkt-zu-Punkt-Modell 189 Queue 189 siehe auch Warteschlange Sender 187 361 Register Topic 194 Warteschlange 189 Namensdienst 29 Native Bibliothek 35 O O/R-Mapping 87 siehe auch Objektrelationale Abbildung Objektrelationale Abbildung 87, 104 Ohne Schnittstelle 52 OJB 185 OpenEJB 286, 291, 348 Optimistic Locking 123 siehe auch Optimistisches Sperren Optimistisches Sperren 123 362 PostConstruct 46 PostLoad 101 PostPersist 101 PostRemove 101 PreDestroy 47 PrePassivate 67 PrePersist 101 PreRemove 101 PriDE 185 Principal 248 Programmiermodell 33 Proxy 15 Q Query 159 P R Paralleler Zugriff 76 Bean-verwaltet 75 Container-verwaltet 72 Explizite Synchronisierung 75 Lock 73 Singleton SessionBean 72 Stateful SessionBean 77 Stateless SessionBean 76 Peer-To-Peer-System 188 persistence.xml 95 <shared-cache-mode> 133 Persistence-Manager 93 Persistence-Provider 93 Persistence-Unit 92 Persistenz 85 Persistenzkontext 92, 238 erweitert 183 Pfadausdruck 164 einzelwertig 164 mengenwertig 164 Plain Old Java Interface 42 Plain Old Java Object 41, 198 POJI 42 siehe auch Plain Old Java Interface POJO 41 siehe auch Plain Old Java Object Polling 310 PostActivate 67 Relation 134 Remote-Home-Interface 60 Remove 64 Resource-Factory 240 Ressource 223 transaktional 238 Rollback 224 Bean-verwaltete Transaktion 236 Container-verwaltete Transaktion 227 Rolle 32 Application-Assembler 33, 81 Deployer 33 EJB-Container-Provider 33 EJB-Server-Provider 33 Enterprise-Bean-Provider 32, 81 System-Administrator 33 S Second-Level-Cache 132 Secure Socket Layer 266 Gegenseitige Authentifizierung 266 SSL-Zertifikat 266 Separation of Concerns 13 Servlets 17 SessionBean 37 Asynchrone Methoden 58 Register Deployment-Deskriptor 81 EJB2-Sicht 42, 60, 65 Handle 284 Local-Interface 39, 50, 63 Lokaler Zugriff 38, 50 Ohne Schnittstelle 52 Paralleler Zugriff 76 Remote-Interface 30, 38, 63 Remote-Zugriff 38 SessionContext 77 Singleton 37, 322, 324 Stateful 37, 61 Stateless 37, 39, 69 Timed-Object 269 SessionSynchronization 241 Per Annotation 242 Singleton SessionBean 37, 322, 324 Abhängigkeiten 71 Paralleler Zugriff 72 SQL-Datenbank 87 SSL 266 siehe auch Secure Socket Layer Stateful SessionBean 37, 61 Aktivierung 67 Callback-Interceptor 48 Callback-Methode 46, 65 Init-Methode 65 Lebenszyklus 62 Local-Interface 63 Paralleler Zugriff 77 Passivierung 67 Remote-Interface 63 SessionSynchronization 66 Stateless SessionBean 37, 39, 69 Callback-Interceptor 48 Callback-Methode 46 Implementierung 42, 44 Lebenszyklus 39 Local-Interface 50 Lokaler Zugriff 50 Paralleler Zugriff 76 Pool 40 Remote-Business-Interface 42, 45 Webservice 39, 54 WebServiceContext 58 System-Administrator 33 System-Exception 68, 80 T Testen 287 Frameworks 291 mit OpenEJB 348 Mock-Objekt 288 Test Driven Development 288 siehe auch Testgetriebene Entwicklung Testgetriebene Entwicklung 288 Unit-Test 288 Timed-Object 269 Automatische Timer 273, 324 Interceptor 282 Kalender-Ausdruck 270 Persistente Timer 272 Timeout-Callback 270, 272 Timer 270 TimerService 269 TimerService 269 TLS 266 siehe auch Transport Layer Security Transaktion 88, 221 Bean-verwaltet 235 Client-verwaltet 244 Container-verwaltet 226 Datenbank- 222 Propagation 233 unspezifiziert 234 Transaktionskontext 223 Transport Layer Security 266 TypedQuery 177 U unchecked Exception 80 Unit-Test 288 Mock-Objekt 288 UserTransaction 236, 244 V Validierung 155 Verteiltes System 7 363 Register W Web-Archive 325 Webservice 39, 54, 217, 329 RESTful 58, 331 364 WebServiceContext 58 Webservice-Description-Language 55 WSDL 55 siehe auch Webservice-DescriptionLanguage