Implementierung einer Referenzanwendung für den JBoss Application Server unter Verwendung der Java 2 Enterprise Edition Mark Rambow geb. am 09.08.1977 in Potsdam Diplomarbeit zur Erlangung des akademischen Grades Diplom-Informatiker (FH) eingereicht an der Fachhochschule Brandenburg - Fachbereich Informatik und Medien - Betreuer Erstprüfer: Prof. Dr. Ing. Stefan Edlich (Fachhochschule Brandenburg) Zweitprüfer: Prof. Dr. Ing. Thomas Preuß (Fachhochschule Brandenburg) Brandenburg an der Havel, 22. Mai 2004 Danksagung Durch die Auswahl des Themas und die gemeinsame Bestimmung der Schwerpunkte mit meinem betreuenden Prof. Dr. Stefan Edlich, ist die vorliegende Diplomarbeit zum interessantesten Teil meines Studiums geworden. Für die Unterstützung bei der Umsetzung möchte ich mich hiermit bei meinen Betreuern Prof. Dr. Stefan Edlich und Prof. Dr. Thomas Preuß bedanken. Ebenfalls möchte ich mich an dieser Stelle bei meinen Kommilitonen Christian Koth, Jens Ziegler, Oliver Kalz, Andreas Graff und Mathias Meyer bedanken. Durch ihre konstruktive Kritik und ihr fachliches Wissen konnten einige Fragen, die im Verlauf der Arbeit auftraten, geklärt werden. Meinen Eltern möchte ich für die hervorragende Unterstützung während des gesamten Studiums danken. Mark Rambow Inhaltsverzeichnis 1. Einleitung 1 1.1. Thematik und Aufbau der Arbeit . . . . . . . . . . . . . . . . . . . . . . . 1 1.2. Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1.3. Aufgabenstellung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 2. Theoretische Grundlagen 3 2.1. Einführung in plattformunabhängige Programmierung . . . . . . . . . . . . 3 2.1.1. Die Java-Plattform . . . . . . . . . . . . . . . . . . . . . . . . . . 4 2.1.2. XML als plattformunabhängiges Datenformat . . . . . . . . . . . . 8 2.1.3. SQL, die Standard-Datenbank-Anfragesprache . . . . . . . . . . . 10 2.2. Verteilte Anwendungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 2.2.1. Komponenten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.2.2. Komponentenmodelle in Java . . . . . . . . . . . . . . . . . . . . 15 2.2.3. Alternative Komponentenmodelle . . . . . . . . . . . . . . . . . . 18 2.2.4. Vergleich der Komponentenmodelle . . . . . . . . . . . . . . . . . 21 2.3. Softwareentwicklung für komponentenbasierte Systeme . . . . . . . . . . . 24 2.3.1. Komponenten-Engineering . . . . . . . . . . . . . . . . . . . . . . 24 2.3.2. UML als Standard zur Modellierung des Entwicklungsprozesses . . 26 3. Enterprise JavaBeans 29 3.1. Rollenmodell bei J2EE . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 3.1.1. Enterprise Bean-Provider . . . . . . . . . . . . . . . . . . . . . . . 29 3.1.2. Application Assembler . . . . . . . . . . . . . . . . . . . . . . . . 30 3.1.3. Deployer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 vi Inhaltsverzeichnis 3.1.4. EJB-Server-Provider . . . . . . . . . . . . . . . . . . . . . . . . . 31 3.1.5. EJB-Container-Provider . . . . . . . . . . . . . . . . . . . . . . . 31 3.1.6. System-Administrator . . . . . . . . . . . . . . . . . . . . . . . . 32 3.2. Architektur der Enterprise JavaBeans . . . . . . . . . . . . . . . . . . . . . 32 3.2.1. J2EE-Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 3.2.2. EJB-Container . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 3.2.3. Programmierrestriktionen bei EJB . . . . . . . . . . . . . . . . . . 37 3.3. Enity Beans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 3.3.1. Aufbau einer Entity Bean . . . . . . . . . . . . . . . . . . . . . . . 38 3.3.2. Bean Managed Persistence . . . . . . . . . . . . . . . . . . . . . . 40 3.3.3. Container Managed Persistence . . . . . . . . . . . . . . . . . . . 41 3.3.4. Container Managed Relations . . . . . . . . . . . . . . . . . . . . 45 3.3.5. Client-Sicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 3.3.6. Alternativen für persistente Objekte . . . . . . . . . . . . . . . . . 48 3.4. Session Beans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 3.4.1. Stateless Session Beans . . . . . . . . . . . . . . . . . . . . . . . 49 3.4.2. Stateful Session Beans . . . . . . . . . . . . . . . . . . . . . . . . 50 3.4.3. Client-Sicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 3.5. Message-Driven Beans . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 3.6. Transaktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 4. JBoss Application Server 61 4.1. Architektur des JBoss . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 4.1.1. Java Management Extension . . . . . . . . . . . . . . . . . . . . . 61 4.1.2. Aufbau des JBoss-Kerns . . . . . . . . . . . . . . . . . . . . . . . 63 4.1.3. JBoss Interceptor-Architektur . . . . . . . . . . . . . . . . . . . . 64 4.2. Deployment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 4.2.1. JBoss Classloading . . . . . . . . . . . . . . . . . . . . . . . . . . 65 4.2.2. JBoss Deployment-Komponenten . . . . . . . . . . . . . . . . . . 66 4.2.3. Hot-Deployment . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 4.2.4. Vorgang des Deployments . . . . . . . . . . . . . . . . . . . . . . 70 4.2.5. Clustering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 4.2.6. Cluster-Architektur des JBoss . . . . . . . . . . . . . . . . . . . . 72 Inhaltsverzeichnis vii 4.3. EJB-Container . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 4.4. Webserver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 4.5. JBoss-Konfiguration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 4.5.1. JBoss-Standard-Konfigurationen . . . . . . . . . . . . . . . . . . . 81 4.5.2. JBoss-spezifische Deployment-Deskriptoren . . . . . . . . . . . . 84 4.5.3. Konfiguration für HTTPS-Verbindungen . . . . . . . . . . . . . . . 90 4.6. JBoss Version 4.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 4.6.1. AOP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 4.7. Werkzeuge für den JBoss Application Server . . . . . . . . . . . . . . . . 92 4.7.1. Ant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 4.7.2. XDoclet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 4.7.3. Entwickler-Werkzeuge für die JBoss-Plattform . . . . . . . . . . . 95 4.7.4. Integrierte Entwicklungsumgebungen . . . . . . . . . . . . . . . . 97 4.8. Vergleich zwischen J2EE-Application-Servern . . . . . . . . . . . . . . . . 98 4.8.1. JOnAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 4.8.2. Oracle 10g und Orion Application Server . . . . . . . . . . . . . . 100 4.8.3. BEA WebLogic 8.1 . . . . . . . . . . . . . . . . . . . . . . . . . . 102 4.8.4. IBM WebSphere . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 4.9. Fazit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 5. Referenz-Anwendung 107 5.1. Zielsetzung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 5.2. Anwendungsfälle - UML . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 5.3. Aufbau, Architektur und Entwurfsmuster . . . . . . . . . . . . . . . . . . 109 5.3.1. Multitier-Anwendung . . . . . . . . . . . . . . . . . . . . . . . . 110 5.3.2. Entwurfsmuster: MVC 2 - Web . . . . . . . . . . . . . . . . . . . 111 5.3.3. Entwurfsmuster: Session-Fassade . . . . . . . . . . . . . . . . . . 113 5.3.4. Entwurfsmuster: DTO Data Transfer Object . . . . . . . . . . . . . 114 5.3.5. Entwurfsmuster: UUID . . . . . . . . . . . . . . . . . . . . . . . . 115 5.4. Backend der Anwendung . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 5.4.1. Datenmodell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 5.5. Web-Anwendung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 5.5.1. Aufbau und Architektur der Anwendung . . . . . . . . . . . . . . 119 viii Inhaltsverzeichnis 5.5.2. Web-Benutzer-Interface . . . . . . . . . . . . . . . . . . . . . . . 122 5.5.3. Konfiguration der Anwendung . . . . . . . . . . . . . . . . . . . . 123 5.6. Administrator-Anwendung . . . . . . . . . . . . . . . . . . . . . . . . . . 124 5.6.1. Architektur der Administrator-Anwendung . . . . . . . . . . . . . 125 5.6.2. Verbindung mit JBoss . . . . . . . . . . . . . . . . . . . . . . . . 126 5.7. WAP-Frontend . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 6. Zusammenfassung und Ausblick 129 6.1. Zukunftsprognose . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 6.2. Einsatzmöglichkeiten der entwickelten Anwendung . . . . . . . . . . . . . 131 6.2.1. Notwendige Erweiterungen für einen produktiven Einsatz . . . . . 131 6.2.2. Die Anwendung als Beispiel zur Erstellung von J2EE Applikationen 132 6.3. Fazit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 A. Anhang 135 A.1. Servlet und JavaServer Pages . . . . . . . . . . . . . . . . . . . . . . . . . 135 A.1.1. Servlets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135 A.1.2. JavaServer Pages . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 A.2. Deployment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 A.3. JBoss Management Konsole . . . . . . . . . . . . . . . . . . . . . . . . . 140 A.4. Datenmodell der Referenzanwendung . . . . . . . . . . . . . . . . . . . . 141 A.5. Konfiguration der Web-Anwendung . . . . . . . . . . . . . . . . . . . . . 142 A.6. Inhalt der CD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 Abbildungsverzeichnis 149 Tabellenverzeichnis 151 Quelltextverzeichnis 153 Listings 153 Literaturverzeichnis 155 Selbstständigkeitserklärung 159 1. Einleitung Durch zunehmende Globalisierung und gemeinschaftliches Arbeiten bei räumlicher Trennung gewinnt die Vernetzung von Unternehmensanwendungen immer mehr an Bedeutung. Das World Wide Web ermöglicht den Zugriff auf die Daten von Unternehmen. Um dieser Entwicklung gerecht werden zu können ist es notwendig, Konzepte für eine Infrastruktur zu schaffen, welche die dabei auftretenden Probleme beherrschbar macht. Dieser Herausforderung stellen sich Unternehmen wie Sun Microsystems oder Microsoft. In dieser Arbeit soll auf die von Sun eingeführte, Java 2 Platform, Enterprise Edition (J2EE) eingegangen werden. Um deren Vorteile nutzen zu können, wird ein Application-Server verwendet, welcher die benötigten Dienste bereitstellt. In der vorliegenden Diplomarbeit soll eine Evaluation des Open-Source-Projekt JBoss Application Server durchgeführt werden, dabei wird JBoss auch kommerziellen Produkten gegenübergestellt. Ziel ist es, dem Leser sowohl ein Verständnis für das Erstellen von Anwendungssoftware auf Basis von J2EE zu vermitteln, als auch den JBoss Application Server detailliert und kritisch zu untersuchen. 1.1. Thematik und Aufbau der Arbeit Diese Arbeit beschäftigt sich mit der Erstellung einer Referenzimplementierung für den JBoss Application-Server. In diesem Zusammenhang wird in die Grundlagen für die Erstellung von komponentenbasierten Systemen auf J2EE-Basis eingeführt, einige „best practises“ in Form von Entwurfsmustern (Pattern) vorgestellt und Quellcodebeispiele zur Veranschaulichung angeführt. Der zweite Schwerpunkt dieser Arbeit befasst sich mit Application-Servern, speziell mit dem JBoss. Dabei wird der JBoss genau untersucht und seine Konfiguration erläutert. Um den JBoss Application Server im Markt einordnen zu können, wird ein kurzer Vergleich mit 2 1. Einleitung den Konkurenzprodukten durchgeführt. Es soll gezeigt werden, welche Kriterien für den Einsatz eines Application-Server sprechen und was beim Einsatz zu beachten ist. 1.2. Motivation JBoss ist ein Open-Source Application-Servern für J2EE Anwendungen. Dadurch ist er sowohl für kosteneffizient arbeitende kleinere Unternehmen interessant, die ihn kostenlos einsetzen können als auch für große Unternehmen, die in der Verfügbarkeit des Quellcodes mehr Sicherheit für ihr Unternehmen erkennen. Durch seine große Entwicklergemeinde, die als JBoss Group gemeinsam das Projekt vorantreiben, gehört er zu den sich am schnellsten weiterentwickelnden Application-Servern. Durch den Einsatz neuester Technologien gehen vom JBoss immer wieder Impulse aus, die ihn besonders interessant für die Untersuchung machen. 1.3. Aufgabenstellung Die Aufgabenstellung umfasst sowohl die Erstellung einer Referenzimplementierung auf Basis des JBoss als auch die genaue Untersuchung des JBoss Application Servers. Das zu entwickelnde Programm stellt ein Beispiel für J2EE-Anwendungen dar. Sie soll nicht den Anforderungen eines Produktivsystems gerecht werden, sondern vielmehr als Studienobjekt Entwickler bei der Erstellung von J2EE-Anwendungen und dem Betrieb des JBoss Application Server unterstützen. 2. Theoretische Grundlagen Die Basis für komplexe Anwendungen im J2EE1 -Bereich bildet die Programmiersprache Java2 , auf der die Enterprise Edition aufbaut. Im Rahmen dieser Diplomarbeit kann keine vollständige Einführung in die Softwareentwicklung mit Java gegeben werden. Vielmehr geht es um die Vermittlung von Konzepten, die bei der Entwicklung von J2EE-Applikationen Verwendung finden. Weitere wichtige Grundlagen stellen die Auszeichnungssprache XML3 und die DatenbankAnfragesprache SQL4 dar. In welchem Zusammenhang sie mit der Entwicklung von Enterprise Systemen stehen, wird im ersten Abschnitt dieses Kapitels veranschaulicht. Der daran anschließende Abschnitt „Verteilte Anwendungen“ geht tiefer auf die Programmierung mit der Java 2 Enterprise Edition ein. Es soll ein Überblick über die verfügbaren Komponenten der J2EE gegeben und diese mit anderen Modellen verglichen werden. Den Abschluss des Kapitels bildet der Abschnitt „Softwareentwicklung für komponentenbasierte Systeme“. Hier wird auf das Softwareengineering bei J2EE Anwendungen eingegangen und es werden Standards vorgestellt, die diesen Prozess unterstützen. 2.1. Einführung in plattformunabhängige Programmierung Unter Plattformunabhängigkeit versteht man die Unabhängigkeit einer entwickelten Software von einer spezifischen Zielplattform. In die Betrachtung müssen dabei sowohl die Hardware als auch die verwendeten Betriebssysteme einbezogen werden. Unter anderem ist dabei sicherzustellen, dass alle Datentypen den gleichen Wertebereich ausschöpfen z. B. 1 Java 2 Platform, Enterprise Edition Java ist eingetragenes Markenzeichen der Sun Microsystems Cooperation 3 Extensible Markup Language 4 Structured Query Language 2 4 2. Theoretische Grundlagen ist der Integer-Wertebereich maschinenabhängig. Eine weitere Anpassung bezieht sich auf die Haltung von Daten im Hauptspeicher. Dieser kann als „Big-Endian“ oder „Little-Endian“ organisiert sein. Dabei bedeutet Big-Endian, dass die Bytes in einer Speicherzelle vom höchstwertigen Byte links zum niederwertigsten Byte rechts angeordnet werden. Beim „Little-Endian“-Format, welches hauptsächlich von Intel bevorzugt wird, steht das niederwertigste Byte links, das höchstwertige Byte rechts [Cur94]. Auch der Zugriff und Austausch von Daten muss geregelt werden. Immer häufiger kommt daher eine Datenaustauschsprache zum Einsatz, die öffentlich spezifiziert wurde - XML. Auch offen gelegte Standards bei Netzwerkprotokollen helfen hier Plattformunabhängigkeit zu erreichen. Um dieses Konzept zu verwirklichen ist es erforderlich, eine Vermittlerinstanz (Middleware) zwischen den Programmcode und die Zielplattform zu schalten. Mit einer solchen Middleware kann z. B. ein Java-Programm mit einem in COBOL5 implementierten Programm auf einem Mainframe kommunizieren. Hierbei könnte z. B. CORBA6 als Middleware eingesetzt werden. Ein gutes Beispiel für offene Protokolle zur Kommunikation findet man u. a. bei den WebServices. Hier wird mittels SOAP7 und einer Servicebeschreibung in XML der Zugang zu Programmen unterschiedlicher Programmiersprachen und Systeme hergestellt. Ein weiterer Ansatz, der bei portablen Programmen unterschiedlicher Sprachen zum Einsatz kommt, ist eine Laufzeitumgebung, wie sie bei der Sprache Java oder der .NET-Sprachfamilie zu finden sind. Diese Sprachen nennt man interpretierte Programmiersprachen. Im Fall von Java wird kein nativer Code erzeugt, sondern Bytecode, der von der JVM8 interpretiert wird. Das hat den Vorteil, dass man Programmcode auf jedem Rechner, für den eine JVM verfügbar ist, ohne Änderungen ausführen kann. Dieses Prinzip nennt Sun „Write Once, Run Anywhere“. 2.1.1. Die Java-Plattform Als Sun 1995 die Programmiersprache Java veröffentlichte, wuchs deren Verbreitung mit der gleichzeitig wachsenden Popularität des Internets. Java setzte sich zum Ziel, die unterschiedlichsten Hard- und Softwareplattformen in der Art zu vereinen, dass Java-Programme ohne Codeanpassungen überall dort lauffähig sind, wo eine JVM installiert ist. 5 Common Business Oriented Language Common Object Request Broker Architecture 7 Simple Object Access Protocol 8 Java Virtual Maschine 6 2. Theoretische Grundlagen 5 Die ersten Java-Programme waren Applets, die in Browsern ausgeführt und von einem Server bei Bedarf geladen wurden. Der Vorteil dieser Programme war, dass eine Oberfläche für dynamische Interaktion von Webseiten mit deren Benutzern geschaffen wurde. Oftmals wurden mit Applets jedoch auch einfach nur Webseiten, z. B. durch animierte Logos, aufgewertet. Die Benutzer dieser Programme können sicher sein, dass diese keinen Schaden verursachen. Java-Applets laufen in der sogenannten Sandbox ab. Das heißt, dass sie nicht auf Systemressourcen zugreifen können. Aufgrund der Applet-Technologie wird Java oft als die Sprache des Internets bezeichnet. Doch die Java-Plattform kann weitaus mehr und entwickelt sich in rasantem Tempo weiter. Durch die Auslegung Javas als objektorientierte Programmiersprache mit einer Vielzahl von APIs9 , z. B. für Netzwerkprogrammierung und Sicherheit, wurde Java unter anderem auch für Serverprogrammierung interessant. Der eigentliche Durchbruch auf diesem Gebiet gelang Sun mit der Spezifikation von J2EE mit den Teilspezifikationen der Servlets und JavaServer Pages (vgl. A.1) sowie der Enterprise JavaBeans (EJB), die in Kapitel 3 beschrieben werden. Die Plattformunabhängigkeit half dabei der Marktdurchdringung, so dass Java eine der am häufigsten verwendeten Programmiersprachen ist. TM JavaBeans Applets EJBs JSPs Servlets Transactions EJB Container Messaging Java CORBA TM 2 SDK, Standard Edition RMI Database Naming/Directory Java Virtual Maschine Hardware Platform Abb. 2.1: Java und J2EE Quelle: [SM97] 9 Mail Application Programming Interface Connectors Application Programming Interface Tools 6 2. Theoretische Grundlagen Plattformunabhängigkeit - Portabilität Erreicht wurde die Plattformunabhängigkeit Javas durch einen Zwischenschritt bei der Übersetzung des Quelltextes in einen lauffähigen Code. Statt eines Compilers, der Programme in Maschinensprache übersetzt und so lauffähig macht, übersetzt der Java Compiler das Programm in einen maschinenunabhängigen Bytecode. Dieser kann dann in einer virtuellen Maschine ausgeführt werden. Sun bzw. deren Tochterunternehmen JavaSoft sorgen dafür, dass für die meisten Hard- und Softwareplattformen eine solche JVM verfügbar ist. Dieses Konzept orientierte sich am aktuellen Bedarf. In einer heterogenen Landschaft wie dem Internet gab es nun die Möglichkeit, Software nicht mehr für eine bestimmte Plattform zu entwickeln, sondern für einen definierten Benutzerkreis. Doch nicht nur reine Java-Programme und Applets sind portabel, auch andere Komponenten die in Java entwickelt wurden, so z. B. die Enterprise JavaBeans der J2EE-Spezifikation. Diese sind ohne Javacode-Anpassungen zwischen den Application-Servern unterschiedlicher Hersteller austauschbar. Geringfügige Anpassungen, die bei solch komplexen Softwaresystemen notwendig sind, werden mittels XML-Dateien konfiguriert. Diese sind ebenfalls durch ihre Repräsentation als reiner Text auf jeder Plattform bearbeitbar. Solche Anpassungen sind einfach und weniger fehlerträchtig, als die Portierung eines in C++ geschriebenen Softwaresystems von Windows auf z. B. Linux. Die Portabilität aller Bestandteile der Java-Plattform lässt Entwickler aus einer Vielzahl möglicher Implementierungsvarianten auswählen, wodurch besser skalierbare und individueller zugeschnittene Softwaresysteme entstehen können. Die Entwicklung der Plattformunabhängigkeit geht jedoch weiter und betrifft nicht nur die Java Softwareentwicklung. Durch die Einführung von WebServices ist mittlerweile die Interoperabilität zwischen sehr unterschiedlichen Rechner-Architekturen möglich, selbst wenn der WebService von einem Programm einer anderen Programmiersprache zur Verfügung gestellt wird. Konzepte der Sprache Die Eigenschaften Javas, wie Dynamik, Robustheit und Sicherheit, ließen aus der vermeintlichen Internetsprache schnell eine universell einsetzbare Programmiersprache werden. 2. Theoretische Grundlagen 7 Die Objektorientierung veränderte die Art der Softwareentwicklung. Das Modellieren von komplexen Objekten entspricht viel eher der Art, wie Menschen ihre Umgebung wahrnehmen. Dieses Programmierparadigma kann als Grundlage für das neue Konzept der komponentenorientierten Softwareentwicklung angesehen werden. Hierbei wird noch weiter generalisiert ohne die Möglichkeit zu verlieren, detailgenaue Abbildungen der Wirklichkeit zu schaffen. Als völlig neu entwickelte Sprache konnte sich Java auch von einigen in anderen Sprachen existierenden Konzepten lösen, die sowohl in der Entwicklung als auch im Betrieb eines Programms zu Fehlern führen können. Konzepte, die nicht in Java aufgenommen wurden, sind unter anderen die aus der Sprache C und C++ bekannte Zeigerarithmetik, die Mehrfachvererbung oder auch die goto-Anweisung, um nur einige wichtige zu nennen [Krü02]. Das Weglassen dieser Eigenschaften hatte jedoch außer einer Umgewöhnung für Umsteiger aus anderen Sprachen mehr Vor- als Nachteile. Java ist um einige Syntaxelemente ärmer als z. B. C++ und deshalb leichter zu erlernen, zum anderen ist die Sprache dadurch stabiler. Alle Speicherzugriffe werden von der JVM durchgeführt. Hierbei tritt auch der Garbage Collector als eine wichtige Eigenschaft von Java auf. Wo C-Programmierer noch selbst dafür sorgen mussten Speicher freizugeben, läuft in Java in gewissen Zeitabständen der Garbage Collector als Prozess. Dieser sucht nach nicht referenzierten Java-Objekten. Wenn ein solches Objekt gefunden wurde, wird der belegte Speicherplatz wieder freigegeben bzw. die finalize-Methode aufgerufen. Ein Absturz eines Javaprogramms, das Auftreten eines Nullpointers oder eine andere Ausnahme wird durch die Ausnahmebehandlung10 der JVM verarbeitet und, wenn nötig, die fehlerhafte Anwendung kontrolliert beendet. Die Ausnahmebehandlung trägt jedoch nicht nur durch das Abfangen von Fehlern zur Stabilität bei. Durch diesen Mechanismus ist es auch leichter, Fehler im Programmcode während der Entwicklung zu finden und so entsprechend auszuschließen. Dies führt dazu, dass die Programme fehlerfreier und fehlertoleranter sind. Das Sicherheitskonzept von Java ist dafür zuständig, dass Programme und Daten nicht kompromittiert oder von Unbefugten gelesen werden können. Zugriffe auf Daten und Ressour10 Exceptionhandling 8 2. Theoretische Grundlagen cen werden nur autorisierten Personen gestattet. Dieses Sicherheitskonzept wird zusätzlich durch die Java Cryptographic API unterstützt, die die Verschlüsselung jeglicher Daten ermöglicht. Der Java Security Manager sorgt für die Verwaltung von Zugriffsrechten. Dabei kann er eingesetzt werden, um z. B. den Zugriff auf das Netzwerk oder auf bestimmte Dateien zu verhindern. Der Security Manager arbeitet mit einer Positivliste: alles was nicht erlaubt ist, ist verboten. Um den Security Manager einzusetzen, muss das Programm jedoch mit der entsprechenden Option gestartet werden [Ull03]. Applets benutzen grundsätzlich den Security Manager, der vom Browser beim Start der JVM aktiviert wird. Da Java durch die Möglichkeit, Programmteile bei Bedarf nachzuladen, sehr oft in verteilten Systemen eingesetzt wird, gibt es auch einen Mechanismus, um Programm-Pakete zu signieren. Die Dateien, die dabei meist übertragen werden, sind JARs11 . Dies hilft dem Empfänger zu überprüfen, wessen Programmteil er empfängt, und gibt ihm die Sicherheit, dass auf dem Weg durch das Netzwerk der Bytecode nicht manipuliert wurde. 2.1.2. XML als plattformunabhängiges Datenformat Die Extensible Markup Language (XML) entstand aus der Standard Generalized Markup Language (SGML), einem ISO-Standard12 . Nachdem SGML nicht die gewünschte Akzeptanz fand, begann das W3C (World Wide Web Consortium) unter Mitwirkung der Industrie einen neuen Standard zu entwickeln. XML wurde sehr schnell in der Industrie angenommen und fand eine enorm schnelle Verbreitung. Zum Ziel gesetzt hatte sich das W3C, einen Sprach-Standard zu etablieren, der es ermöglicht, Daten zu strukturieren und über das Internet auszutauschen. Ursprünglich war XML dazu gedacht, elektronische Publikationen zu unterstützen und so das Design von der Darstellung zu lösen (nach [Qui04]). Durch den allgemeinen Charakter von XML lassen sich fast beliebige Daten darstellen und auch andere Auszeichnungssprachen wie HTML13 oder auch SVG14 damit beschreiben. Es wird jedoch noch lange dauern bis sich reine oder generierte HTML-Seiten vollständig durch XML11 Java Archives International Organisation for Standardization 13 Hypertext Markup Language 14 Scalable Vector Graphics 12 2. Theoretische Grundlagen 9 Seiten ersetzen lassen, die mit Hilfe von XSLT15 zum gewünschten Dokument umgeformt werden. In XML verfasste Dokumente unterliegen den Richtlinien der XML-Spezifikation [Qui04]. Zum einen müssen XML-Dokumente wohlgeformt sein, das heißt, dass jedes geöffnete Tag16 auch durch einen „ / “ oder ein schließendes Tag terminiert werden. Tags können ineinander verschachtelt werden, wenn deren Reihenfolge dabei konsistent bleibt. Eine restriktivere Einschränkung stellt die Gültigkeit eines XML-Dokuments dar. Ein XML-Dokument ist genau dann gültig, wenn es eine DTD17 referenziert und der darin beschriebenen Grammatik entspricht. Der folgende XML Codeabschnitt zeigt ein Beispiel der Datei jboss-web.xml eines speziellen Deployment-Deskriptors des JBoss Servers (vgl. Kapitel 3). Dieses Dokument ist wohlgeformt, da öffnende Tags in korrekter Weise geschlossen werden. In der ersten Zeile wird für das Dokument der Zeichensatz angegeben, hier UTF-818 . Danach wurde, mit der Angabe der DTD, der Document-Type festgelegt, der unter der angegebenen URL19 zu finden ist. Listing 2.1: jboss-web.xml 1 2 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE jboss-web PUBLIC "-//JBoss//DTD Web Application 2.3V2// EN" "http://www.jboss.org/j2ee/dtd/jboss-web_3_2.dtd"> 3 4 5 6 <jboss-web> <security-domain>java:/jaas/myJBossSec</security-domain> </jboss-web> Bei J2EE-Anwendungen werden seit EJB 2.0 XML-Dateien zur Konfiguration eingesetzt. In früheren EJB-Versionen wurden zu diesem Zweck noch serialisierte Java-Objekte benutzt. Durch die einfachere Verarbeitung von XML lassen sich so leichter Anpassungen an den EJBs vornehmen. Auch der JBoss-Server wird mit XML-Dateien konfiguriert. Alle 15 eXtensible Stylesheet Language Transformation, Eine Sprache zur Formatierung von XML Dokumenten engl. Markierung 17 Document Type Definition 18 Unicode Transformation Format, 8-bit kodierte Form 19 Uniform Resource Locator 16 10 2. Theoretische Grundlagen Einstellungen, die die angebotenen Dienste betreffen, werden in einer der Konfigurationsdateien vorgeschrieben. Auf diese Dateien wird in Kapitel 4.5 genauer eingegangen. 2.1.3. SQL, die Standard-Datenbank-Anfragesprache Die Structured Query Language (SQL) ist die Standard-Anfragesprache für relationale Datenbanksysteme. Sie vereinigt in sich die verschiedenen Sprachen, die bei einem RDBMS20 benötigt werden [HS00]: • Data Definition Language (DDL) • Data Manipulation Language (DML) • View Definition Language (VDL) • Storage Definition Language (SDL) Die Grundlagen der Sprache wurden bereits 1974 und 1976 von IBM durch die Entwicklung der Sprachen SEQUEL21 und SEQUEL2 gelegt. SQL entstand in den folgenden Jahren durch Datenbankhersteller wie Oracle. Im Jahr 1986 wurde SQL dann zum ANSI22 -Standard. Durch die International Standard Organisation (ISO) wurde 1989 SQL-89 und 1992 SQL-92 standardisiert. Mit SQL-99 wurde SQL dann zu einer objektrelationalen Datenbanksprache. Relationale Datenbanksysteme beherrschen zur Zeit den Markt, obwohl objektrelationale und objektorientierte Datenbanksysteme eine Zeit lang immer mehr Marktanteile beanspruchten. Der Trend zur objektorientierten Datenbank wurde durch den Einsatz der sogenannten Objektrelationalen Mapper gebremst (vgl. Kapitel 3.3.3). Durch die lange Tradition des Relationen-Modells ist die damit verbundene SQL jedoch nicht aus der Datenbankwelt wegzudenken. Die Verwendung von SQL in objektorientierten Systemen führt jedoch zum Impedance Mismatch, dem Bruch zwischen der Programmier- und Datenzugriffssprache. In den heutigen Zugriffsschichten für Datenbanksysteme aus objektorientierten Welten werden meist SQL-Statements generiert, um den Impedance Mismatch vor dem Nutzer zu verbergen. Um den Übergang zu objektorientierten Datenbanken zu erleichtern bietet z.B. die 20 Relational Database Management System Structured English Query Language 22 American National Standard Institute 21 2. Theoretische Grundlagen 11 postrelationale Datenbank Caché die Möglichkeit, auch mit SQL Daten zu manipulieren, zu definieren oder Anfragen zu stellen. Im J2EE-Umfeld wird häufig eine relationale Datenbank für die Persistenz der Daten eingesetzt. Auch hier werden SQL-Statements erzeugt. Bei der Container Managed Persistence (CMP) wird dem Programmierer mit EJB-QL (vgl. Kapitel 3.3.2) eine auf der SQL-Syntax basierende Anfragesprache zur Verfügung gestellt, mit der Objekte aus Datensätzen des RDBMS erzeugt werden können. Die Bedeutung von SQL lässt sich an diesen Beispielen gut erkennen. Selbst völlig neue Ansätze zur Speicherung von Daten greifen auf SQL zu oder bieten eine Anfragesprache, die sich an SQL orientiert. 2.2. Verteilte Anwendungen In einem heterogenen Umfeld mit ständig wachsendem Bedarf an Rechenleistung, Speichergrösse und immer kürzeren Antwortzeiten wird das Konzept des Grossrechners zunehmend durch verteilte Systeme ersetzt. Diese Systeme haben einige entscheidende Vorteile [TS03]: • Benutzertransparenz: Ein verteiltes System fühlt sich für den Benutzer an, wie ein einzelner leistungsfähiger Computer. • Kosten: Rechenleistung im PC-Bereich wird immer günstiger. Durch den Zusammenschluss vieler günstiger Systeme ist die Rechenleistung eines Grossrechners zu einem wesentlich geringeren Preis zu verwirklichen. • Erweiterbarkeit: Bei Leistungsengpässen und schwindenden Reserven von Speicherplatz oder anderen Betriebsmitteln können neue Systeme an das verteilte System angeschlossen werden, um die Leistung weiter zu steigern. • Spezialisierung: Komponenten einer Software können so verteilt werden, das sie auf dem Rechner im verteilten System ablaufen, der ihnen die bestmögliche Leistung gewährleistet. • Ausfallsicherheit: Bei einem verteilten System soll der Ausfall einer Komponente nicht das gesamte System beeinträchtigen. 12 2. Theoretische Grundlagen Die im folgenden aufgeführten Nachteile hingegen lassen sich durch sorgfältige Planung relativieren. Verteilte Systeme sind abhängig vom Verbindungsnetzwerk. Wenn die Netzwerkkomponenten unzuverlässig arbeiten, wird das Gesamtsystem beeinträchtigt. Die fortschreitende Entwicklung in der Netzwerktechnik verringert jedoch dieses Problem immer weiter. Eine weitere Aufgabe ist es, ein solches System gegen Angriffe von außen zu schützen. Es werden mehr Punkte zur Kompromittierung angeboten; die Chance, ein Sicherheitsloch zu finden, steigt. Bei verteilten Systemen, die in einem Intranet genutzt werden, um eine hohe Rechenleistung zu erbringen ist dieses Problem geringer, als beim verteilten Rechnen z. B. im Internet. Hier lassen sich aber durch virtuelle private Netzwerke (VPN) die Risiken von ungewolltem Mitlesen und Verändern des Datenverkehrs minimieren. Der Einsatz von Firewalls und Intrusion Detection Systemen (IDS) schützt vor Einbrüchen in die Systeme und gehört mittlerweile zum Standard in Firmen- und oft auch in Heimnetzwerken. Ein weiteres Problem liegt in der Komplexität der Verwaltung eines solchen Systems. Die Software, die die Vorteile von verteilten Systemen nutzen soll, ist wesentlich komplizierter zu entwickeln, als die für monolithische Systeme. Es gibt jedoch Rahmenwerke (Frameworks), die den Entwickler hierbei unterstützen. Im Bereich der Application-Server bieten die Serverhersteller oftmals schon die Möglichkeit zur Verteilung der Last auf mehrere Application-Server. Das so genannte Clustering bietet hierbei die Vorteile von verteilten Systemen ohne grösseren Aufwand. Software die für J2EE entwickelt wird, ist ohne große Änderungen auch in einem Cluster einsetzbar. Auf das Verteilen von Komponenten und Last wird im folgenden Abschnitt eingegangen. In Kapitel 4.2.5 wird am Beispiel des JBoss die Konfiguration eines Clusters erläutert. 2.2.1. Komponenten „Jeder Teil einer Software wurde schon einmal implementiert, aber noch nicht von jedem.“ [Quelle: unbekannt] Die objektorientierte Software-Entwicklung ist erprobt und hat ihre Stärken und Schwächen offenbart. Es wurde nach Lösungsansätzen gesucht, um die Wiederverwendbarkeit von Programmteilen zu erhöhen. Dabei hat sich auch gezeigt, dass Klassen und Objekte zu feingranular sind, um den Softwareentwicklungszyklus weiter zu beschleunigen. Oftmals werden in unterschiedlichen Softwaresystemen ähnliche Programmteile benötigt, wie z. B. 2. Theoretische Grundlagen 13 ein Datenbankzugang oder eine Benutzerverwaltung. Solch ein Programmteil besteht in der Regel jedoch aus mehreren Klassen. In Java werden solche Teilsysteme zu Paketen, den so genannten „Packages“ zusammengefasst. Um diese Programmteile einfach wiederverwenden zu können, ist es notwendig, aus solchen Paketen Komponenten zu erzeugen. Der Begriff Komponente kann wie folgt definiert werden: „Ein Halbfabrikat bzw. eine Komponente (componentware) ist also ein abgeschlossener, binärer Software-Baustein, der eine anwendungsorientierte, semantisch zusammengehörende Funktionalität besitzt, die nach außen über Schnittstellen zur Verfügung gestellt wird.“ [Bal00] Eine Komponente kann also aus einer Vielzahl von Klassen bestehen, deren Funktionalität über eine Schnittstelle bereitgestellt wird. Dadurch ist es auch möglich, dass viele Komponenten miteinander interagieren können. Da Komponenten mit dem Ziel der Wiederverwendung entwickelt werden, ist es notwendig, dass alle Funktionen und Schnittstellen der Komponente ausreichend beschrieben und getestet werden. Eine Komponente sollte klein genug sein, um sie leicht warten und herstellen und in einer Vielzahl von Systemen integrieren zu können. Sie soll aber einen Funktionsumfang bieten, der gross genug ist, um einen Vorteil durch ihre Integration zu erhalten. (vgl. [SDD02] und [DP02]). Der Einsatz einer fertigen Komponente orientiert sich am so genannten „Blackbox Prinzip“. Das bedeutet, dass für den Einsatz und die Integration der Komponente nicht der Quelltext bzw. die Implementierungsdetails offen liegen müssen, sondern dass anhand der Schnittstellen und Funktionsbeschreibung eine Integration erfolgt. Durch das Komponenten-Paradigma lassen sich grössere Softwaresysteme effizienter zusammenstellen und entwickeln. Bei Software-Entwicklern, welche an verschiedenen Standorten arbeiten, ist eine solche Architektur notwendig. So kann jeder einen Teil der Software entwickeln, welcher der Schnittstellen- und Funktionsbeschreibung entspricht. Komponenten steigern die Qualität einer Software. Durch gut getestete Komponenten treten weniger Fehler auf und die Komplexität bei der Fehlersuche wird verringert. Wenn eine Komponente fehlerhaft ist, kann diese überprüft und berichtigt werden. Auch ist es wesentlich einfacher, neue Technologien in Komponenten-Software zu integrieren. Wenn 14 2. Theoretische Grundlagen eine Komponente ein Refactoring23 durchläuft, kann festgestellt werden, ob sie die neuesten Entwurfsmuster verwendet. Ist dies nicht der Fall, kann sie aufgrund ihrer geringeren Größe leichter auf den aktuellsten Stand der Softwaretechnik gebracht werden. Komponenten in Geschäftsanwendungen In verteilten Softwaresystemen gibt es eine Reihe von immer wieder auftretenden Anforderungen, die durch den Einsatz von Komponentenmodellen erfüllt werden können. In heutigen Unternehmensanwendungen steht meist eine Datenbank zur Verfügung, die Geschäftsdaten (Entitäten) enthält. Programme oder Programmteile arbeiten auf der Basis dieser Daten. Oftmals sind sowohl die Daten, als auch die Geschäftsprozesse über ein Netzwerk miteinander verbunden. Die Änderungen an den Geschäftsdaten werden mit Hilfe von Transaktionen (vgl. 3.6) gesichert und die Daten der Anwendung werden dem Nutzer ansprechend visualisiert. Man spricht hierbei von mehrschichtigen Systemen. Moderne Anwendungen werden immer vielschichtiger. Die ehemaligen 2-Schichtsysteme (Client-Server-Systeme) werden durch 3bis n-Schichtsysteme ersetzt. Server Client Browser/GUI Logik zur Darstellung der Daten ion ikat P mun r HTT Kom I ode M R . B . z Client Kommunikation Geschäftslogik Datenzugriff r übe ion ikat rotokoll P mun Kom bartes in e ver Datenbank Abb. 2.2: Beispiel einer Mehrschicht-Architektur Dabei gibt es meistens eine Präsentations-, eine so genannte Geschäftslogik- und eine Datenhaltungs-Schicht. Die drei Hauptschichten sind oft auch physikalisch voneinander abgegrenzt. Das Schichtenmodell durchzieht jedoch auch die Anwendungen innerhalb der 23 Das Untersuchen, Verbessern und ggf. Neuimplementieren von Quelltexten, ohne dessenderen Semantik zu verändern. 2. Theoretische Grundlagen 15 physikalischen Schichten. Bei speziellen Anforderungen kann die Anzahl der Schichten um weitere ergänzt werden. Intern sind sie oft stark gekoppelt; zu ihren korrespondierenden Schichten besteht eine schwächere Bindung. So ist der Austausch einer Schicht durch eine andere mit entsprechenden Schnittstellen möglich. Das Komponenten-Paradigma entfaltet hier sein Potential. So ist es durch eine Analyse möglich, Komponenten in bestehenden oder neu zu entwickelnden Anwendungen zu finden. Komponenten können sowohl die einzelnen Schichten der Anwendung darstellen als auch bestimmte funktionale Aspekte, wie z. B. Logging, Netzwerkverbindungen oder Sicherheit. Bei diesen funktionalen Anforderungen ist eine weitere Abstraktion, durch die aspektorientierte Programmierung möglich, die in Kapitel 4.6.1 vorgestellt wird. Die heutigen Geschäftsanwendungen verwenden zumeist einen Application-Server, der die technischen Anforderungen eines Softwaresystems umsetzt, während die funktionalen Teile des Systems von Entwicklern individuell erstellt werden. Man spricht dabei von einer Trennung der Zuständigkeiten („separation of concerns“). Die Application-Server bieten eine Ablaufumgebung (auch Container genannt) für die funktionalen Bestandteile des Softwaresystems. Sie bieten Dienste an, die in allen Geschäftsanwendungen gleichermaßen auftreten. So z. B. Transaktionen, Sicherheitsrichtlinien, Zugriff auf Datenquellen (EIS24 ) und Laufzeitverwaltung der installierten Anwendungen. 2.2.2. Komponentenmodelle in Java Da Komponenten und Objekte viele Gemeinsamkeiten haben, definiert Java mehrere Komponentenmodelle. Der erste Ansatz zu Komponenten ist bei den Applets zu finden. Diese kann man als GUI25 -Komponenten in Webseiten betrachten. Applets sind keine Programme und sind nicht eigenständig ausführbar. Ein Applet wird immer in einer Ablaufumgebung, also einem Container, ausgeführt. Dieser Container kann sowohl ein Webbrowser als auch ein Applet-Viewer sein. Der Container überwacht unter anderem die Rechte des Applets (Sandbox-Prinzip) und dessen Lebenszyklus. Die Darstellung eines Applets ist immer eine vom Applet implementierte GUI. Applets werden von java.applet.Applet abgeleitet. Komponenten sind wiederverwendbare Softwarebausteine (vgl. 2.2.1), die über Schnittstel24 25 Enterprise Information System Graphical User Interface 16 2. Theoretische Grundlagen len Funktionen bereitstellen. Applets können aus einer Reihe von Klassen bestehen, die selbst Funktionseinheiten innerhalb des Applet-Programms darstellen. Applets können also selbst ebenfalls aus Komponenten bestehen. Dabei kann man die visuelle Komponente des Applets von seinen funktionalen Komponenten trennen. Applets können also aus Komponenten zusammengesetzt sein und Teil anderer komponentenbasierter Systeme werden. Die Portabilität ist durch die Sprache Java gewährleistet. Es ist leicht, Komponenten eines Applets in anderen Programmen wiederzuverwenden. Ein ganzes Applet ist jedoch nur komplett als Komponente einer anderen Webseite wiederverwendbar. Ebenso ist die Anzahl der Schnittstellen die ein Applet hat sehr begrenzt. Es kann mit JavaScript26 und dem Benutzer interagieren sowie auf Programm-Ereignisse und Lebenszyklusmethoden reagieren. JavaBeans Das erste echte Komponentenmodell, das auch als solches entwickelt wurde, ist die JavaBeans-Spezifikation. Sun hat sich damit zum Ziel gesetzt, das Erstellen von Softwarebausteinen (Komponenten) für Firmen zu ermöglichen, die diese Komponenten vertreiben können, (vgl. [SM97]). Bei der Entwicklung des GUI-Frameworks Swing und AWT27 wurden von Sun selbst JavaBeans eingesetzt. Eine kurze Definition von Sun für JavaBeans lautet: „A Java Bean is a reusable software component that can be manipulated visually in a builder tool.“ [SM97] Dies zeigt nur ein kleines Spektrum der Möglichkeiten, die man mit JavaBeans hat. Um diese Definition zu erfüllen ist es notwendig, dass andere Programme JavaBeans untersuchen können. Zu diesem Zweck dient die Java Reflection-API28 . Mit den ReflectionMethoden ist es möglich, Objekte und Klassen zur Laufzeit zu untersuchen. Da alle Objekte von Object abgeleitet sind, steht ihnen die Methode getClass() zur Verfügung. Das Class-Objekt liefert Informationen zum Typ, den Konstruktoren, Methoden und Feldern ei26 in Webseiten eingebettete, von Netscape entwickelte Skript-Sprache um dynamische Inhalte zu erzeugen oder zu modifizieren 27 Abstract Windowing Toolkit, API zur Erstellung grafischer Benutzeroberflächen 28 java.lang.reflect 2. Theoretische Grundlagen 17 ner Klasse. Die Attribute einer JavaBean unterliegen wohl definierten Namens-Konventionen. So müssen die Attribute die Sichtbarkeit private definieren. Damit sind sie nicht direkt von einer anderen Klasse zugänglich. Um die Attribute einer JavaBean dennoch ändern zu können, bekommen alle Attribute, die änderbar sein sollen, ein get/set-Methoden-Paar, das als public definiert ist. Auf diese öffentlich zugänglichen Methoden können andere Klassen und Programme über die Reflection-API zugreifen. Dieser Vorgang wird Introspection genannt. Die grafischen Programme zum Editieren einer JavaBean benutzen genau diese Möglichkeit. Attribute die diese Anforderungen erfüllen, werden bei den JavaBeans „properties“ genannt. Um sicherzustellen, dass alle JavaBean-Instanzen bei ihrer Erzeugung die gleichen Eigenschaften haben, besitzen sie nur einen parameterlosen Konstruktor29 . Um die Beans anzupassen werden die Properties bearbeitet. Dieser Vorgang wird als „Customizing“ bezeichnet. JavaBeans erzeugen z. B. für jede Property ein PropertyChangeEvent bei Änderungen dieser Attribute. JavaBeans können auch eigene Events definieren, bei GUI-Komponenten sind das die AWT- oder Swing-Events. Wie in Kapitel 2.2.1 bereits beschrieben, müssen Komponenten Interfaces besitzen, die nach außen deren Fähigkeiten anzeigen. Bei den JavaBeans sind das BeanInfo und PropertyEditor. Diese Interfaces werden explizit von grafischen Editoren genutzt (z. B. Bean Development Kit von Sun), um die Beans zu bearbeiten. Die Spezifikation der JavaBeans verlangt auch, dass sie dauerhaft abgespeichert werden können. Dazu wird wie bei anderen Java-Klassen das Interface Serializable implementiert, wodurch die JavaBean in binärer Form dauerhaft speicherbar ist. Es besteht ebenso die Möglichkeit Beans über XML-Encoder/Decoder persistent zu machen. Wie bereits erwähnt, werden JavaBeans als GUI-Komponenten eingesetzt, z. B. als JButton oder auch als MenuItem. Doch außer diesen „sichtbaren“ Komponenten werden auch „unsichtbare“ JavaBeans benutzt. Letztere werden z. B. in Webanwendungen verwendet um die Programmlogik zu halten oder das Datenmodell einer Seite zu kapseln. In der Beschreibung der in dieser Diplomarbeit erstellten Anwendung im Kapitel 5.5 wird genauer auf die Verwendung von JavaBeans eingegangen. 29 Durch den Aufruf des Konstruktors wird bei eine Instanz einer Klasse erzeugt 18 2. Theoretische Grundlagen Enterprise JavaBeans An dieser Stelle wird nur kurz auf die Enterprise JavaBeans-Technologie eingegangen. Ein umfassender Überblick wird in Kapitel 3 gegeben. Die Enterprise JavaBeans sind eine serverseitige Komponententechnologie der J2EE. Um EJB nutzen zu können, ist ein Application-Server notwendig, der die Ablaufumgebung bereitstellt und den Lebenszyklus der EJB überwacht. Dieser stellt eine Vielzahl von Diensten bereit, die bei Geschäftsanwendungen notwendig sind. Diese Dienste können implizit genutzt werden und müssen nicht vom Programmierer der Komponente entwickelt werden. Zu diesen Diensten zählen z. B. die Persistenz von Entity Beans. Dieser Dienst ermöglicht die Speicherung von Geschäfts-Entitäten in einem Enterprise Information System, z. B. einer relationalen Datenbank. Dies entlastet den Entwickler und sorgt für fehlertolerantere Anwendungen, da weniger funktionaler Quelltext benötigt wird. Die Enterprise JavaBeans sind konsequent auf verteilte Systeme ausgerichtet. Sie ermöglichen über Namensdienste das Auffinden von Komponenten und Datenquellen. Dadurch ist der Einsatz von EJBs in Clustern möglich. Ein Cluster bietet verschiedene Vorteile, die in Kapitel 4.2.5 aufgezeigt werden. 2.2.3. Alternative Komponentenmodelle Die alternativen Komponentenmodelle die hier beschrieben werden sollen, sind als Konkurrenz zu den in dieser Arbeit verwendeten Java-Komponentenmodellen zu sehen. Es soll nur ein kurzer Überblick gegeben werden, um die Java-Komponentenmodelle besser einordnen zu können und vergleichbar zu machen. Der anschließende Vergleich der Komponentenmodelle ergänzt diesen Abschnitt. COM, COM+ und DCOM Das von Microsoft entwickelte Component Object Model (COM) ist bereits im Jahr 1993 entstanden. Als eines der ersten Modelle für komponentenbasierte Software und durch den Marketingdruck von Microsoft wurde es zu einer führenden Komponententechnologie. COM basiert auf „Object Linking and Embedding“ (OLE) von Microsoft, das eine Komponentenumgebung bietet, die jedoch noch nicht auf verteilte Komponenten eingeht. In den 2. Theoretische Grundlagen 19 folgenden Jahren und Betriebssystem-Versionen von Windows wurde COM vollständig integriert und bietet die Dienste, die Applikationsentwickler in Windows benötigen. Bereits damals wurden Konzepte wie Objektorientierung und Unabhängigkeit von Programmiersprachen umgesetzt. COM definiert einen Binärstandard für die erzeugten DLL-Dateien, die mit Programmiersprachen wie C++, Delphi und sogar Java erzeugt und benutzt werden können (vgl. [Sch01]) . Jedoch gab es mit COM und dem später folgenden COM+, das seit Windows 2000 eine Reihe weiterer Dienste bereitstellt, auch zahlreiche Probleme. COM fehlte die Möglichkeit Komponenten über ein Netzwerk zu verteilen. Diese Aufgabe übernahm das „Distributed Component Object Model“ (DCOM), welches die entsprechenden Dienste zur Verfügung stellte. Eine fehlende Versionskontrolle und das systemweite Registrieren der Komponenten führten zum Begriff der DLL-Hölle. Damit meint man, dass durch die Verwendung von DLLs über deren Namen geschieht, wodurch es möglich ist, dass mehrere Hersteller von Komponenten eine DLL mit gleichem Namen zur Verfügung stellten. Ebenso war es für Applikationen schwer herauszufinden, ob die Komponente die geforderte ist und in der richtigen Version vorliegt. Einer der größten Nachteile, der sich nach der Einführung und dem Erfolg von Java noch weiter verstärkte, war die Bindung an die Windows-Plattform. Das Portieren von WindowsAnwendungen, die als COM implementiert wurden, war gar nicht oder nur mit enormen Aufwand auf andere Systeme möglich. .NET Microsoft nahm sich der Problematik an und schuf .NET30 . Es wurde, basierend auf der COM und COM+ Architektur, eine Neuimplementierung vorgenommen und deren beste Eigenschaften übernommen. Auch die Konzepte, die Java so erfolgreich machen, wurden herangezogen. Als Konkurrenz zu Java und J2EE hat Microsoft mit .NET ein Framework entwickelt, das nicht wie Java/J2EE plattformunabhängig, sondern programmiersprachenunabhängig ist. Dadurch kann die Windowsplattform weiteren Ansprüchen gerecht werden. Microsoft entwickelte eine „Common Language Runtime“ (CLR) und die „Microsoft Intermediate Language“ (MSIL). Die CLR ist die Ablaufumgebung für alle .NET-fähigen Spra30 gesprochen: DOT NET 20 2. Theoretische Grundlagen chen und verwaltet deren Speicherzugriffe, Threads, Laufzeitausnahmen, Sicherheit bzw. Rechte und das Typsystem. Die CLR vereinheitlicht für alle Sprachen die Datentypen. Mit der Entwicklung der Sprache C#31 erreichte Microsoft eine große Kompatibilität zu CCode, der teilweise direkt in C# verwendet werden kann. Ebenfalls gibt es die Möglichkeit der Wiederverwendung von COM und COM+ Komponenten. Bei C++ ist es sogar möglich, „unmanaged code“ im .NET Framework ablaufen zu lassen, also Code, der weiterhin selbst das Speichermanagement und Zeigerarithmetik verwenden darf. Doch Microsoft wollte es auch Umsteigern anderer Sprachen leicht machen, ihre Programme für die .NET Plattform zu entwickeln. Dazu wurden Sprachen wie J#, VisualBasic.NET und sogar COBOL.NET und Haskell.NET entwickelt. Auch die Kombination verschiedener Sprachen innerhalb eines Assembly ist möglich. Ein Assembly ist eine Komponente in dem Sinn, dass es Schnittstellen und Metainformationen besitzt und ist eher mit JavaBeans als mit Enterprise JavaBeans zu vergleichen. Sie können zwar auch serverseitig eingesetzt werden (ASP.NET Assembly), sind jedoch kein serverseitiges Komponentenmodell. Die MSIL ist der „kleinste gemeinsame Nenner“ aller .NET-Sprachen. Da .NET programmiersprachenunabhängig ist (die Sprachen müssen der „Common Language Specification“ CLS entsprechen), müssen alle Sprachen erst in MSIL übersetzt werden. Danach werden sie vom .NET Just in Time Compiler in Maschinencode oder Assembler übersetzt. Das heißt, dass die Programme direkt auf dem Prozessor ausgeführt und nicht interpretiert werden. Microsoft hat .NET von Anfang an auf WebServices und XML ausgerichtet. So ist XML ein integraler Bestandteil des .NET Frameworks und wird in jeder Sprache unterstützt. WebServices sind für Microsoft ein wichtiger Bestandteil in .NET und dafür gedacht, mit unterschiedlichen Komponenten, verteilt im Netz, von jedem Endgerät aus, zu kommunizieren. Als Transportprotokoll wird der Standard SOAP genutzt. Damit hat Microsoft die Möglichkeit geschaffen DCOM abzulösen. DCOM kommuniziert nicht via HTTP (Port 80) und ist daher unflexibel in komplexeren Netzwerktopologien (scheitert z. B. an den meisten Firewalls). Um Marktanteile, die Java in den letzten Jahren im Bereich der Enterprise Systeme gewonnen hat, zurückzugewinnen, wurde ASP.NET entwickelt. ASP.NET ist eine Weiterentwicklung der „Active Server Pages“, die vom „Internet Information Server“ IIS bekannt sind. Hier werden die Assemblies genau wie andere Programme in MSIL übersetzt und in eine 31 C Sharp 2. Theoretische Grundlagen 21 DLL überführt, die mit Hilfe der CLR ausgeführt werden kann. Die ASP Assemblies erzeugen als Ausgabe HTML, können aber durch ihre Zugehörigkeit zur .NET Familie auch Komponenten anderer .NET-Sprachen direkt benutzen (nach [Poh03]). Microsoft liefert für die Entwicklung mit .NET die Entwicklungsumgebung Visual Studio .NET. Prinzipiell ist das .NET Framework plattformunabhängig angelegt, jedoch liefert Microsoft nur Implementierungen für die eigene Windows Produktfamilie. Mit dem MONO Projekt32 gibt es lauffähige Ansätze für die Portierung auf andere Plattformen wie Linux und Mac-OS. Jedoch sind diese bei weitem noch nicht so leistungsfähig wie .NET für Windows. Das liegt unter anderem daran, dass .NET keine klare Trennung zwischen dem .NET Framework und dem Betriebssystem geschaffen hat. Einige Dienste wie Transaktionsüberwachung werden vom Betriebssystem zur Verfügung gestellt. Auch ist .NET bisher nur in Teilen bei der ISO und ECMA33 standardisiert (nach [Gra03]). 2.2.4. Vergleich der Komponentenmodelle Der Vergleich der Komponentenmodelle von Java/J2EE und Microsoft.NET erfolgt auf der Ebene der Geschäftsanwendungen. Bei unternehmensweiten Anwendungen hat J2EE derzeit einen großen Vorsprung vor Microsoft .NET. Dieser Vorsprung ist zum einen dadurch zu erklären, dass J2EE früher entwickelt wurde, zum anderen schafft es eine andere technologische Basis. Die Plattformunabhängigkeit bietet vielen Unternehmen größeren Entscheidungsspielraum bei der Auswahl von Betriebssystemen und Hardwareplattformen. Dies kann die .NET Plattform nicht bieten. Microsoft .NET ist zugeschnitten auf die Microsoft Produktpalette, deren Betriebssysteme und die dazu passende Hardware. Ein verteiltes Komponentenmodell wurde mit .NET nicht neu eingeführt, sondern es wurde auf das COM+/DCOM Modell zurückgegriffen. Microsoft bedient eine andere Zielgruppe mit ihrer Plattform: Entwickler die seit jeher Microsoft-Produkte einsetzen und die eine Bindung an den Konzern nicht scheuen. Meist haben diese Firmen eine Vielzahl von Entwicklungen in COM und Webanwendungen mit ASP. Diese sind leicht in das neue .NET zu integrieren. Angesprochen werden sollen außerdem Programmierer der unterschiedlichsten Sprachen, die in .NET eine gemeinsame 32 33 http://www.go-mono.com European Computer Manufacturers Association 22 2. Theoretische Grundlagen Plattform finden können, ohne sich auf eine Sprache zu einigen. J2EE ist bei den Komponenten für verteilte Anwendungen ein wesentliches Stück weiter. Die Enterprise JavaBeans Technologie ist speziell auf große verteilte Systeme zugeschnitten und bietet eine Vielzahl von Diensten. Eine besonders interessante Technik ist bei den Entity Beans die Container Managed Persistenz (CMP) vgl. Kapitel 3.3. CMP ist ein Modell zum transparenten Laden, Speichern und Verändern von Daten in Informationssystemen, wie z. B. relationalen Datenbanken. Auf die weiteren Eigenschaften der EJB wird im Kapitel 3 eingegangen. Doch auch Microsoft hat Eigenschaften in die .NET-Plattform integriert, die bei J2EE noch nicht genausoweit ausgereift sind. Hier ist vor allem die Unterstützung für WebServices zu nennen. Darin liegen eindeutig die Stärken der .NET-Plattform. Die konsequente Ausrichtung auf XML und WebServices liegt zum einen daran, dass .NET noch ebenso jung ist wie die WebServices, als auch daran, dass das DCOM-Modell ersetzt werden sollte. Microsoft unterstützt nicht nur die Entwicklung von WebServices, sondern bietet z. B. mit MicrosoftPassport selbst WebServices an. WebServices sind ein offener Standard, basierend auf dem SOAP-Protokoll, das auch mit J2EE verwendet werden kann. So gibt es z. B. mit JAXP einen XML Parser, JAXM34 und SAAJ35 ermöglichen die Nutzung von SOAP als Protokoll zum Nachrichtenaustausch. JAX-RPC ermöglicht, „Remote Procedure Calls“ an den WebService-Schnittstellen, die mit der WebService Definition Language (WSDL) beschrieben sind. Mit JAXR besteht Zugang zu Informationen über registrierte Webservices (UDDI36 ). In der kürzlich vorgestellten Version 1.4 der J2EE sind die WebServices vollständig integriert worden. Insgesamt kann man sagen, dass Microsoft.NET einige interessante Fähigkeiten vor allem im Desktop-Applikations-Bereich, mitbringt. Integration von XML und WebServices sind als Stärken zu nennen. Im Bereich der verteilten Anwendungen gibt es jedoch noch einigen Nachholbedarf, um die Leistungsfähigkeit von J2EE zu erreichen. Als Nachteil ist die Bindung an Microsoft zu nennen, strategische Entscheidungen bezüglich Softwarearchitekturen sind so von diesem Konzern abhängig. Die Offenheit von Java und J2EE als unabhängige Standards bieten großen Spielraum für Weiterentwicklungen. Der Java Community Process, der für Vorschläge und Erweiterungen 34 Java API for XML Messaging SOAP with Attachments API for Java 36 Universal Description, Discovery and Integration www.uddi.org 35 2. Theoretische Grundlagen 23 der Java-Standards zuständig ist, bietet die Möglichkeit, Entwicklungen mitzuverfolgen und frühzeitig Designentscheidungen treffen zu können. Ein weiterer wichtiger Faktor ist der, dass es bereits eine große Zahl an Java/J2EE Projekten gibt und viele Erfahrungen gesammelt und veröffentlicht sind. Man kann in Foren und in Büchern wesentlich mehr Informationen und Problemlösungen finden, als im Microsoft.NET Bereich. Als Übersicht über bestimmte Eigenschaften der Plattformen soll folgende Tabelle dienen. Tabelle 2.1.: Vergleich J2EE und .NET-Plattform verfügbare Java/J2EE Microsoft.NET Plattform beliebig, bei verfügbarer JVM Microsoft-Betriebssystem, Plattform mit .NET-Plattform Komponenten- serverseitig: EJB, clientseitig: serverseitig: Integration von Modell JavaBeans COM+, clientseitig: Assembly Webservice Integriert in der J2EE Spezifi- integraler Bestandteil kation, Verwendung über Bibliotheken Applikation- IBM, BEA, JBoss, JOnAS, anderes Konzept Server Orion.... Persistenz CMP, JDO (deklarativ); BMP ADO.NET und JDBC (programmatisch) ObjectSpaces (programmatisch); (deklarativ, im Entwicklungsstadium) Entwickler- Eclipse, NetBeans, IDEA, Bor- Visual Studio.NET, NANT, NU- werkzeuge land X, JDeveloper, Ant, jUnit, nit, NDoc HttpUnit, XDoclet, JavaDoc ... verteilte Kom- EJB ponenten Programmier- COM+ (Zugriff mit WebServices) Java C#, J#, COBOL.NET, C++ ... Web-Frontend JSP/Servlet, Taglibs ASP.NET/C#, WebForms grafische Benut- AWT, SWT, Swing Windows Forms sprachen zeroberfläche 24 2. Theoretische Grundlagen 2.3. Softwareentwicklung für komponentenbasierte Systeme Die Softwareentwicklung von komponentenbasierten Systemen unterscheidet sich von der Softwareentwicklung für objektorientierte Systeme in ihrer Granularität und der Sichtweise. Da Komponenten als fertige Softwarebausteine betrachtet werden können, geht es beim Komponentenengineering vielmehr um das Zusammenspiel der Komponenten untereinander und in ihrem Systemumfeld. Wenn Komponenten eines Systems neu geschaffen werden, muss jede dieser Komponenten den Softwareentwicklungszyklus durchlaufen. Da Komponenten nicht allzu komplex gehalten werden sollten, gestaltet sich deren Entwicklung einfacher, als die Entwicklung eines monolithischen Programms. Nach der Entwicklung müssen die Komponenten jedoch zusammengesetzt und in eine Systemumgebung integriert werden. Notwendig ist bei Komponenten, dass eine Dokumentation und Schnittstellenbeschreibung vorliegt. Diese kann schon während der Entwurfsphase erstellt werden. Es wird angestrebt, die Schnittstellenbeschreibungen einem Standard anzupassen, um höhere Wiederverwendbarkeit zu ermöglichen. Der nächsten Abschnitt thematisiert das Softwareengineering für komponentenbasierte Systeme. Danach erfolgt eine kurze Darstellung der Unified Modeling Language (UML), die die Modellierung von Komponenten unterstützt. 2.3.1. Komponenten-Engineering Nach [SDD02] kann die Entwicklung von komponentenbasierter Software in verschiedene Teilbereiche untergliedert werden : • Application Family Engineering: Dieser Prozess widmet sich der Entwicklung von Softwaresystemen für eine Gruppe von Anwendungen. Hierbei wird auf bereits vorhandene Komponenten zurückgegriffen, die an das System angepasst und integriert werden können. Am Ende des Prozesses soll ein Komponenten-Framework für die gewählte Anwendungsgruppe entstehen. • Domain Engineering: Ziel ist es, ein Komponentensystem zu entwickeln, das explizit für eine Wiederverwendung vorgesehen ist. Es entsteht ein Architekturmodell, das für die gewählte und verwandte Anwendungsdomänen genutzt werden kann. 2. Theoretische Grundlagen 25 • Component System Engineering: In dieser Phase werden die Komponenten erstellt, deren Funktionen und Schnittstellen den gestellten Anforderungen entsprechen. Ihr Verhalten wird in der Komponenten-Spezifikation dokumentiert. • Application Engineering: In diesem Prozess wird der größte Nutzen aus komponentenbasierter Software gezogen. Hier werden die entsprechenden Komponenten konfiguriert und zusammengesetzt, um ein Softwaresystem zu erstellen. Dieser Vorgang ähnelt dem Assemblieren von Computerhardware, wo Wiederverwendung effektiv einsetzt wird. Eine der Hauptaufgaben bei der Entwicklung von komponentenbasierten Systemen ist die Identifizierung von möglichen Komponenten. Dabei können sowohl fachliche als auch funktionale Komponenten gefunden und gekapselt werden. Da in heutigen Komponentenarchitekturen, wie sie die EJB-Technologie bereitstellt, bereits eine Vielzahl von funktionalen Komponenten integriert sind, bieten hauptsächlich die Fachkomponenten ein hohes Potential für die Wiederverwendung. Die Identifizierung der Komponenten geschieht entweder während der Entwurfsphase des Softwareengineering-Prozesses oder bei bestehenden nicht komponentenbasierten Systemen durch gezielte Analyse. Die Erstellung eines Komponentensystems verlangt einen umfangreicheren Softwareengineering-Zyklus. Die Phasen des Softwareengineering untergliedern sich laut [Bal00] in: • Planungsphase • Definitionsphase • Entwurfsphase • Implementierungsphase • Einführungsphase • Wartungsphase Durch das Komponentenparadigma erweitern sich vor allem die Entwurfs-, Implementierungs- und Einführungsphase. In der Entwurfsphase muss zusätzlich zur Architekturentscheidung (z. B. 3- oder Mehrschicht-Modell) die Identifizierung der Fachkomponenten erfolgen. Weiterhin ist während 26 2. Theoretische Grundlagen dieser Phase die Entscheidung für oder gegen spezielle Entwurfsmuster zu treffen. Für die Entwicklung mit der J2EE werden diesbezüglich einige Vorschläge von Sun Microsystems in den „J2EE Blueprints“ [SM04a] veröffentlicht, die sich als effektiv bewährt haben. Die in dieser Arbeit verwandten Entwurfsmuster werden im Abschnitt 5.3 beschrieben. Die Implementierungsphase gestaltet sich bei Komponentensystemen ebenfalls anders als bei monolithischen Softwaresystemen. Die einzelnen Komponenten lassen sich unabhängig voneinander implementieren (unter Beachtung der Schnittstellen). Um jedoch ein lauffähiges System zu schaffen, müssen die Applikation zusammengesetzt und entsprechende Umgebungsvariablen angepasst werden. Die J2EE-Spezifikation hat die Implementierung auf verschiedene Rollen aufgeteilt, die im Abschnitt 3.1 genauer beschrieben werden. Die Einführungsphase soll sich bei der EJB-Technologie auf das Installieren der Anwendung auf dem Application-Server beschränken. Dabei müssen Anpassungen in speziellen Dateien, den „Deployment-Deskriptoren“ (siehe Abschnitt 3.2), vorgenommen werden. Durch die Standardisierung der J2EE Plattform sind Anwendungen so mit geringem Aufwand auf unterschiedlichen Application-Servern verschiedener Hersteller lauffähig. 2.3.2. UML als Standard zur Modellierung des Entwicklungsprozesses Die „Unified Modeling Language“ (UML) wurde von der Object Management Group (OMG)37 entwickelt, die unter anderem auch CORBA eingeführt hat. UML hat sich als Standard insbesondere für die Modellierung objektorientierter Softwaresysteme durchgesetzt. Da Komponenten in Java objektorientiert entwickelt werden (laut Definition ist eine Komponente nicht zwingend objektorientiert), ist die Entwicklung mit der UML gut abgedeckt. UML bietet verschiedene Diagrammtypen an, um Klassen, Beziehungen und Abläufe darzustellen. Dabei wird von der Implementierung abstrahiert. Ein UML-Diagramm muss nicht jedes Implementierungsdetail darstellen aber einen guten Überblick über das System vermitteln. Durch die unterschiedlichen Diagrammtypen können Klassen und Objekte aus verschiedenen Blickwinkeln betrachtet werden. So wird von einer groben Struktur bis hin zu Methoden, Attributen und Referenzen einer Klasse, alles darstellbar. Es lassen sich auch Abläufe innerhalb einer Programmsequenz (Sequenzdiagramm) modellieren. 37 http://www.omg.org 2. Theoretische Grundlagen 27 Um die Anforderungen an eine Software zu modellieren, werden Anwendungsfall-Diagramme (Geschäftsprozessdiagramme) verwandt. Diese Diagramme abstrahieren so stark von der Implementierung, dass sie sich gut dazu eignen, sie mit dem Auftraggeber zu entwickeln. Anwendungsfall-Diagramme sind in der ersten Stufe des Entwicklungsprozesses anzusiedeln. Die folgende Abbildung zeigt ein Anwendungsfall-Diagramm eines Nutzers. registrieren anmelden news posten search user abmelden Abb. 2.3: Ausschnitt der Anwendungsfälle der Referenz Anwendung Mit der Weiterentwicklung der UML wird angestrebt, durch exakte Modellierung von Softwaresystemen aus UML Diagrammen lauffähige Programme zu erzeugen. Der Begriff „Model Driven Architecture“ bezeichnet diese Vorgehensweise. MDA ist ebenfalls ein Standard der OMG und stützt sich auf UML und andere Techniken (Meta-Object Facility MOF, Common Warehouse Meta-Model CWM). Mit der Einführung von UML 2.0 (eine Veröffentlichung wird 2004 erwartet) sind neue Diagrammtypen und Erweiterungen für MDA und komponentenbasierte Softwareentwicklung eingeführt worden. In UML 2.0 lassen sich nun nicht nur Schnittstellen von Softwarekomponenten beschreiben, die von anderen Komponenten aus erreicht werden können, sondern ebenfalls Schnittstellen, die von einer Komponente benötigt werden und z. B. von einem Application-Server bereitgestellt werden. Es mit UML 2.0 auch möglich, Parameter für die Deploymentdeskriptoren (siehe Kapitel 3) innerhalb eines Diagramms anzugeben und so die Installation von J2EE-Komponenten zu steuern. UML hat sich zum Ziel gesetzt in der Version 2.0 wieder stärker von Programmiersprachen zu abstrahieren. Um spezielle Anforderungen dennoch erfüllen zu können, werden die so genannten „Profile“ benutzt. Diese UML-Profile erlauben es „Stereotypen“ zu definieren, also Klassen mit einer selbst definierten Charakteristik. Diese können sowohl Methoden als 28 2. Theoretische Grundlagen auch Attribute enthalten, wodurch z. B. die Definition von Session Beans oder Entity Beans möglich ist. Mit diesen Stereotypen lassen sich dann alle Komponenten des J2EE-Systems ausstatten und die entsprechenden Schnittstellen können in der UML dargestellt werden. Diese Aufgabe fällt dem Modellierungswerkzeug zu. Danach lassen sich die Komponenten über deren Schnittstellen verbinden. In der folgenden Abbildung sind eine Session- und eine Entity Bean-Komponente dargestellt, die eine Schnittstelle bereitstellen (Entity Bean) bzw. benötigen (Session Bean). Sie befinden sich in einem Artefakt, einer JAR-Datei. Zu diesem Artefakt können Eigenschaften angegeben werden, die bei J2EE in den Deployment-Deskriptoren konfiguriert werden. Im Beispiel ist das Attribut Transaction auf den Wert required zu setzen (vgl. Kapitel 3.6). Das Artefakt wird auf dem JBoss Application Server Version 3.2 installiert. JBoss 3.2 <<artifact>> User.jar <<EntityBean>> <<SessionBean>> UserEntityBean UserSessionFassade User User {transaction = required} Abb. 2.4: UML 2 - Diagramm (Komponenten und Deployment) 3. Enterprise JavaBeans In diesem Kapitel wird das Enterprise JavaBeans-Komponentenmodell detailliert beschrieben. Dabei wird auf die Rollen eingegangen, die für J2EE-Entwickler bei der Erstellung von Softwaresystemen spezifiziert sind. Anschließend werden die verschiedenen EJB-Typen, deren Implementierung und ihre Konfiguration in den entsprechenden DeploymentDeskriptoren beschrieben. Den Abschluss des Kapitels bildet ein Abschnitt über Alternativen für die Persistenz von EJBs und ihre Transaktionsverwaltung. 3.1. Rollenmodell bei J2EE In der Spezifikation der Enterprise JavaBeans 2.0 [SM01a], auf die sich diese Arbeit bezieht, sind nicht nur die Implementierungsdetails der einzelnen Beantypen und Vorschriften für die EJB-Container festgelegt, sondern auch die Rollen, die bei der Erstellung von Enterprise-Anwendungen eingenommen werden. Dabei sind die einzelnen Rollen voneinander abgegrenzt, um sie von verschiedenen Personen oder Unternehmen ausfüllen lassen zu können. Die Spezifikation der Rollen bestimmt die Eigenschaften der Endprodukte jeder einzelnen Rolle, um so die aufeinander aufbauenden Stufen bei der Enwicklung durchlaufen zu können. Währen der Entwicklung der in dieser Arbeit in Kapitel 5 beschriebenen J2EE-Anwendung werden vom Autor alle hier beschriebenen Rollen eingenommen. 3.1.1. Enterprise Bean-Provider Der Bean-Provider (Anbieter einer Enterprise-JavaBean-Komponente) ist für die Entwicklung der Enterprise JavaBeans zuständig. Er entwickelt die Geschäftslogik, indem er die für einen Anwendungsteil nötigen Entitäten und Geschäftsabläufe abbildet. Dazu bedient er sich bei den dazu passenden Bean-Typen, die in Kapitel 3.2 beschrieben werden. 30 3. Enterprise JavaBeans Da der Enterprise Bean-Provider alle Implementierungsdetails seiner Klassen und der bereitgestellten Schnittstellen kennt, beschreibt er diese im Deployment-Deskriptor seiner Bean. Dabei werden Abhängigkeiten zu anderen Teilen der Gesamtanwendung definiert. Durch die Trennung der Zuständigkeiten ist der Enterprise Bean-Provider von technischen Aspekten der Anwendung, wie z.B. der Implementierung von Sicherheitsrichtlinien und Transaktionsverwaltung, befreit. Als Endprodukt seiner Arbeit liefert der Bean-Provider ein Java Archiv (JAR-Datei) aus, das die implementierten Klassen, Schnittstellen und den Deployment-Deskriptor seiner EJBs enthält. Bei einer Trennung der Rollen auf verschiedene Personen oder sogar Unternehmen, muss die JAR-Datei vom Enterprise Bean-Provider ausreichend dokumentiert werden, um die nachfolgende Arbeit des Zusammenstellens der Anwendung zu ermöglichen. Die nachfolgenden Rollen im Entwicklungsprozess stützen sich auf die Arbeit des BeanProviders und ergänzen die notwendigen Anforderungen im Deployment-Deskriptor sowie in der Container- und Serverkonfiguration. 3.1.2. Application Assembler Der Application Assembler benötigt für seine Arbeit ein umfassendes Wissen über die Gesamtanwendung. Er stellt aus den, von den Enterprise Bean-Providern bereitgestellten, JavaArchiven eine Anwendung zusammen. Dazu ergänzt er die mitgelieferten Deployment-Deskriptoren der einzelnen Komponenten. Viele J2EE-Anwendungen besitzen ein Web-Interface für den Benutzer. Diese Schnittstellen werden bei J2EE-Anwendungen überwiegend durch den Einsatz der JSP- und Servlet-Technologie erstellt (vgl. A.1). Der Application-Assembler kann eine solche Benutzerschnittstelle selbst erstellt haben oder eine vorhandene in die Gesamtanwendung integrieren. Das Ergebnis seiner Arbeit ist ein weiteres Archiv, das die einzelnen Komponenten, das optionale Web-Interface und einen weiteren Deployment-Deskriptor (application.xml) enthält. Das Archiv ist eine EAR-Datei, wobei „EAR“ für Enterprise Archive steht. 3.1.3. Deployer Der Deployer ist nun für die Installation und Inbetriebnahme der Anwendung zuständig. Dabei wird er von serverseitigen Tools des Container-Providers (siehe 3.1.5) unterstützt. 3. Enterprise JavaBeans 31 Seine Aufgabe ist es unter anderem sicherzustellen, dass alle angeforderten Datenquellen (Datenbanken, Dateien etc.) verfügbar sind. Hierbei muss er z. B. das Mapping der Entity Beans auf bereits vorhandene Datenbanken vornehmen und die in den einzelnen Komponenten definierten Sicherheitsrollen konkreten Benutzern und Benutzergruppen aus der Benutzerverwaltung zuordnen. Der Deploymentvorgang wird beim JBoss Application Server nicht, wie bei anderen Anbietern, über ein grafisches Programm unterstützt. Der JBoss benutzt einen Hot-DeploymentMechanismus, der das Installieren der Anwendung automatisiert, wenn entsprechende Konfigurations-Informationen vorliegen. Detailliert beschrieben wird der Hot-Deployment-Mechanismus im Kapitel 4.2.3. 3.1.4. EJB-Server-Provider Der Serveranbieter ist in den meisten Fällen mit dem EJB Container-Provider gleichzusetzen. Der Server bietet die Grundlage des EJB-Containers und bietet diesem Systemdienste an. Er kümmert sich z. B. um Netzwerkverbindungen, Thread und Prozessmanagement. Der Server ist auch für das Clustering zuständig, das in Kapitel 4.2.5 am Beispiel des JBoss veranschaulicht wird. 3.1.5. EJB-Container-Provider Der Container-Provider ist dafür zuständig, eine Laufzeitumgebung für Enterprise JavaBeans bereitzustellen. Der EJB-Container ist im EJB-Server installiert und nutzt dessen grundlegenden Dienste. Die Aufgaben des Containers werden in der EJB-Spezifikation genau beschrieben. Unter anderem werden vom Container der Persistenzmechanismus angeboten, die Transaktionen bei Datenbankzugriffen überwacht und die Instanzen der EJBs verwaltet. Den installierten EJBs werden Schnittstellen zu den Containerdiensten bereitgestellt. Der Container überwacht auch den Zugriff auf die EJBs, denn alle Aufrufe werden vom Container abgefangen und weitergeleitet. Dadurch ist es auch möglich, Sicherheitsrichtlinien auf der Server/Container-Seite durchzusetzen. Der Container-Provider bietet die Werkzeuge an, die vom Deployer benötigt werden, um Anwendungen zu installieren und zu überwachen. Diese Monitoring-Programme werden auch vom System-Administrator benötigt um z. B. Engpässe (Anzahl der Datenbankverbin- 32 3. Enterprise JavaBeans dungen, Speicherauslastung, Netzwerkverkehr) aufzuspüren und Gegenmaßnamen einzuleiten. 3.1.6. System-Administrator Der System-Administrator ist für die Konfiguration, Installation, den reibungslosen Lauf und die Verfügbarkeit des EJB-Servers zuständig. Dabei beobachtet er sowohl die Netzinfrastruktur als auch die Lastverteilung am Server über die vom Server- bzw. ContainerProvider mitgelieferten Managementprogramme. Zu seinen Aufgaben zählen hierbei der Schutz des Servers vor Angriffen aus dem Netzwerk, die Sicherung der Verfügbarkeit über redundante Hardwaresysteme als auch die Konfiguration und der Betrieb von EJB-Clustern, um Leistungsengpässe zu vermeiden und die Ausfallsicherheit zu erhöhen. 3.2. Architektur der Enterprise JavaBeans Die Enterprise JavaBeans sind der zentrale Bestandteil der J2EE-Spezifikation. Wie bereits in Kapitel 2.2.2 erwähnt, handelt es sich bei den EJBs um ein serverseitiges Komponentenmodell. Sie repräsentieren die Geschäftslogik von verteilten, unternehmensweiten Anwendungen (Enterprise-Systeme) und laufen innerhalb eines EJB-Containers ab. 3.2.1. J2EE-Server Um Enterprise JavaBeans zu nutzen, benötigt man einen EJB-Container, der selbst auf einem Server läuft. Der Server bietet dabei dem EJB- und anderen Containern eine Laufzeitumgebung und grundlegende Dienste an. Er ist somit die Schnittstelle zur darunterliegenden Plattform. Da Sun die Aufgaben des J2EE-Servers nicht explizit vorschreibt, hängt es vom Hersteller ab, welche Dienste der Server bietet. In den meisten Fällen entwickelt der Serverhersteller auch den EJB-Container, wodurch gewährleistet ist, dass alle benötigten Dienste zur Verfügung stehen. Eine Ausnahme ist das Unternehmen Oracle, deren EJB-Container Orion nicht aus dem gleichen Haus stammt. Im Allgemeinen werden folgende Dienste vom Server angeboten: • Thread- und Prozessmanagement zur Verwaltung unterschiedlicher Container 3. Enterprise JavaBeans 33 • Unterstützung von Clustering • Namens und Verzeichnisdienste (JNDI) • Netzwerkverbindungen und Socket-Schnittstellen Abbildung 3.1 Zeigt den EJB-Server mit integriertem Web- und EJB-Container sowie die bereitgestellten Dienste. J2EE-Server HTTP/HTTPS Web-Browser JSP Servlet HTML XML Web-Container JMS JAAS JavaMail Enterprise Information System JTA Client RMI-IIOP EJB EJB EJB JDBC Datenbank ERP Systeme JAXP Rich-Client EJB-Container J2SE Abb. 3.1: J2EE-Architektur (Abkürzungen siehe Glossar Seite:145) 3.2.2. EJB-Container Der EJB-Container bietet seine Dienste direkt den installieren EJBs an. Dabei hat er über verschiedene definierte Schnittstellen (Callback-Methoden) die Möglichkeit, den Lebenszyklus der EJBs zu beeinflussen. Je nach Bean-Typ unterscheiden sich die möglichen Zustände innerhalb des Lebenszyklus der Bean voneinander und werden bei der genaueren Betrachtung der Beantypen im diesem Kapitel dargestellt. Allen Bean-Typen ist jedoch gemeinsam, dass der Container Instanzen der EJBs erzeugt und auch ihren Lebenszyklus beenden kann, indem er nicht mehr benötigte Instanzen löscht. Clients benutzen die EJBs, um bestimmte Methoden auszuführen. Sie haben jedoch keinen direkten Zugriff auf eine Instanz der Bean-Klasse, sondern kommunizieren aussschliesslich mit Interfaces (Local- oder Remote-Interface). Dadurch hat der Container die Möglichkeit, seinen Managementaufgaben nachzukommen (vgl. 4.1.3). Der Zugriff von Java-Clients an den bereitgestellten Schnittstellen ist in der Abbildung 3.2 dargestellt. Client Code (native Java Code) 34 3. Enterprise JavaBeans 1. Finden einer Bean-Referenz EJB Container/ Server Home Object 3. Rückgabe einer EJB-Object Referenz 2.EJB- Object Instanz erzeugen 4. Aufruf einer Methode des EJB- Objects 5.Methodenaufruf EJB Object 7. Rückgabe Enterprise Bean 6. Rückgabe Abb. 3.2: Client-Sicht auf EJBs nach [SDD02] Beim Deployment1 werden Klassen für die vom Bean-Provider erstellten Home- und Komponenten-Interfaces generiert. Dabei benötigen die Tools des Container-Providers die Angaben der entsprechenden Deployment-Deskriptoren. Aus dem Home-Interface wird von den Container-Tools die Home-Klasse erzeugt. Ihre Instanzen fungieren als Factories und erzeugen, finden oder löschen Komponenten-Instanzen. Als Factory stehen sie demnach als eine Instanz für alle Anfragen zur Verfügung. Die Instanz der konkreten Klasse des HomeInterfaces (remote oder local) bezeichnet man als Home-Objekt. Die Instanz des Komponenten-Interfaces (remote oder local) wird als EJB-Objekt bezeichnet. Es werden so viele EJB-Objekte instanziiert, wie von den Clients angefordert werden. Dabei kann man im EJB-Container Beschränkungen für die maximale Anzahl setzen und durch Aktivierung und Passivierung der Instanzen wird außerdem vom Container der Speicherplatz verwaltet. Die konkreten Klassen der Interfaces und ihre Instanzen bezeichnet man als Glue-Code des Containers (nach [BG02]). Das Komponenten-Interface exportiert die Methoden der Komponente nach außen, so dass der Client auf sie zugreifen kann. Die Implementierung des Komponenten-Interfaces fungiert als Vermittler zwischen dem Client und der implementierten Bean-Klasse. Hier werden die im Deployment-Deskriptor deklarierten Einstellungen wie Sicherheitsüberprüfungen, Transaktionen oder die „Container Managed Persistence“ (vgl. Kapitel 3.3) umgesetzt. Die Interfaces können als Local- oder Remote-Interface ausgelegt sein. Sie unterscheiden 1 Installation einer EJB in einem EJB-Container 3. Enterprise JavaBeans 35 sich in der Art des Zugriffs und der generierten Home- und Komponenten-Klasse voneinander. Die lokalen Interfaces erzeugen „normale“ Javaklassen, deren Zugriff aus der gleichen JVM stattfinden muss. Remote-Interfaces können auch aus einer anderen JVM oder auch von einem anderen Rechner angesprochen werden, die Implementierung der Remote-Interfaces folgt den Anforderungen der Java-RMI (Remote Method Invocation). Um auf Komponenten zugreifen zu können, die nicht innerhalb der selben Java Virtual Maschine ablaufen, bedient sich der Application-Server der RMI. Die J2EE-Spezifikation schreibt dabei vor, dass als zugrundeliegendes Protokoll für RMI das IIOP (Internet InterORB Protocol) benutzt werden muss. Dabei garantiert RMI-IIOP die Interoperabilität zu CORBA und anderen J2EE-konformen Application-Servern. Bei der Kommunikation mittels RMI-IIOP wird auf der Seite des zugreifenden Clients ein Stellvertreter-Objekt (Stub) des Objektes erzeugt, mit dem der Client dann kommuniziert. Das Stub-Objekt leitet die Aufrufe dann über eine Kommunikations-Brücke (z. B. IIOP) an das serverseitige Skeleton-Objekt weiter. Das Skeleton-Objekt übergibt die Aufrufe an das zuständige Remote-Objekt. Der Stub ist dafür zuständig die Daten für die Übertragung zum Skeleton netzwerktauglich zu verpacken (Marshalling). Das Skeleton-Objekt macht diesen Prozess rückgängig (Unmarshalling) und übergibt die Daten an das Remote-Objekt. In der Folgenden Grafik ist die Kommunikation zwischen Client und Remote-Objekt dargestellt: Client Server RMI-Client Prozess Stub Marshalling/Unmarshalling ORB Remote Objekt Skeleton Marshalling/Unmarshalling IIOP ORB Abb. 3.3: RMI-Kommunikation nach [BG02] Der Vorteil von RMI ist, dass der Client nicht wissen muss, wo sich die aufgerufene Komponente befindet. Dies bezeichnet man als Ortstransparenz, für die man einen Namensdienst benötigt. Der Namensdienst, der vom J2EE-Server angeboten wird, kann über JNDI (Java Naming 36 3. Enterprise JavaBeans and Directory Interface) angesprochen werden. Installierte Komponenten werden mit ihrem Namen in einer Registry angemeldet und sind so für andere Komponenten und Clients auffindbar. JNDI bietet jedoch nicht nur Zugriff auf den Namens-, sondern auch einen Verzeichnisdienst, der eine hierarchische Verwaltung der Einträge ermöglicht. Der Verzeichnisdienst kann außer dem Binden eines Namens an eine Komponente auch weitere Informationen über diese bereitstellen. EJB-Komponenten nutzen diesen Dienst, um z. B. den Zugriff auf eine Datenbank zu erlangen. Die Informationen die eine EJB vom ApplicationServer benötigt, werden in ihrem EJB-Environment eingetragen. Seit EJB 2.0 ist es möglich, statt über RMI auch lokal auf eine Komponente zuzugreifen. Dazu müssen jedoch sowohl Client als auch EJB-Komponente in der selben JVM ablaufen. Vorteilhaft ist, dass der komplette Vorgang des Stub- und Skeleton-Erzeugens und auch die aufwändige RMI-IIOP Kommunikation vermieden wird. Dabei wechselt die Aufruf-Semantik vom „call by value“ zu einem „call by reference“. Wie bereits erwähnt, bietet der EJB-Container Dienste wie Sicherheit- oder auch einen Nachrichten-Dienst an. Der Sicherheitsdienst entbindet den Programmierer der Geschäftslogik von der programmatischen Überprüfung der Zugriffsrechte eines Benutzers oder Clients. Die Sicherheit wird über ein Rollenmodell definiert, wobei jeder Methode einzeln eine bestimmte Rolle zugewiesen werden kann. Da der Aufruf einer Enterprise JavaBean über ihre Interfaces kontrolliert durch den EJB-Container erfolgt, ist es hier möglich, dass der EJB-Container den Zugriff überprüft. Man spricht beim Abfangen des Aufrufs von einer „Interception“. Wenn der gewünschte Zugriff auf eine Methode untersagt ist, löst der EJBContainer eine Ausnahme aus und signalisiert damit das Scheitern des Versuchs. Der Nachrichtendienst ist ebenfalls eine Neuerung der EJB 2.0 Spezifikation. Zu diesem Dienst wurde auch ein neuer EJB-Typ, die Message-Driven Beans, eingeführt. Der Nachrichtendienst wird über den Java Message Service (JMS) zur Verfügung gestellt und bietet eine asynchrone Verarbeitung von Nachrichten an. So können verschiedene NachrichtenSchlangen (Queues) definiert werden, auf denen Nachrichten eingestellt und abgerufen werden. Beim Ausfall eines Empfängers bleibt die Nachricht erhalten und wird vom Empfänger abgeholt, sobald dies für ihn möglich ist. Solche Systeme sind auch unter dem Begriff Messageoriented-Middleware (MOM) bekannt. Die Konfiguration von Message-Driven Beans und weitere Vorteile bei ihrer Verwendung werden im Kapitel 3.5 dargestellt. 3. Enterprise JavaBeans 37 Auf den Persistenz- und Transaktionsdienst des EJB-Containers wird gesondert im Kapitel 3.3.2 bzw. 3.6 eingegangen. 3.2.3. Programmierrestriktionen bei EJB Um die Leistungsfähigkeit und Kompatibilität der Enterprise JavaBean Technologie gewährleisten zu können, wurden in der EJB-Spezifikation [SM01a] zahlreiche Restriktionen festgelegt. Dadurch soll der EJB-Container seine Zuständigkeiten erfüllen können. Die folgende Liste der Beschränkungen zeigt nur die wichtigsten Reglementierungen, eine komplette Liste ist in der EJB-Spezifikation nachzulesen. • Als static gekennzeichnete Variablen sind nicht erlaubt, da diese nur innerhalb einer JVM sichtbar sind. Als Konstanten sind statische Felder erlaubt. • EJBs dürfen weder Threads noch Thread-Steuerungsanweisungen (z. B.: synchronized) benutzen. • Es ist nicht erlaubt, Methoden des AWT zu benutzen. Da EJB eine Servertechnologie ist, kann durchaus die Möglichkeit zur Darstellung grafischer Oberflächen fehlen. • EJBs dürfen nicht auf das Dateisystem zugreifen ( java.io-Methoden sind untersagt). Dadurch würde die Umgebung des EJB-Containers durchbrochen werden. • EJBs dürfen keine Socketdienste anbieten, aber Socketdienste nutzen. Da eine EJB durch den Container deaktiviert und gelöscht werden kann, wäre ein solcher Socketdienst nicht dauerhaft verfügbar. • EJBs ist es untersagt auf native Bibliotheken zuzugreifen (z. B. DLLs über Java Native Interface) • EJBs dürfen nicht über Reflections und Introspection auf Objekte zugreifen und so die Interception-Möglichkeit des Containers umgehen. Dadurch kann man z. B. Sicherheitsmaßnahmen aushebeln. • Um die Stabilität aller im Container laufenden Softwaresysteme zu gewährleisten, dürfen die EJBs keine Methoden benutzen um die Laufzeitumgebung zu beeinflussen. Dazu sind der Zugriff, die Erstellung und Änderungen am Classloader untersagt. 38 3. Enterprise JavaBeans Da der Container für die Steuerung der Sicherheitsrichtlinien aller Anwendungen zuständig ist, sind Zugriffe auf das java.security-Package zu vermeiden. • Methodenaufrufe dürfen weder als Parameter, noch als Ergebnis die Java-Referenz this benutzen. 3.3. Enity Beans Entity Beans sind die Ausprägung der Enterprise JavaBeans, die die Repräsentation von Daten, also Geschäftsentitäten, darstellen. Dabei unterscheidet man Entity Beans in solche mit „Bean Managed Persistence“ (BMP) und „Container Managed Persistence“ (CMP). Entity Beans (im folgenden auch EB genannt) stellen also persistent gespeicherte Daten als Geschäftsobjekte dar. Dabei wird als Speichermedium meist eine relationale Datenbank eingesetzt, jedoch sind auch andere Enterprise-Informationssysteme denkbar (XML-Datenspeicher, Main-Frames und Altsysteme). Beim Einsatz von relationalen Datenbanken repräsentiert eine EB einen Datensatz, der z. B. eine Zeile einer Datenbanktabelle darstellt. Da das Ziel von J2EE große, verteilte Systeme mit einer hohen Benutzeranzahl sind, müssen Objekte, die Daten repräsentieren, vor Problemen durch konkurrierenden Zugriff geschützt werden. Um dies zu gewährleisten werden EBs mittels Transaktionen gesichert(vgl. Kapitel 3.6). Um Asynchronität zu vermeiden, stellt der EJB-Container sicher, dass alle Clients auf den selben Datenzustand einer EB zugreifen. Entity Beans ermöglichen mehreren Clients den parallelen Zugriff auf transaktionsgesicherte Daten. [DP02]. 3.3.1. Aufbau einer Entity Bean Eine Entity Bean besteht aus zwei oder vier Interfaces (je zwei Local- und/oder RemoteInterfaces) und einer Bean-Klasse. Die Bean-Klasse definiert alle Attribute, Methoden und Beziehungen (vgl. Kapitel 3.3.4) einer Entität. Dabei wird ein Attribut oder eine Reihe von Attributen als Primärschlüssel benutzt. Über diesen Primärschlüssel werden die Geschäfts-Entitäten einer Anwendung eindeutig unterscheidbar, weshalb er auch zum Auffinden der Entitäten benutzt wird (vgl. 3.3). Der Primärschlüssel muss ein Objekt einer serialisierbaren Klasse sein, um den Anforderungen von RMI-IIOP zu entsprechen. Bei nicht zusammengesetzten Primärschlüsseln bieten sich daher Klassen wie String oder Integer an. 3. Enterprise JavaBeans 39 Die Methoden der Bean-Klasse bieten Zugriff auf deren Daten und ermöglichen einfache Manipulationen. Die Beziehungen definieren die Abhängigkeiten zwischen verschiedenen Entity Beans. Jede Entity Bean-Klasse implementiert die Callback-Methoden des Interface javax. ejb.EntityBean. Diese werden vom EJB-Container benutzt um die Instanz der EB zu überwachen und zu steuern. Die Callbackmethoden werden immer ausgeführt, wenn der Container in den Lebenszyklus der Bean eingreift. Das gibt dem Programmierer die Möglichkeit bestimmte Aktionen vor einem Zustandswechsel auszuführen. Sinnvoll ist es z. B. in manchen Umgebungen, das Löschen oder Erzeugen von Entitäten zu protokollieren. Bei BMP-Entity Beans werden die Callbackmethoden mit der Funktionalität für die Persistenz der Komponenten ausimplementiert. Weiterhin werden in der Beanklasse die Create-, Finder-, Select- und Home-Methoden definiert. Jede Entity Bean kann mehrere Create-Methoden mit unterschiedlicher Signatur definieren und ist dazu verpflichtet, jeweils eine ejbPostCreate-Methode gleicher Signatur zu erstellen. Die Finder-Methoden der Bean dienen dem Auffinden einer oder mehrerer Bean-Instanzen. Sie müssen im Home-Interface und in der Bean-Klasse deklariert werden. Dabei ist die Namenskonvention findBy<Suffix>() im Interface und ejbFindBy<Suffix>() in der Bean-Klasse einzuhalten. Eine Finder-Methode ist für jede Entity Bean vorgeschrieben und heißt findByPrimaryKey(*Schlüssel*). Diese Methoden haben als Rückgabewert, aus Sicht des Clients, eine Instanz des Komponenteninterfaces, also das EJBObjekt. In der Beanklasse selbst wird eine Instanz des Primärschlüssels zurückgegeben. Bei einer grösseren Rückgabemenge wird je nach Definition im Deployment-Deskriptor eine Collection oder ein Set zurückgeliefert. Ein Set darf jedes Objekt nur einmal enthalten, in SQL und EJB-QL (vgl. 3.3.3) wird dies durch ein select destinct erreicht. Alle Findermethoden müssen die FinderException deklarieren. Die Select-Methoden sind ausschliesslich den CMP-Entity Beans zuzuordnen und werden im Kapitel 3.3.3 besprochen. Die Home-Methoden sind Geschäftsmethoden der Entity Beans, jedoch operieren sie nicht auf einer EB-Instanz, sondern global auf allen Entitäten. Die Home-Methoden werden im Zustand „pooled“ ausgeführt. Die Nameskonvention der Home-Methoden besagt, dass in der Beanklasse eine Home-Methode das Präfix ejbHome besitzen muss. Exportiert wer- 40 3. Enterprise JavaBeans den die Home-Methoden über das Home-Interface der Entity Bean. Hier besitzt die Methode kein Präfix. Der Lebenszyklus einer Entity Bean und die beim Übergang aufgerufenen Methoden sind in Abbildung 3.4 dargestellt. Bean-Instanz oder Transaktion löst eine System-Ausnahme aus ejbFind<Suffix>(...) ejbHome<Suffix>(...) Class.newInstance () setEntityContext (ctx) create() I. ejbCreate<Suffix>() II. ejbPostCreate<Suffix>() I. ejbActivate() II. ejbLoad() im Pool bereit (pooled-ready) Existiert nicht Geschäftsmethoden() bereit (ready) I. ejbStore() II. ejbPassivate() ejbRemove() unsetEntityContext() ejbSelect<Suffix>(...) remove() Vom Container Initiiert ejbLoad() ejbStore() ejbSelect<Suffix>() Vom Client initiiert Abb. 3.4: Lebenzyklus: Entity Bean 3.3.2. Bean Managed Persistence In der Version 1.3 der J2EE-Spezifikation gibt es zwei Möglichkeiten, Entity Bean-Objekte persistent zu speichern. Eine Alternative wird dann in Kapitel 3.3.6 aufgezeigt. Zunächst soll hier auf die Methode der Bean-managed-Persistence (kurz: BMP) eingegangen werden. BMP-Entity Beans werden hauptsächlich dann eingesetzt, wenn der Programmierer selbst die vollständige Kontrolle über Datenbankverbindungen, Speichern und Laden von Objekten haben möchte. Bei der Bean-managed-Persistence werden die Callback-Methoden des implementierten Interface javax.ejb.EntityBean selbst mit der Logik für Datenspeicherung und Laden versehen. Der EJB-Container ruft weiterhin zum entsprechenden Zeitpunkt die Methoden auf und steuert so die Prozesse, die für die Persistenz notwendig sind. Den Zeitpunkt bestimmt also der Container, die Umsetzung liegt jedoch in der Hand des Bean-Providers. 3. Enterprise JavaBeans 41 Zur Speicherung von Daten wird in Java häufig eine relationale Datenbank verwendet, die über das JDBC-API angesprochen wird. Sinnvoll ist es hier, eine eigene Daten-Zugriffsklasse zu implementieren, die aus den verschiedenen BMP-EBs genutzt wird. Im DeploymentDeskriptor wird für eine BMP-EB ein Eintrag vorgenommen, der die Datenbank in JNDIVerzeichnis mit einem Namen auffindbar macht. In der Datenzugriffsklasse kann so über einen JNDI-Lookup die gewünschte Datenbank angesprochen werden. Die Methoden des Interfaces, welches Entity Beans implementieren, werden in der Tabelle 3.1 beschrieben und angegeben, ob sie bei den beiden Persistenzarten selbst implementiert werden müssen. Weiterhin müssen die Methoden zum Auffinden von Objekten (Finder-Methoden) in der Beanklasse mit Hilfe von SQL-Statements implementiert werden. Sie liefern eine Referenz oder eine Anzahl von Referenzen auf das oder die EJB-Objekte der Entität zurück. Die BMP gibt dem Bean-Provider große Flexibilität bei der Umsetzung des „Objektrelationalen Mappings“, jedoch ist die Kompatibilität von BMP-Entity Beans eingeschränkt. Ein weiterer Typ für die persistente Speicherung von Objekten ist die Container-ManagedPersistence (CMP), deren Vorteile im folgenden Kapitel dargestellt werden. 3.3.3. Container Managed Persistence Bei der Container Managed Persistence benutzt man den Persistenz-Mechanismus des EJBContainers, um seine Geschäfts-Entitäten dauerhaft zu speichern. Dabei kommt, wie bereits erwähnt, oft eine relationale Datenbank zum Einsatz. Man spricht in diesem Fall vom Objektrelationalen Mapping (vgl. Abbildung 3.5). <<ejb-jar.xml>> <persistence-type>Container</persistence-type> <prim-key-class>java.lang.Integer</prim-key-class> <reentrant>False</reentrant> <cmp-version>2.x</cmp-version> <abstract-schema-name>USERENTITY</abstract-schema-name> <cmp-field> <field-name>ID</field-name> </cmp-field> <cmp-field> <field-name>name</field-name> </cmp-field> <primkey-field>ID</primkey-field> UserEntityEJB User +setID() +getID() +setName() +getName() ... ID 007 Name Bond UserEntityEJB-Objekt ID=”007” Name=”Bond” ... Abb. 3.5: Mapping von Entity Beans auf eine relationale Datenbank 42 3. Enterprise JavaBeans Der Bean-Provider einer Entity Bean mit CMP braucht sich nur um das Erstellen der Beanklasse und deren Interfaces zu kümmern. Die persistenten Attribute werden dann im Deployment-Deskriptor (ejb-jar.xml) der Bean angegeben. Eine Besonderheit seit EJB 2.0 besteht darin, dass die Bean-Klasse als abstract deklariert wird, so wie auch ihre Methoden („Getter“ und „Setter“) für den Zugriff auf die persistenten Attribute. Der Container implementiert beim Deployment der Entity Bean nicht nur die bereitgestellten Interfaces, sondern erzeugt auch eine abgeleitete Klasse der Bean-Klasse, die alle abstrakten Methoden implementiert. Beim JBoss wird aus den Angaben im Deployment-Deskriptor während des Installationsvorgangs der EJB auch die Datenbanktabelle erzeugt (wie eine EB auf eine vorhandene Tabelle abgebildet wird, erläutert Kapitel 4.5.2). Das Umsetzen der Persistenz ist in der EJB-Spezifikation nicht festgelegt und somit herstellerabhängig. Die Callback-Methoden des Containers müssen bei CMP nicht implementiert werden. Es steht dem Bean-Provider jedoch frei, bei Zustandswechseln in den entsprechenden Methoden Programmcode ablaufen zu lassen. Die Finder- und Select-Methoden einer CMP-Entity Bean ermöglichen es, Anfragen an die Entitäten zu stellen. Das Auffinden einer Instanz führt jedoch nicht zum Laden sämtlicher Daten einer Entität. Zunächst wird nur der Primärschlüssel der Entität geladen, alle weiteren persistenten Attribute erst beim Zugriff auf das gelieferte EJB-Objekt (lazy loading). Der Unterschied zwischen Select- und Finder-Methoden liegt darin, dass Finder vom Client direkt genutzt werden können, um Entitäten zu finden. Select-Methoden können jedoch nicht direkt vom Client benutzt werden. Um sie dennoch nutzbar zu machen, bedient man sich der Home-Methoden, um ihre Ergebnismenge dem Client zur Verfügung zu stellen. Ein weiterer Unterschied besteht darin, dass Select-Methoden sowohl EJB-Objekt-Referenzen, als auch Ergebnismengen eines anderen Typs liefern können und so z. B. alle Artikelnamen eines Shops liefern. Die Transaktionssicherung der Findermethoden ist im Deployment-Deskriptor deklarierbar, die Select-Methoden werden im Transaktionskontext der aufrufenden Methode ausgeführt (vgl. Kapitel 3.6). Die reine Deklaration einer Anfragemethode genügt jedoch dem Container nicht, um diese zu implementieren. Um die Anfragen zu deklarieren ist es notwendig, eine herstellerunabhängige Anfragesprache zu benutzen. Zu diesem Zweck kann man den SQL-Standard nicht einsetzen, da nicht jede Datenbank den gesamten SQL-Sprachumfang unterstützt. Bei anderen Persistenzmedien ist der Einsatz von SQL gar nicht möglich. Daher wurde die 3. Enterprise JavaBeans 43 Enterprise JavaBeans-Query Language (EJB-QL) mit der EJB Version 2.0 eingeführt. Die Syntax der EJB-QL orientiert sich an SQL. Jedoch werden nicht alle Sprachelemente von SQL bereitgestellt und neue Elemente, die zum Navigieren in Relationen von EBs benutzt werden, sind hinzugekommen. Ein EJB-QL-Statement folgt dem Schema: SELECT [DISTINCT] Objekt(Variable) FROM abstract Schema Name [AS] Variable IN (Variable.Attribut) [AS] Variable2 [WHERE Wert Vergleich Wert] [Pro03]. Dabei ist der „abstract Schema Name“ die Verbindung zwischen der Entity-Deklaration im Deployment-Deskriptor und dessen Repräsentation im Persistenzmedium. Bei relationalen Datenbanken wird häufig der abstrakte Schema-Name als Tabellenname benutzt. Im Select wird eine Variable benutzt, die eine gefundene Entität repräsentiert, indem sie das abstrakte Schema referenziert. Dadurch ist es möglich, auf die persistenten Attribute einer Entität zuzugreifen und Vergleiche auszuführen. Die Methoden-Parameter werden in Ihrer Reihenfolge an die durchnummerierten Platzhalter gebunden (?1..?n). Das Schlüsselwort IN wird benötigt, um eine Navigation zu verknüpften Entitäten zu ermöglichen (vgl. 3.3.4). Der Codeabschnitt 3.1 zeigt die Deklaration einer Query mittels EJB-QL in der ejbjar.xml-Datei. Er ist eingebettet in die Beschreibung einer Container-managed Entity Bean. Listing 3.1: Beispiel eines EJB-QL Statements (ejb-jar.xml) 1 2 3 4 5 6 7 <query> <query-method> <method-name>findByKnowledgeValue</method-name> <method-params> <method-param>java.lang.String</method-param> <method-param>java.lang.Integer</method-param> </method-params> 8 </query-method> 9 <ejb-ql> 10 11 <![CDATA[SELECT DISTINCT OBJECT(u) FROM IN (u.skills) as s where s.skillType.ID=?1 and s.knowledgeValue <=?2]]> 12 13 USERENTITY as u, </ejb-ql> </query> 44 3. Enterprise JavaBeans Der Vorteil der CMP liegt in seiner Portabilität. Laut Spezifikation sollte jede dem Standard entsprechende CMP-Entity Bean auf allen J2EE-Servern lauffähig sein. Auch der Austausch des Persistenzmediums, z. B. der Wechsel eines Datenbankherstellers, ist durch einige Änderungen an der Konfiguration des Containers abgeschlossen und es muss kein Code in den EJB-Klassen angepasst werden. Tabelle 3.1.: Interfaces bei EnityBeans Interface-Methode Funktion setEntityContext(ec) Diese Methode wird zu Begin des Lebens- CMP BMP - - - - + + - + - - - - zyklus (vgl. Grafik 3.4) der Bean aufgerufen, um die Umgebungsvariablen der Bean festzulegen. Über den EntityContext besteht Zugriff auf die Dienste des Containers unsetEntityContext() löschen der Umgebungsvariablen der BeanInstanz ejbCreate() Eine EntityBean-Instanz und ein neuer Primärschlüssel werden erzeugt und in die Datenbank übernommen (SQL INSERT). Ressourcen die in ejbActivate() angefordert werden, müssen hier ebenfalls gebunden werden, da ejbActivate() nicht mehr aufgerufen und die EB direkt initialisiert wird [BG02]. ejbLoad() Das Laden aller zur Bean gehörenden Daten aus der Datenbank (SQL SELECT). ejbActivate() Aktiviert eine Beaninstanz, die zuvor passiviert wurde. Sie bekommt dann eine Identität (der Primärschlüssel wird gesetzt ). ejbPassivate() Eine nicht benötigte Beaninstanz wird vorrübergehend serialisiert, um den Hauptspeicherplatz anderweitig zu vergeben Fortsetzung auf der nächsten Seite 3. Enterprise JavaBeans 45 Interface-Methode Funktion ejbStore() Eine EntityBeaninstanz wird persistent ge- CMP BMP - + macht, Änderungen werden in die Datenbank übernommen (SQL UPDATE). ejbRemove() Löschen der Beaninstanz (SQL DELETE). - + ejbFindBy<suffix>() Finder-Methoden liefern eine Instanz oder - + - * eine Menge von Instanzen der EB zurück . findByPrimaryKey ist eine Pflichtmethode, die in CMP als abstrakt definiert und nicht implementiert wird, in BMP implementiert werden muss. ejbSelect<suffix>() Liefern eine spezifizierte Datenmenge zurück und werden mit EJB-QL im Deploymentdeskriptor definiert. Legende: Implementierung notwendig +, Implementierung optional -, nicht Verfügbar * 3.3.4. Container Managed Relations Um Beziehungen zwischen verschiedenen persistenten Objekten herstellen zu können, bietet die EJB-Spezifikation die „Container Managed Relations“ an. Hierbei werden die Beziehungen vom EJB-Container verwaltet und persistent gespeichert. Wenn als Speichermedium eine relationale Datenbank dient werden sie über Fremdschlüssel abgebildet. Wie in Datenbanksystemen sind als Kardinalitäten 1 : 1, 1 : n und n : m möglich. Diese können sowohl uni- als auch bidirektional ausgelegt sein. Den Zugriff auf miteinander verbundene Objekte nennt man Navigation. So kann man z. B. über eine User-Entität zu deren E-MailAdressen navigieren. Der EJB-Container bietet für die Navigation Getter und Setter an, die man in der abstrakten Bean-Klasse definieren kann. Um die Beziehungen zu konfigurieren werden entsprechende Einträge im Deployment-Deskriptor vorgenommen. Es ist nur möglich, Beziehungen zwischen Entity Beans zu definieren, die in einem Deployment-Deskriptor beschrieben sind. Das hat den Grund, dass beim Deployment nur so sichergestellt werden kann, dass beide Beziehungspartner auch tatsächlich erreichbar sind. Der Zugriff auf Beziehungen einer Entity Bean ist laut Spezifikation nur von Local-Clients aus möglich. Das ist unter anderem ein Grund dafür, dass viele Entity Beans nur mit Local-Interfa- 46 3. Enterprise JavaBeans ces ausgestattet werden. Um Beziehungen zwischen den EBs abbilden zu können bedienen sich die Persistenztools des EJB-Containers üblicher Datenbankmittel. Bei 1:1 und 1:n Beziehungen werden Fremdschlüsselspalten eingerichtet, n:m Beziehungen werden mit Hilfe von Assoziationstabellen realisiert. Beim Deployment werden diese Tabellen erstellt, bei schon bestehenden Tabellen wird jedoch kein SQL alter table-Satement generiert. Das Mapping auf vorhandene Tabellen wird im Kapitel 4.5.2 erläutert. Die Container Managed Relations ermöglichen außerdem kaskadiertes Löschen (cascade deletes); wenn im Deployment-Deskriptor cascade-delete für eine Seite der Relation aktiviert wird, werden z. B. alle E-Mail-Adressen eines Benutzers gelöscht, sobald auch der User gelöscht wird. Listing 3.2: Definition von Container-managed-Relations 1 <relationships> 2 <ejb-relation> <!--User has Address--> 3 <ejb-relation-name>User-Address</ejb-relation-name> 4 <ejb-relationship-role> 5 <!--left--> <ejb-relationship-role-name>User-has-Addresses</ejb-relationshiprole-name> 6 <multiplicity>One</multiplicity> 7 <relationship-role-source> 8 9 10 11 12 13 <ejb-name>UserEntity</ejb-name> </relationship-role-source> <cmr-field> <cmr-field-name>addresses</cmr-field-name> <cmr-field-type>java.util.Collection</cmr-field-type> </cmr-field> 14 </ejb-relationship-role> 15 <ejb-relationship-role> 16 <!--Kardinalitaet Links--> <!--right--> <ejb-relationship-role-name>Addresses-of-User</ejb-relationship-role -name> 17 <multiplicity>Many</multiplicity> <!--Kardinalitaet Rechts --> 18 <cascade-delete/> <!--cascading deletes --> 19 20 <relationship-role-source> <ejb-name>AddressEntity</ejb-name> 21 </relationship-role-source> 22 <cmr-field> 23 <cmr-field-name>user</cmr-field-name> 3. Enterprise JavaBeans </cmr-field> 24 25 47 </ejb-relationship-role> 26 </ejb-relation> 27 </relationships> 3.3.5. Client-Sicht Die Sicht des Clients auf eine Entity Bean ist unabhängig von der Art des verwendeten Persistenzmechanismus. Da der Client nur Methoden an den beiden Interfaces aufruft, kann er nicht unterscheiden wie die Logik dahinter umgesetzt wird. Wie alle EJBs seit Version 2.0, können auch die Entity Beans sowohl von Remote- als auch von Local-Clients genutzt werden. Der Ablauf eines Clientzugriffs beginnt mit dem Erzeugen eines neuen EJB-Kontexts. Danach wird die Objektreferenz zum angegebenen Namen ermittelt und die Referenz in ein Home-Interface (local/remote) umgewandelt. Anschließend können die Methoden des Interfaces ausgeführt werden (create, find, remove). Je nach gewählter Methode erhält man ein Objekt, welches das Komponenten-Interface implementiert und kann die entsprechenden Geschäftsmethoden ausführen. In Listing 3.3 ist der Ablauf nachzuverfolgen. Listing 3.3: Clientaufruf an einer Local-Entity Bean 1 //JNDI Kontext ermitteln 2 InitialContext jndiContext = new InitialContext(); 3 //LocalHome Erzeugen, durch Nachschlagen im JNDI Verzeichnis 4 UserEntityLocalHome uelhome = (UserEntityLocalHome) 5 jndiContext.lookup("java:comp/env/UserEntityLocal"); 6 //Entity mit Referenz belegen 7 UserEntityLocal uel = uelhome.findByPrimaryKey(ID); 8 //Geschäftsmethoden am Component-Interface ausführen 9 UserDTO myUserBean = uel.getUserDTO(); Das Beispiel benutzt nur Local-Interfaces, da Entity Beans grundsätzlich über eine Session-Fassade (vgl. Kapitel 5.3.3) angesprochen werden sollten. Ein Beispiel für den Ablauf an einer Remote-Schnittstelle wird bei den Session Beans gegeben. Es ist auch möglich Interfaces für Remote- und Local-Clients anzubieten. 48 3. Enterprise JavaBeans 3.3.6. Alternativen für persistente Objekte Sun Microsystems hat mit den Entity Beans eine Technik geschaffen, um den Impedance Mismatch innerhalb der J2EE zu vermeiden. Um auch andere Java-Programme von einer solchen Technik profitieren lassen zu können, wurde zwischen 1999 und 2002 die Java Data Object-Spezifikation 1.0 (JDO) entwickelt. Diese freie Spezifikation wurde durch den Java Community Process angeregt. Sie ermöglicht es, Java-Objekte persistent in einem Speichermedium abzulegen. Dabei ist der Einsatz von SQL via JDBC vor dem Entwickler verborgen. Die Java Data Objects stellten sich als schnell zu erlernen und mit geringerem Aufwand zu implementieren heraus. Entity Beans hingegen wurden von vielen Programmierern als umständlich und zeitaufwändig eingeschätzt. So liegt es nahe, JDO auch in Enterprise-Systemen einsetzen zu wollen. Dabei kann JDO die gesamte Funktionalität der Entity Beans übernehmen und direkt aus Session Beans heraus eingesetzt werden. JDO ist eine API-Spezifikation, zu der zusätzlich eine Implementierung benötigt wird. Um Java-Objekte persistent zu machen benötigt man mit JDO, ebenso wie bei Entity Beans eine Datei mit Metadaten. In XML wird beschrieben, welche Felder der Klasse persistiert werden sollen. Um aus den einfachen Java-Klassen nun persistente Objekte erzeugen zu können, arbeitet JDO mit der umstrittenen Methode des Bytecode-Enhancements. Dabei wird der Bytecode der kompilierten Klasse mit Hilfe der Metadaten-Datei erweitert. Um JDO zu benutzen, benötigt man einen Bytecode-Enhancer, der durch die JDO-Implementation zur Verfügung gestellt wird. Viele Programmierer mögen diese Technik nicht, da sie nicht mehr genau wissen, was in ihren Klassen für Code erzeugt wurde. Auch lassen sich die Bytecode-Enhancer (noch) nicht in alle IDEs integrieren (vgl. [BE03]). Wenn man sich dazu entschieden hat, JDO in seinen Projekten einzusetzen, kann man dies sowohl in Desktop-Applikationen als auch in J2EE-Anwendungen tun. Das verringert die Anzahl der verwendeten Technologien und sorgt so für mehr Produktivität. Die JBoss Group hat den Trend zu JDO erkannt und stellt mit JBossDO eine Implementierung von JDO ab JBoss v.4.0 zur Verfügung. Dabei wird auch eine Bytecode-Enhancer geliefert, der jedoch in den Hot-Deployment-Mechanismus des JBoss integriert ist. Das bedeutet, dass erst während der Installation auf dem Server das Bytecode-Enhancement statt- 3. Enterprise JavaBeans 49 findet. Dadurch ändert sich bei der Entwicklung der Klassen weniger und die Unterstützung innerhalb der IDEs bleibt gewahrt. 3.4. Session Beans Während Entity Beans die Geschäftsdaten repräsentieren, sind Session Beans für die Geschäftsabläufe zuständig. Auch bei den Session Beans gibt es zwei Ausprägungen, zum einen die zustandslosen Session Beans (stateless), zum anderen die zustandsbehafteten Session Beans (stateful). 3.4.1. Stateless Session Beans Die stateless Session Beans werden keinem speziellen Client zugeordnet. Sie werden vom Container so verwaltet, dass immer eine bestimmte Anzahl ihrer Instanzen in einem „Pool“ gehalten werden. Wenn ein Client eine Methode an ihrem Remote- oder Local-Interface aufruft wird eine Instanz aus dem Pool für die Dauer eines Methodenaufrufes dem Client zugeordnet. Da sie keine Daten über ihren Zustand speichern müssen, kann der Container diesen Pool nach Belieben verwalten (z. B. Löschen statt Passivieren). Man spricht bei stateless Session Beans von leichtgewichtigen Komponenten. Stateless Session Beans kennen nur zwei Zustände: • nicht existent • im Pool befindlich und bereit („pooled ready“) In der Abbildung 3.6 sind die Übergänge zwischen den Zuständen dargestellt. Class.newInstance () setSessionContext (ctx) ejbCreate (args) Existiert nicht im Pool bereit (pooled-ready) ejbRemove () Vom Container initiiert Client - Methodenaufruf Abb. 3.6: Lebenszyklus: stateless Session Bean 50 3. Enterprise JavaBeans Wenn ein Client eine Instanz anfordert, kann der EJB-Container den Client entweder aus dem Pool bedienen oder muss eine Instanz erzeugen. Diese bleibt dann im Pool und wartet auf Anfragen der Clients. Dieses Verhalten kann man mit statischen Methoden in JavaKlassen vergleichen. 3.4.2. Stateful Session Beans Mit den stateful Session Beans können Informationen über die Sitzung eines Clients verwaltet werden. Anders als die stateless Session Beans sind sie nur einem speziellen Client während der Dauer seiner Sitzung zugeordnet. Somit ist es möglich, voneinander abhängige Aufgaben abzuarbeiten. Die Aktionen, die ein Client während seiner Sitzung ausführt, bezeichnet man auch als Konversation mit der Anwendung. Der Konversationszustand (conversational state) beschreibt dabei den Zustand der zugeordneten Session Bean-Instanz. Also den Wert aller Attribute und mit der Bean verbundenen Objekte, den so genannten Objektgraph. Eine stateful Session Bean kann vom Container passiviert werden, um die Menge der Objekte zu begrenzen und Speicherplatz freizugeben. Dabei wird mittels Serialisierung das Objekt als Bytestrom auf einen Datenträger (vorzugsweise eine Festplatte) gespeichert. Um dies zu ermöglichen, müssen alle Objekte des Objektgraphen serialisierbar sein, also das Interface java.io.Serializable implementieren. Da z. B. Datenbankverbindungen oder andere genutzte EJBs nicht serialisierbar sind, können diese Ressourcen als transient2 gekennzeichnet werden. Der Zustandswechsel erfolgt, wie andere auch, über den Aufruf der Callbackmethoden. Beim Aufruf von ejbPassivate() sollten also innerhalb dieser Methode alle als nicht transient gekennzeichnete Datenbankverbindungen geschlossen werden und alle Objekte, die nicht serialisierbar sind, eine null-Referenz zugewiesen bekommen. Bei der Aktivierung, also der Deserialisierung des Objektes wird die Methode ejbActivate() aufgerufen. Innerhalb dieser Methode können die Referenzen wieder hergestellt und die Datenbankverbindung erneut aufgebaut werden. 2 transient nach dict.leo.org: flüchtig, kurzlebig 3. Enterprise JavaBeans 51 Daraus ergibt sich für die stateful Session Beans folgender Lebenszyklus: Bean-Instanz oder Transaktion löst eine System-Ausnahme aus Class.newInstance () setSession Context (ctx) ejbCreate (args) Transaktionsmethode afterBegin() im Pool bereit (pooled-ready) Existiert nicht ejbRemove () commit beforeCompletion() afterCompletion(true) bereit in Transaktion (method-ready in TX) afterCompletion(false) rollback Transaktionsmethode ejbPassivate() Timeout ejbActivate() durch (Geschäftsmethoden-Aufruf) passiv Client - Methodenaufruf Vom Container initiiert Abb. 3.7: Lebenszyklus: stateful Session Bean Da die Serialisierung von Objekten eine rechenintensive Aufgabe ist und der Zugriff auf das Speichermedium ebenfalls eine langsame Operation, spricht man bei stateful Session Beans von „schwergewichtigen Komponenten“. Die Methoden von Session Beans können über Transaktionen gesichert werden. Dabei ist es nicht nur möglich, jede einzelne Methode in eine eigene Transaktion zu verpacken, sondern auch mehrere Methoden in einer Transaktion ablaufen zu lassen. Wenn mehrere Methoden in einer Transaktion zusammengefasst werden, ändert sich der Zustand der Bean in „ready in TX“. Nach Beendigung der Transaktion kehrt das Beanobjekt wieder in den Zustand „bereit“ zurück. 3.4.3. Client-Sicht Der Client, der auf eine Session Bean zugreift, läuft oftmals nicht innerhalb der gleichen JVM ab (z. B. von einem Web-Server aus). Dadurch ist ein Zugriff auf ein mögliches Local-Interface einer Session Bean seltener realisierbar als bei Entity Beans, die in der Regel über eine Session-Fassade (vgl. 5.3.3) angesprochen werden. Am folgenden Code-Beispiel (Listing 3.4) soll gezeigt werden, wie eine Session Bean über ihr Remote-Interface angesprochen wird. 52 3. Enterprise JavaBeans Listing 3.4: Clientaufruf an einer Remote-Session Bean 1 private UserSFHome usrSFHome; 2 //JNDI Kontext ermitteln 3 private Context ctx = new InitialContext(); 4 /*Home Erzeugen, durch Nachschlagen im JNDI Verzeichnis 5 Cast des Remote-Objekts. Über die statische Methode 6 PortableRemoteObject.narrow wird der Rückgabewert 7 Object der lookup-Methode in den korrekten Interfacetyp 8 9 10 gecastet. Dies ist eine Beschränkung von RMI-IIOP.*/ usrSFHome = (UserSFHome) PortableRemoteObject.narrow( ctx.lookup("/UserSF"),UserSFHome.class); 11 //Erzeugen der Referenz auf die Beanklasse 12 //(SessionBean ist im Pool oder wird in den Pool geladen) 13 UserSF usf = usrSFHome.create(); 14 //Geschäftsmethoden am Component-Interface ausführen 15 UserDTO myUserBean = usf.getUserData(ID); 3.5. Message-Driven Beans Message-Driven Beans (MDB) sind erst in der EJB-Spezifikation 2.0 eingeführt worden. Hierbei handelt es sich, anders als bei den vorher dargestellten Enterprise JavaBean-Arten, um asynchron arbeitende Komponenten. Das heißt, dass ein Client durch die Benutzung einer Nachrichten-gesteuerten Infrastruktur nicht dadurch blockiert wird, dass er auf das Ergebnis seiner Anfrage warten muss. Um dem Client bzw. einem Client-Prozess diese asynchrone Kommunikation bieten zu können, nutzen Message-Driven Beans den Java Message Service (JMS). Mit Hilfe von JMS bietet also die EJB-Spezifikation 2.0 die Nutzung einer „Message oriented Middleware“ (MOM) an. Ziel solcher Systeme ist die Entkopplung von Sendern und Empfängern. Durch ihren Einsatz hat ein Prozess die Möglichkeit, an viele „interessierte Empfänger“ Nachrichten senden zu können. Gesendete Nachrichten können in eine Warteschlange (Queue) aufgenommen und an verfügbare Empfänger weitergeleitet werden. Falls ein Emfänger ausgefallen ist, verbleibt die Nachricht in der Queue oder wird vorübergehend persistent gespeichert. Dies dient der Güte der Nachrichtenübermittlung und garantiert, dass die Nachrichten nicht verloren gehen. Es gibt verschiedene Stufen für die Übertragungssicherheit der Nachrichten, die im Messaging-System eingestellt werden können. 3. Enterprise JavaBeans 53 Durch die Entkopplung des Nachrichtenübertragungs-Mechanismus können sich Anwendungsentwickler stärker auf die Implementierung der Geschäftslogik konzentrieren. Das Messaging System wird vom Anwendungsentwickler mit der Gewissheit benutzt, dass die Kommunikation seinen Güteanforderungen gerecht wird. Um Message-Driven Beans benutzen zu können, muss man die angebotenen Modi von JMS verstehen. JMS bietet über verschiedene Interfaces folgene Kommunikationsmodelle: • Publish-Subscribe (1:n) • Point-to-Point (1:1) Publisher 3 2 Sender 7 6 5 Topic 6 Queue 4 5 4 1 1 1 3 1 2 Client Client Client Client Client Client Abb. 3.8: Die Modi des JMS Je nach Anforderung an die benötigte Inter-Prozess-Kommunikation benutzt man die verschiedenen Modi. Der Publish-Subscribe Modus ist vergleichbar mit einer Newsgroup. Ein oder mehrere Message-Producer (Nachrichten-Produzenten) senden ihre Nachricht zu einem registrierten „topic“ (Thema). Die Message-Consumer (Nachrichten-Empfänger) können ein solches Topic abonnieren (engl. subscribe) und erhalten die dort eingegangenen Nachrichten, sobald sie für den Empfang „verfügbar sind“. Der Point-to-Point-Modus gibt dem Nachrichten-Produzenten die Möglichkeit seine Nachricht an genau einen interessierten Nachrichten-Empfänger zu senden. Sinnvoll ist dies 54 3. Enterprise JavaBeans z. B., wenn es für den Sender unwichtig ist, welcher Empfänger seine Nachricht zur Verarbeitung erhält, wobei er jedoch sicher sein will, dass sie nur einmal verarbeitet wird. Dieses Modell ist z. B. für Lastverteilung einsetzbar. Message-Driven Beans können von Clients also nicht direkt und auch nicht über ein bereitgestelltes Interface angesprochen werden. Ein Nachrichten-Produzent, z. B. eine stateless Session Bean, sendet eine Nachricht mit Hilfe der vom JMS bereitgestellten Interfaces an ein topic oder eine queue. Eine Message-Driven Bean fungiert als Empfänger dieser Nachricht. Wird eine Nachricht empfangen, wird die onMessage-Methode der MDB ausgeführt. Der Lebenszyklus einer MDB ist ebenso einfach gehalten wie der einer stateless Session Bean und kann in der Grafik 3.9 nachvollzogen werden. Existiert nicht Class.newInstance () setSessionContext (ctx) ejbCreate (args) onMessage() im Pool bereit (pooled-ready) ejbRemove () Abb. 3.9: Lebenszyklus: Message-Driven Bean Wann die Nachricht empfangen wird, kann hierbei nicht bestimmt werden und hängt von der Verfügbarkeit der MDB und dem gesamten Nachrichtenaufkommen ab. Beim Pointto-Point-Modus werden die Nachrichten nach dem „FIFO“-Prinzip (first-in first-out) zugestellt. Die JMS-Interfaces bieten die Methoden an um Nachrichten zu erstellen und an ein bestimmtes Ziel zu versenden. Dazu wird zunächst ein Connection-Factory-Objekt benutzt, das auf einen Modus spezialisiert ist: javax.jms.QueueConnectionFactory bzw. javax.jms.TopicConnectionFactory. Die Objekte dieser Factories werden bei J2EE vom EJB-Container zur Verfügung gestellt und mittels JNDI-Lookup gebunden. Sie werden beim Serverstart erzeugt und stehen dann für alle Nachrichten-Erzeuger zur Verfügung. „Laut JMS-Spezifikation ist es die Aufgabe des Administrators, Connection-Factories zu konfigurieren. Man nennt sie deshalb auch Administered Objects“ [DP02]. Die 3. Enterprise JavaBeans 55 ConnectionFactory bietet eine Methode zum Erzeugen einer Connection (Topic oder Queue). Mit dem erhaltenen Connection-Objekt wird eine Session erzeugt, über welchedie Nachrichtenobjekte gesendet oder empfangen werden können. Das Interface javax.jms.Destination bietet die queue- und topic-Objekte an, die als Ziel der Nachrichten angegeben werden. Diese Objekte werden ebenfalls durch den Server-Administrator konfiguriert und beim Serverstart über JNDI zur Verfügung gestellt. Die eigentliche Nachricht wird mittels javax.jms.Message definiert. Eine Nachricht besteht aus drei Teilen. Der erste Teil ist der Header. Hier können Informationen zur Nachricht wie z. B. Nachrichten-ID zur Unterscheidung der im System befindlichen Nachrichten gespeichert werden. Der nächste Teil der Nachricht sind die Properties. Dort können zusätzliche Informationen gespeichert werden, die z. B. die Identität des Senders enthalten. Empfänger können auch Filter einrichten, um nur bestimmte Nachrichten zu verarbeiten. Solche Filterinformationen beziehen sich auf die property-Felder einer Nachricht. Der Hauptteil der Nachricht ist der Body. Möglich sind folgende Objekte im so genannten payload der Nachricht [MHC01]: • javax.jms.TextMessage: für eine Textnachricht, die auch ein bestimmtes Format erfüllen könnte (z. B. HTML). • javax.jms.ByteMessage: Hier wird im Nachrichtenrumpf ein Byte-Strom gesendet. Das kann sowohl ein serialisiertes Objekt oder auch ein Bild sein. Der Empfänger muss diesen Byte-Strom verarbeiten können. • javax.jms.StreamMessage: Der Datenstrom muss in der richtigen Reihenfolge vom Empfänger eingelesen werden. • javax.jms.MapMessage: Hier werden Schlüssel-Wert-Paare in der Nachricht gesendet. Diese können benutzt werden wie z. B. HashMaps in Java. • javax.jms.ObjectMessage: Hier kann jegliches serialisierbares Java-Objekt gesendet werden. Die Message-Driven Beans fungieren nicht direkt als Nachrichten-Empfänger. Alle Nachrichten werden vom EJB-Container empfangen und an die entsprechenden MDBs weitergeleitet. Dazu wird im Deployment-Deskriptor der MDBs konfiguriert, ob an einer queue oder einem 56 3. Enterprise JavaBeans topic die Nachrichten eintreffen und ob die Transaktionssicherheit der Netzwerkverarbeitung durch den Container oder durch die Bean selbst stattfindet. Sobald eine MDB aktiviert wird (etwa nach einem Neustart), werden die für sie bestimmten Nachrichten durch den Container zugestellt. Message-Driven Beans werden häufig dazu eingesetzt, die Performance von Anwendungen zu erhöhen. Da das Antwortverhalten spürbar gebessert wird, sehen die Nutzer die Gesamtanwendung als schneller an. Alle langwierigen Prozesse, wie große Eintragungen in eine Datenbank oder Textdateien die in die Datenbank geschrieben werden, sollten durch den Einsatz von MDBs vom User entkoppelt werden. Über Queues können auch Batchprozesse, wie sie im Mainframeumfeld bekannt sind, abgearbeitet werden. Wenn eine Queue eine entsprechende Anzahl von Nachrichten enthält, können diese zugestellt und zu lastarmen Zeiten abgearbeitet werden. 3.6. Transaktionen Unter einer Transaktion wird eine Folge von Datenbankoperationen verstanden, die den Zustand der Daten einer Datenbank von einem konsistenten in einen anderen konsistenten Zustand überführt. Dabei erfüllen Transaktionen das so genannte ACID-Prinzip (nach [HS00] und [Ric01]): • Atomicity (Atomarität): Eine Transaktion wird als unteilbar angesehen. Sie kann also nur als Ganzes abgeschlossen werden (commit) oder alle Änderungen am Datenbestand, z. B. bei einem aufgetretenen Fehler, werden zurückgesetzt (rollback). Dadurch ist und bleibt der Zustand konsistent. • Consistency (Konsistenz): Ein Datenbestand wird während einer Transaktion von einem konsistenten Zustand in einen neuen konsistenten Zustand überführt oder ist nach der Transaktion im gleichen konsistenten Zustand wie zuvor. Die Transaktion erfüllt bei ihrer Durchführung die Bedingungen des zugrundeliegenden Systems, welches festlegt was konsistente Daten sind. • Isolation (Isolation): Transaktionen laufen ab, als hätten sie exklusiven Zugriff auf die Datenbank. Parallel ablaufende Transaktionen werden nicht beeinflusst. Das Datenbank Management System garantiert die Isolation der Transaktionen durch ver- 3. Enterprise JavaBeans 57 schiedene Verfahren, wie z. B. Sperrung von Daten (locking). Dadurch werden inkonsistente Zustände, die während einer Transaktion auftreten können, vor anderen Transaktionen verborgen. Gegebenenfalls werden die Transaktionen seriell ausgeführt. (vgl. [Ric01] Stichworte: Isolationsstufen, Dirty Read, Phantom Read). Zur Steigerung der Performance werden bei den Isolationsstufen einige möglicherweise auftretende Inkonsistenzen zugelassen. Dabei ist es wichtig zu überprüfen wie sicher eine Applikation gegenüber solchen Inkonsistenzen sein muss. Es sind z. B. BankTransaktionen anders zu bewerten, als Einträge in ein Bug-Tracking-System3 . • Durability (Dauerhaftigkeit): Die Datenänderungen einer erfolgreich abgeschlossenen Transaktion werden dauerhaft gespeichert und stehen danach anderen Anfragen und Transaktionen zur Vefügung. Die Enterprise JavaBeans sind eine transaktionale Komponententechnologie. Sie unterstützen auf verschiedene Weise die Nutzung von Transaktionen. Diese können sowohl vom Client, von einer Enterprise JavaBean, als auch (deklarativ) vom Container gesteuert werden. Client-gesteuerte Transaktionen werden von Remote-Clients gestartet. Alle Aufrufe zwischen begin und commit bzw. rollback laufen dann als eine Transaktion ab. Der Client benötigt für den Start der Transaktion ein Objekt der Klasse javax.transaction. UserTransaction, das über einen JNDI-Lookup vom EJB-Container ermittelt werden kann. Alle Methoden, die innerhalb der Client-Transaktion ablaufen, müssen Transaktionen unterstützen. Sie nehmen an der Transaktion teil, wenn im Deployment-Deskriptor der Bean nicht das Transaktionsattribut never deklariert wurde. (nach [BG02]) Bean-gesteuerte Transaktionen werden, wie der Name schon sagt, innerhalb einer BeanKlasse deklariert. Man bezeichnet sie auch als explizite Transaktionen. Dazu benötigt die Bean-Klasse ebenfalls ein UserTransaction-Objekt, das über den EJB-Context vom Container zur Verfügung gestellt wird. Zu Beginn der durch eine Transaktion zu sichernden Methoden wird die Methode begin des Transaktions-Objekts aufgerufen. Nach fehlerfreier Beendigung wird commit aufgerufen. Im Fehlerfall (im catch-Block) wird die Methode rollback aufgerufen. Die beiden Lösungen zur Steuerung von Transaktionen sind aufwändiger in ihrer Programmierung, bei manchen Anwendungsfällen jedoch unabdingbar (vgl. [BG02]). 3 Ein System, das Entwicklern und Anwendern ermöglicht über Fehler in einer Anwendung zu berichten. 58 3. Enterprise JavaBeans Die J2EE-Spezifikation rät zum Einsatz der Container-gesteuerten Transaktionen. Bei der container-managed transaction demarcation werden die Transaktionsgrenzen für Methoden im Deployment-Deskriptor der Bean deklariert. Der Container kümmert sich um die Umsetzung dieser Anweisungen. Dadurch können Transaktionen leichter festgelegt und bei der Änderung von Systembedingungen angepasst werden. Damit der Container seiner Aufgabe nachkommen kann wird, wie auch bei der Überprüfung von sicherheitsrelevanten Angaben (JAAS), der Interceptionmechanismus benutzt. Die Ausführung der Methode wird demnach so lange unterbrochen bis eine Transaktion gestartet wurde und dann innerhalb dieser Transaktion fortgesetzt. Wie auch bereits bei der expliziten Transaktionssteuerung innerhalb von Beans angesprochen, gibt es verschiedene Transaktionsattribute, die festlegen, auf welche Art Transaktionen von Methoden unterstützt werden. Gültige Einträge für das Tag <trans-attribute> und deren Bedeutung sind im Folgenden aufgeführt [SM01a]: • Required: Die Methode benötigt eine Transaktion für ihre Ausführung. Dabei kann eine bestehende Transaktion genutzt werden oder eine neue Transaktion wird gestartet, die nach Abschluß der Methode beendet wird. • RequiresNew: Eine Methode mit diesem Transaktionsattribut kann nicht in einer bestehenden Transaktion ausgeführt werden und fordert daher eine neue Transaktion an. Wenn diese Methode während einer bereits gestarteten Transaktion aufgerufen wird, wird die bestehende Transaktion unterbrochen und nach Beendigung der neuen Transaktion fortgesetzt. • Mandatory: Ist für Methoden gedacht, die als Teil einer anderen Transaktion ablaufen sollen. Dabei überprüft der Container, ob eine Transaktion gestartet wurde. Wenn dies nicht der Fall ist, wird eine Ausnahme ausgelöst. • Supports: Die Methode, die derart deklariert ist, kann sowohl innerhalb als auch ohne eine Transaktion ausgeführt werden. Die Methode darf, wenn sie ohne Transaktionssicherung ausgeführt wird, keinen inkonsistenten Datenzustand schaffen. • NotSupported: Dieses Attribut bedeutet, dass die Methode keine Transaktionen unterstützt. Eine laufende Transaktion, in der eine derart deklarierte Methode abläuft, wird unterbrochen und nach Abschluss der Methode fortgesetzt. 3. Enterprise JavaBeans 59 „Der Einsatz von NotSupported bietet sich an, wenn in der Methode auf nicht transaktionsfähige Ressourcen zugegriffen wird.“[BG02] • Never: Es werden keine Transaktionen unterstützt. Eine solche Methode wirft eine Ausnahme, wenn sie innerhalb einer Transaktion ausgeführt wird, und startet selbst niemals eine eigene Transaktion. Die Deklaration der Transaktionsattribute ist jedoch auch abhängig vom Typ der entsprechenden EJB. In der Tabelle 3.2 sind die zulässigen Attribute in Abhängigkeit vom EJB-Typ aufgeführt. Dazu ist zu bemerken, dass bei Message-Driven Beans die einzige Methode, die durch den Container transaktional gesichert werden kann, die onMessage()-Methode ist. Tabelle 3.2.: Transaktionsattribute der EJB-Typen (CMT) (nach [SDD02]) Transaktions- EntityBean SessionBean Attribut stateful SessionBean Message-driven- (implements Bean SessionSynchronisation) Required + + + + RequiresNew + + + - Mandatory + + + - Supports - + - - NotSupported - + - + Never - + - - Legende: zulässig +, unzulässig - Um bei verteilten Anwendungen Transaktionen sicher durchführen zu können, benötigt der Transaktionsmanager des DBMS einen Mechanismus, um zu überprüfen, ob alle Aktionen sicher abgeschlossen wurden. Dazu wurde das two-phase-commit-Protokoll entwickelt, das auch im J2EE-Umfeld Anwendung findet. Der Transaktionsmanager fragt alle an der Transaktion Beteiligten, ob ihre Methode vollständig durchgeführt werden konnte. Wenn alle dies mit Ja beantworten, sendet der Transaktionsmanager den Befehl zum commit, anderenfalls wird rollback auslöst. 4. JBoss Application Server Der JBoss Application-Server ist ein freier1 , Open-Source J2EE-Server. Ursprünglich ist er als EJBoss in Version 1.0 gestartet und hat sich seither bis zur aktuell stabilen Version 3.2 weiterentwickelt. Laut Entwicklerteam ist der Server vollständig J2EE-1.3 kompatibel, jedoch ist er bislang noch nicht von Sun zertifiziert worden. 4.1. Architektur des JBoss Die Architektur des JBoss basiert auf einem Micro-Kernel. Dieser c.a. 200KB kleine und effiziente Kern bildet die Basis, um alle Bestandteile, die der JBoss als J2EE-Server benötigt, anzubinden. Er basiert auf der Java Management Extension (JMX) [McM02] und stellt einen MBean-Server2 dar. 4.1.1. Java Management Extension Die JMX ist eine Management-Architektur, bestehend aus Entwurfsmustern, einer API und Diensten für Netzwerk- und Applikations-Management. JMX wird in drei Ebenen unterteilt: • Distributed Service Level: In dieser Schicht befinden sich Management-Applikationen. Diese können als HTML-Oberfläche in einem Browser oder als Client-Anwendung mit grafischer Benutzeroberfläche (z. B. Swing-Client) dargestellt werden. Um auf den MBean-Server zugreifen zu können, benötigen die Management-Anwendungen einen entsprechenden Protokoll-Adapter oder einen Connector und dessen Stell1 2 JBoss wird unter der LGPL (lesser gnu public license) veröffentlicht Managed Bean 62 4. JBoss Application Server vertreter-Objekt (Proxy). Diese übersetzen z. B. die Aufrufe und Antworten des MBean-Servers. Dadurch ist es möglich, Protokolle wie SNMP3 zu unterstützen. • Agent Level: Hier befindet sich der MBean-Server und MBeans, die als Agenten fungieren und die JMX-Standarddienste bereitstellen. Am MBean-Server registrieren sich alle MBeans und sind so über ihren Namen mittels JNDI auffindbar. • Instrumentation Level: In dieser Schicht befinden sich MBeans, welche die zu überwachenden Ressourcen darstellen. Diese Ressourcen können sowohl Programme, als auch Dienste oder sogar Hardware-Komponenten sein. Die Kommunikation mit den Agenten-MBeans der oberen Schicht geschieht über ein Ereignismodell. In Abbildung 4.1 wird der Aufbau der JMX-Architektur des JBoss dargestellt. Distributed Service Level Management Client Browser Proxy Protocol Adaptor Connector MBean-Server Agent Level Agent Service MBean Instrumentation Level Application Resource MBean Agent Service MBean Application Resource MBean Abb. 4.1: JMX-Architektur Die Standarddienste, die von den MBeans des Agent-Level bereitgestellt werden sind: • Timer Service: Zeitgesteuerte Benachrichtigungen von Komponenten und Auslösen von Aktionen • MLet Service: Dynamisches Laden von Klassen und Komponenten 3 Simple Network Management Protocol 4. JBoss Application Server 63 • Monitoring Service: Überwachen von Attributwert-Änderungen und Benachrichtigungen bei Bedarf • Relation Service: Verbindungen zwischen Komponenten definieren und aufrechterhalten MBeans sind Java-Objekte, deren Klassen nach den JMX-Restriktionen entwickelt werden. Sie müssen ein Management-Interface bereitstellen, um für Agenten konfigurierbar zu sein. Jede MBean hat einen eindeutigen Namen im MBean-Server, über den sie angesprochen werden kann. 4.1.2. Aufbau des JBoss-Kerns Da JMX bei der Entwicklung nicht zum Ziel hatte als Kern eines Application-Servers zu fungieren, lag das Hauptaugenmerk nicht auf der Performance. Die JBoss-Group entschied sich jedoch trotzdem einen JMX-Kern für ihren Application-Servers zu entwickeln, um die Vorteile des Managements und der Anbindung von Komponenten zu nutzen. Daher mussten einige Performanceverbesserungen vorgenommen werden. So stellte man fest, dass von den verschiedenen MBean-Arten (standard, dynamic, open und model) die Standard-MBeans wesentlich höhere Ausführungszeiten als dynamic-MBeans hatten. Durch den Einsatz von Caching-Mechanismen und der Bytecode Engineering Libary (BCEL4 ) zur Vermeidung von Reflections (vgl. 2.2.2) konnte die Performance exponentiell gesteigert werden [FL02]. Im JBoss stehen zwei der vier möglichen MBean-Varianten zur Verfügung, StandardMBeans und Dynamic-MBeans. Um eigene MBeans zu entwickeln, die auf dem JBossMX laufen, müssen die JMX-Restriktionen eingehalten werden. Dies befähigt den JBoss jedoch noch nicht den Lebenszyklus der Eigenentwicklung zu steuern. Um dies zu erreichen muss zusätzlich das Interface org.jboss.system.Service implementiert werden, das Methoden zum Erzeugen, Starten, Stoppen und Zerstören von MBean-Instanzen bereitstellt [Kun02]. Ein gutes Beispiel für die Flexibilität dieser Architektur ist der einfache Austausch der Servlet-Container Jetty und Tomcat. So wie diese Bestandteile sind auch der EJB-Container, die JAAS-Security-Komponente und alle an den JMX-Bus angeschlossenen Komponenten nach eigenen Wünschen austauschbar oder, wenn nicht benötigt, abschaltbar. 4 http://jakarta.apache.org/bcel 64 4. JBoss Application Server In Abbildung 4.2 sind der JBoss-Kern, der als JBoss Server Spine bezeichnet wird, und einige daran angeschlossenen Komponenten zu sehen. Container Managed Persistence J2EE Web Container Integration Transactions JCA/JTA Eigene MBean JBoss CMP Web Container JBoss TX Eigener Dienst JBoss Server Spine JMX-Bus JBossSX JAAS Security JBossMQ JMS Messaging EJB EJB Container JBossNS JNDI Abb. 4.2: JBoss-Kern (JMX-Bus) und einige angeschlossene Komponenten Beim Start des JBoss wird zuerst eine Instanz des JBossMX Micro-Kernels gestartet, danach werden alle benötigten Komponenten via Hot-Deployment eingebunden. Sobald dieser Vorgang abgeschlossen ist, kann JBoss die Dienste der einzelnen Komponenten allen anderen zur Verfügung stellen. „Dieses Design passt besonders gut zur J2EE-Plattform, welche im Grunde auch eine Service-basierte Plattform ist.“ [Kun02] Durch das Hot-Deployment sind die Dienste des JBoss zur Laufzeit konfigurierbar. Das bedeutet, dass neue Dienste genau wie neue J2EE- und Web-Applikationen während des Betriebs angeschlossen, abgeschaltet oder geändert werden können. 4.1.3. JBoss Interceptor-Architektur Beim Registrieren einer MBean erzeugt der JBoss eine Instanz eines Invokers. Das Ausführen einer Methode am Interface einer MBean geschieht nicht über eine direkte Referenz zum MBean-Objekt, sondern durch einen Serveraufruf, der an den vor die MBean geschalteten Invoker weitergeleitet wird. Ein Aufruf hat dann folgende Signatur: MBeanServer.invoke("MBean_Name","Methoden_Name", Argumente). Diese Entkopplung unterstützt den modularen Aufbau des Systems. Der Invoker ist in der Lage, Aufrufe zu einer MBean zu unterbrechen (Interception). Dieser Mechanismus existiert beim EJB-Container des JBoss um funktionale Aspekte wie Transaktionen und Sicherheit bereitzustellen. Bei den MBeans werden Interceptions vor allem benutzt um das 4. JBoss Application Server 65 Hot-Deployment (vgl. 4.2.3) zu ermöglichen. Bei einer Änderung an einem Service, muss die Ausführung einer Methode unterbrochen werden. Die Interceptions des EJB-Containers sind eine spezialisierte Form der MBean-Interceptions [FL02]. Abbildung 4.3 zeigt den beschriebenen Aufbau und die Anordnung der Interceptoren. Application Resource MBean Interceptors ... Transaction Logging Access Control Invoker MBean-Server Abb. 4.3: Invoker und nachgeschaltete funktionale Aspekte 4.2. Deployment Wie bereits erwähnt, bezeichnet Deployment den Vorgang des Installierens einer Anwendung auf einem Application-Server. Um dies zu ermöglichen bietet der JBoss einen Deployment-Dienst für die verschiedenen Applikationstypen an. Diese Deployment-Komponenten sind konsequenter Weise als MBeans realisiert. Sie überwachen das deploy-Verzeichnis der aktuellen Konfiguration (vgl. 4.5) und reagieren auf geänderte oder neu zu installierende Anwendungen. Eine der Hauptaufgaben der Deployment-Komponenten ist das Auflösen von Klassen-Abhängigkeiten der einzelnen Komponenten. Um dies zu erreichen, wird ein spezielles Classloader-Konzept beim JBoss eingesetzt, das im folgenden Abschnitt beschrieben wird. 4.2.1. JBoss Classloading Beim Deployment wird ein Classloader für die zu installierende Anwendung erzeugt. Classloader sind hierarchisch aufgebaut und werden genutzt, um Klassen dynamisch in die JVM zu laden. Dabei wird beim Suchen einer referenzierten Klasse zuerst beim Parent-Class- 66 4. JBoss Application Server loader nachgefragt, ob die Klasse verfügbar ist. Wenn kein Parent-Classloader Zugriff hat, sucht der ursprüngliche Classloader im Classpath selbst nach der Klasse. Durch den hierarchischen Aufbau der Classloader ist es möglich, dass benachbarte (auf einer Ebene befindliche) Classloader eine Klasse jeweils einmal in den Speicher laden. Um dies zu verhindern und somit Speicherkapazität zu sparen, benutzt der JBoss ab Version 3.0 ein „Shared Repository“, in dem die geladenen Klassen verzeichnet sind. Ein UnifiedClassLoader wird als Parent-Classloader der zu installierenden Anwendungen benutzt, um Klassen im Shared Repository zu finden [Kun02]. Dabei kann aber auch ein Versionskonflikt entstehen. Wenn eine Klasse in verschiedenen Versionen vorliegt, benutzt JBoss die zuerst gefundene Klasse, da das „Shared Repositry“ keine Versionskontrolle bietet. In diesem Fall kann jedoch der Classloading-Mechanismus der Servlet-2.3-Spezifikation eingesetzt werden, bei dem im META-INF-Verzeichnis der Anwendung in der Manifest-Datei Angaben zu Klassen und Pfaden gemacht werden können. Diese werden berücksichtigt, bevor ein Parent-Classloader befragt wird. Eine weitere Möglichkeit ist es, ein applikations-zentriertes Classloading zu benutzen. Dabei wird der JBoss-spezifische Deploymentdeskriptor jboss-app.xml ergänzt durch folgenden Eintrag: Listing 4.1: Beispiel für Applikations-zentriertes Classloading <jboss-app> <loader-repository>mein_name</loader-repository> </jboss-app> 4.2.2. JBoss Deployment-Komponenten Abbildung 4.4 zeigt das hierarchische System der JBoss-Deployment-Komponenten. <<interface>> Deployer AbstractWebContainer <<interface>> MainDeployer RARDeployer SubDeployer EJBDeployer SubDeployerSupport EARDeployer JARDeployer Abb. 4.4: Deployment-Komponenten des JBoss SARDeployer 4. JBoss Application Server 67 Jedem installierbaren Anwendungstyp ist eine eigene Deployment-Komponente zugeordnet, die einen UnifiedClassLoader für die zu installierende Anwendung erzeugt. Diesen Komponenten ist der MainDeployer übergeordnet, welcher beim Serverstart zuerst beim MBean-Server registriert wird. Soll eine Komponente deployed werden, wird zuerst der MainDeployer aufgerufen. Dieser delegiert die Aufgabe dann an einen spezialisierten SubDeployer. • AbstractWebContainer (WAR-Deployer): Zuständig für Web-Komponenten, die entweder als WAR-Datei oder als Verzeichnis (.war als Verzeichnisnamen-Suffix) deployed werden können. Die Web-Anwendung muss ein WEB-INF-Verzeichnis beinhalten, in welchem der web.xml-Deploymentdeskriptor enthalten ist. Auch der JBoss spezifische jboss-web.xml-Deploymentdeskriptor liegt, wenn benötigt, in diesem Verzeichnis. • EARDeployer: Zuständig für die Installation von gesamten Anwendungen. Diese können als Archiv oder Verzeichnis mit dem Suffix .ear vorliegen. Benötigt wird ein META-INF-Verzeichnis, das den Deployment-Deskriptor application. xml und optional den JBoss-spezifischen jboss-app.xml-Deployment-Deskriptor enthält. • EJBDeployer: Zuständig für EJB-Anwendungen. Diese können ge- oder entpackt mit dem Suffix .jar deployed werden. Voraussetzung dafür ist das enthaltene Verzeichnis META-INF, welches die Deploymentdeskriptoren ejb-jar.xml (notwendig) und jboss.xml (optional und JBoss-spezifisch) enthält. • JARDeployer: Zuständig für JAR-Archive, die keine EJBs enthalten. Es darf kein WEB-INF Verzeichnis enthalten sein. • RARDeployer: Zuständig für JCA-Ressourcen5 . Die ge- oder entpackten Anwendungen haben als Suffix .rar und besitzen ein Verzeichnis META-INF mit dem Deployment-Deskriptor ra.xml • SARDeployer: Zuständig für das Deployment von Service-MBeans. Diese können ge- oder entpackt mit dem Suffix .sar deployed werden. Sie beinhalten eine 5 Java Connector API 68 4. JBoss Application Server service.xml Datei und ein META-INF-Verzeichnis, in der der Deployment-Deskriptor jboss-service.xml enthalten ist. Die SAR-Anwendungen sind JBossspezifisch und können nicht auf anderen Application-Servern installiert werden. Die Deployment-Komponenten unterstützen das so genannte „Russian Doll6 “-packaging. Gemeint ist damit, dass die Deployment-Komponenten rekursiv die zu installierenden Anwendungen durchlaufen. Wenn dabei ein Anwendungs-Typ entdeckt wird, der nicht vom aktuellen Deployer installiert werden kann wird der Main-Deployer konsultiert. Dieser delegiert die Anwendung dann an den zuständigen Sub-Deployer. Dadurch ist es möglich jede xAR-Anwendung in einer anderen xAR-Anwendung mitzuliefern. In den meisten Fällen wird ein EAR-Archiv mit einem oder mehreren darin enthaltenen WAR- und JAR-Anwendungen benutzt. 4.2.3. Hot-Deployment Unter Hot-Deployment versteht man den Vorgang des Installierens, Änderns und Löschens einer Anwendung auf einem Application-Server im laufenden Betrieb. Dieser muss also nicht gestoppt und neu gestartet werden. Im JBoss sind alle installierbaren Anwendungstypen (vgl. 4.2.2) Hot-Deployment-fähig. Um das Hot-Deployment zu benutzen, muss dem Server einen Ort angegeben werden, in dem die zu installierenden Anwendungen gefunden werden können. Zu diesem Zweck können zwei verschiedene MBean-Services genutzt werden. Der URLDeploymentScanner ist der Standard-Scanner des JBoss und ist, soweit man dies nicht ändert, bereits in der Grundeinstellung aktiviert. In der jboss-service.xml der aktuellen Konfiguration (vgl. 4.5) können die Parameter der MBean eingestellt werden. Der URLComparator gibt an, welches Verfahren für das Durchsuchen des angegebenen Deployment-Verzeichnisses verwandt werden soll. Der Standard org.jboss.deployment.DeploymentSorter sortiert die am angegebenen Ort befindlichen Dateien nach deren Endung in der Reihenfolge: sar, service.xml, rar, jar, war, wsr, ear, zip. In dieser Reihenfolge werden die gefundenen Dateien an den Deployer übergeben. Wenn ein anderes Verhalten benötigt wird, lässt sich der URLComparator auf den Wert org.jboss.deployment. scanner.PrefixDeploymentSorter umstellen. Dieser sortiert nach dem Namen 6 Matrjoschka 4. JBoss Application Server 69 der gefundenen Dateien, jedoch nicht alphabetisch, sondern numerisch. Das bedeutet, dass die Dateien mit int-Werten vor dem Dateinamen in ihrer Deployment-Reihenfolge durchnummeriert werden können. Alle Dateien ohne numerisches Präfix werden nach allen anderen installiert. Das Attribut Filter in der jboss-service.xml gibt eine Klasse an, die Dateiendungen definiert, welche nicht deployed werden sollen. Die mitgelieferte Klasse org.jboss. deployment.scanner.DeploymentFilter definiert Dateien mit den Endungen: .old, .orig, .rej, .bak etc. als nicht zu deployen. Die Angabe URLs gibt an wo nach den zu installierenden Anwendungen gesucht werden soll. Das Attribut akzeptiert eine kommagetrennte Liste von Pfadangaben. Dabei kann ein relativer Pfad angegeben werden, dessen Ursprung der Pfad zur aktuellen Konfiguration ist. Es kann aber auch ein absoluter Pfad angegeben werden. Dieser benötigt als Angabe, ob im Dateisystem, also (lokal) oder im Netzwerk (remote) gesucht werden soll. Gültige Angaben sind: (lokal) file:/home/workspace/JBoss/deploy oder (remote) http://www.rambow.it/JBossDemo.ear. Die letzte Option, die eingestellt werden kann, ist die ScanPeriod. Der Wert gibt in Millisekunden an, wie oft nach neuen, geänderten oder entfernten Anwendungen gescannt werden soll. Die Einstellung ist mit 5000 Millisekunden (5 Sekunden) voreingestellt. Diese Einstellung reicht am Anfang meistens aus, da der Deploymentvorgang oft nur wenige Sekunden dauert. Wenn jedoch die Applikationgröße stark zunimmt, kann es passieren, dass noch während des Deploymentvorgangs das Verzeichnis überprüft wird und ein neues Deployment der gleichen Anwendung gestartet wird. Dabei werden Exceptions geworfen. Auch beim Remote-Deployment kann diese Einstellung zu niedrig gewählt sein. Auch wenn das Laden über das Netz länger dauert. Ein weiterer Grund für die Erhöhung der ScanPeriod ist, wenn größere Anwendungen entpackt installiert werden sollen. Der URLDirectoryScanner, der standardmäßig deaktiviert ist, hat die gleichen Einstellmöglichkeiten wie der URLDeploymentScanner. Er bietet jedoch die Möglichkeit, die URLs anders zu definieren. Zu jedem Eintrag kann angegeben werden, ob der Pfad auf ein Verzeichnis oder eine Datei verweist. Gültig ist z. B. <dir name=”./deploy” /> oder <url name=”http://www.rambow.it/JBossDemo.ear” />. 70 4. JBoss Application Server Um remote per HTTP Verzeichnisse scannen zu können, muss der Server WebDAV7 unterstützen. 4.2.4. Vorgang des Deployments In der Praxis bietet der Deployment-Vorgang des JBoss einen hohen Komfort. Wenn die Anwendung konfiguriert und zusammengestellt ist, muss diese nur noch in das angegebene Deploy-Verzeichnis kopiert werden. Ebenso einfach lässt sich auch eine Anwendung aktualisieren, die bereits installiert ist. Die entsprechende Datei muss nur mit einer neueren Datei gleichen Namens überschrieben werden. Der Deployment-Scanner bemerkt die Aktualisierung und der Deployer installiert die Anwendung. Das Undeployment der Anwendung geschieht durch das Löschen der Anwendung im Deploy-Verzeichnis. Wenn man die default-Konfiguration des JBoss benutzt, liegt dieses Verzeichnis unter: <JBOSS_HOME>/server/default/deploy. Im Anhang auf Seite 138 sind Konsolenausgaben des Deployments und Undeployments zu sehen. 4.2.5. Clustering Unter Clustering versteht man, das Zusammenschließen mehrerer Rechner zu einem Netzwerk, welches Anfragen entgegen nimmt. Dieser Cluster verhält sich gegenüber dem Benutzer wie ein einzelner Computer, indem er mehrere Transparenzebenen erfüllt. Folgende Transparenzarten können unterschieden werden [TS03]: • Ortstransparenz (location): Der Zugriff auf Komponenten im Netz erfolgt nicht über die Angabe des Ortes sondern über den Namen (JNDI und HA-JNDI siehe unten). • Zugriffstransparenz (access): Der Zugriff auf verteilte Objekte gestaltet sich ebenso wie der Zugriff auf lokale Objekte. • Replikationstransparenz (replication): Mehrfach vorhandene Objekte (Kopien) werden dem Nutzer präsentiert, als wären sie nur einmal vorhanden. 7 Web Distributed Authoring and Versioning: Hierbei kann HTTP für Lese-, Schreib- und Managementoperationen auf HTTP-Servern angewendet werden. vgl. http://ftp.ics.uci.edu/pub/ietf/ webdav/intro.html 4. JBoss Application Server 71 • Fehlertransparenz (failover): Fehler, wie z. B. der Ausfall eines Knotens im Netzwerk, werden vor dem Benutzer verborgen. • Nebenläufigkeitstransparenz (concurrency): Der gemeinsame Zugriff auf Objekte muss koordiniert werden (vgl. 3.6) • Migrationstransparenz (migration): Das Verteilen von Objekten über das Netzwerk wird vor dem Nutzer verborgen (wenn z. B. ein neuer Knoten an das Netzwerk angeschlossen wird) • Weitere Transparenzen wie Sprachtransparenz (language): fällt bei einem J2EE-Server, dessen Komponenten in Java entwickelt werden, nicht ins Gewicht. Beim Anschluss von Fremdsystemen können CORBA, JCA-Adapter und WebServices eingesetzt werden. Wichtige Faktoren, die für den Einsatz von Clustern sprechen, sind: Performance, Skalierbarkeit, Lastverteilung und hohe Verfügbarkeit. Beim Einsatz von mehreren Rechnern soll sich die Performance, also die Antwort- und Ausführungsgeschwindigkeit eines Systems, verbessern. Unter Skalierbarkeit versteht man die einfache Erweiterbarkeit des Clusters. Dabei soll der Nutzer nicht bemerken, dass ein neuer Knoten hinzugefügt wird. Es sei denn durch den positiven Effekt der Performancesteigerung. Mit Lastverteilung ist das bessere Verteilen von Anforderungen an das Gesamt-Netz gemeint. Dabei werden die Auslastung der Netzwerkverbindungen ebenso wie die Ressourcen Speicher und Prozessorlast berücksichtigt. Da sich diese Faktoren negativ auf die Antwortzeiten eines Servers auswirken, kann über sie eine Prognose getroffen und die Anfrage entweder an den jeweils schnellsten Server geschickt oder gleichmäßig verteilt werden. Eine hohe Verfügbarkeit ist bei unternehmenskritischen Anwendungen von größter Bedeutung. Ein Service oder eine Anwendung sollte vor allem in weltweit genutzten Systemen ständig verfügbar sein. Man spricht dabei von 24x7, also einer 24-stündigen Verfügbarkeit an 7 Wochentagen. Um dies gewährleisten und trotzdem Serviceintervalle einhalten zu können oder unvorhergesehene Rechnerausfälle zu kompensieren, ist man auf redundante Systeme angewiesen. Ein Cluster bietet hohe Verfügbarkeit durch seine Fehlertoleranz. Der Ausfall eines Knotens (durch Service oder Defekt) darf nicht vom Benutzer bemerkt werden. 72 4. JBoss Application Server Bei J2EE-Application-Servern gibt es noch eine Reihe spezieller Anforderungen, die aus der Art der laufenden Anwendungen resultieren. Bei Web-Anwendungen wird eine Benutzerverfolgung mit Hilfe von Sessiondaten benötigt. Bei Ausfall eines Knotens im Cluster soll der Benutzer auf einen anderen Knoten im Netzwerk umgelenkt werden. Dabei ist es notwendig, die Sessiondaten auf den neuen Server zu replizieren. Beim Ausfall eines EJB-Containers müssen Aufrufe an dessen Schnittstellen auf einen anderen EJB-Container umgeleitet werden. Dabei wird der Zustand von stateful Session Beans repliziert. Außerdem ist sicherzustellen, dass die gleiche Version der Anwendung installiert ist. Eine weitere spezielle Anforderung an J2EE-Cluster ist die Verfügbarkeit eines global erreichbaren JMS-Systems. Da es sich, wie in Kapitel 3.5 beschrieben, um eine asynchrone Nachrichtentechnik handelt, wird der Nachrichtendienst stets im Netzwerk über einen Namen zur Verfügung gestellt. Dabei schliessen redundante Systeme aus, dass der JMS-Dienst nur auf einem Rechner läuft und dessen Absturz den Dienst beendet. Der schon mehrfach angesprochene Namensdienst (JNDI) sollte cluster-weit zur Verfügung stehen. Nur so ist Ortstransparenz erreichbar. Um den Administrationsaufwand durch einen Cluster nicht unnötig zu erhöhen, ist es von Vorteil wenn die Möglichkeit besteht, Anwendungen an nur einem Punkt im Cluster zu installieren. Dabei sind zwei Varianten denkbar. Die erste Variante hält an einer Stelle den Code der Anwendung, alle Knoten greifen auf diesen Punkt zu. Beim Ausfall des Knotens, der den Code hält funktioniert die Anwendung nicht mehr. Die zweite Variante verteilt den Code auf alle Knoten im Netzwerk. Diese Methode ist aufwändiger, hat aber nicht den zuvor genannten Nachteil. 4.2.6. Cluster-Architektur des JBoss JBoss bietet Clustering, um Fehlertoleranz, hohe Verfügbarkeit, Skalierbarkeit und Performance zu gewährleisten. Im Cluster-Betrieb wird ein Partitions-Konzept verwendet. Dabei können verschiedene logisch zusammengehörige Serverinstanzen (Nodes) einer oder mehreren Partitionen zugeordnet werden. Jede Partition muss einen eigenen, unterscheidbaren Namen besitzen. In Zukunft wird es im JBoss auch Unterstützung für Teilpartitionen (SubPartitions) geben. Diese erlauben es, Knoten zusammenzufassen, zwischen denen der Status von z. B. 4. JBoss Application Server 73 stateful Session Beans ausgetauscht wird. Dadurch vermindern sich Netzwerklast und Administrationsaufwand. Wenn sich viele Server innerhalb einer Partition befinden, repliziert jeder Knoten den Status der anderen Knoten. Dieser Vorgang benötigt viel Speicherkapazität auf den einzelnen Knoten. Das System bekommt bei dieser Konfiguration eine hohe Ausfallsicherheit. Die Ausfallsicherheit ist bei wenigen Knoten innerhalb einer Teil-Partition ebenfalls gegeben und verbraucht weniger Ressourcen. Abbildung 4.5 stellt die heutige und zukünftige Cluster-Architektur dar. Mit N* wurden dabei die einzelnen Cluster-Nodes bezeichnet. (derzeit) Cluster Partition 1 Partition 1 N4 N5 (zukünftig) Cluster Sub Partition 1 N3 N5 N6 N2 N4 N6 N1 N2 N1 N1 N2 Partition 2 N3 Sub Partition 2 Abb. 4.5: derzeitiges Partitions-Konzept und zukünftiges Sub-Partitions-Konzept Es besteht die Möglichkeit mehrere Serverinstanzen auf einem Rechner laufen zu lassen (z. B. sinnvoll bei Multiprozessormaschinen). Dabei muss darauf geachtet werden, dass keine Konflikte bei den Ports der verschiedenen benötigten Netzwerkverbindungen auftreten. Normalerweise wird jedoch eine Installation von verschiedenen JBoss-Instanzen auf voneinander unabhängigen Rechnern bevorzugt. Die Nodes einer Partition können miteinander über den JBoss-abstract communication layer kommunizieren. Bei der Kommunikation werden Informationen über die einzelnen Knoten ausgetauscht. Sobald ein neuer Knoten zur Partition hinzukommt, ausfällt oder entfernt wird, wird dies automatisch durch Multicast-Messages8 ) erkannt. JBoss setzt für die Kommunikation das Java Groups Framework9 ein. Konfiguriert wird dieses für JBoss in der 8 9 Eine Nachricht wird an das Netzwerk gesendet und kann von allen Knoten empfangen werden. http://www.jgroups.org 74 4. JBoss Application Server cluster-service.xml-Datei unter dem Eintrag <Config>. Zwei Hinweise sind als Kommentar zu diesem Tag hinterlegt und betreffen zum einen Windows-Rechner, die einen Fehler beim Multicast-Betrieb haben und deren Loopback-Attribut innerhalb des <UDP>Tags auf true gesetzt werden muss. Die zweite Einstellung betrifft Rechner mit mehreren Netzwerkkarten. Bei diesen muss die IP-Adresse10 angegeben werden, die mit dem Cluster kommuniziert. Die Client-Kommunikation des JBoss erfolgt über RMI mit Hilfe eines Proxys oder, wenn der Client kein RMI unterstützt, über die JBoss-Dispatcher-Logik. Bei der Verwendung von RMI erhält der Client ein Stellvertreter-Objekt vom Server, das eine Referenz auf das eigentliche Objekt hält. Um Lastverteilung zu ermöglichen, ist es notwendig, den Code dieses Stellvertreter-Objektes so zu erweitern, dass er einen Proxy darstellt. Der Proxy hält nun die Referenzen zu den Objekten des Clusters und eine Liste aller verfügbaren Knoten. Die Proxys sind serverseitig erstellt worden und durch ihre Konfiguration implementieren sie einen Lastverteilungs-Algorithmus [LB03]. Standard hierbei ist Round Robin11 ; es sind aber auch first available12 und andere Verfahren möglich. Diese Variante für das Bereitstellen von Lastverteilung ist gut konfigurierbar und ausfallsicher, da der Client nicht auf einen zentralen Lastverteiler angewiesen ist. Abbildung 4.6 zeigt den Ablauf eines Client-Aufrufes. Dabei ist „Node 1“ ausgefallen und der Client-Proxy verwendet den nächsten Node seiner Liste, um den Aufruf an den Server zu leiten. Client Methoden Aufruf 1. 5. Rückgabe der Methode Node 1 Proxy 2. N1 3. 4. N2 Node 2 N3 Node 3 N.. Adresse eines Nodes Abb. 4.6: dynamischer Proxy mit Liste verfügbar Knoten 10 Internet Protocol Jede Anfrage wird einem neuen Knoten aus der Liste übergeben 12 der zuerst Antwortende 11 4. JBoss Application Server 75 Die Alternative für nicht RMI-fähige Clients ist die JBoss-Dispatcher-Logik. Der Dispatcher ist zwischen den Protokoll-Adaptern angeordnet und übersetzt zwischen dem ClientProtokoll und RMI. Somit sind alle oben aufgeführten Verfahren hinter dem Dispatcher verfügbar. Beim Ausfall des Dispatchers kann jedoch von der JBoss Seite dem Client kein Dienst angeboten werden; sie sind voneinander entkoppelt. Um dennoch Lastverteilung zu ermöglichen, muss ein separater Hardware-Load-Balancer vor die Dispatcher gesetzt werden. Der Aufbau einer solchen Lösung ist in Abbildung 4.7 dargestellt. SOAP IIOP Dispatcher IIOP Dispatcher SOAP CORBA SOAP ... Hardware Loadbalancer Client Node 1 Node 2 Abb. 4.7: Bereitstellung von Clustering für nicht RMI-Clients JBoss ist, zumindest in der all-Konfiguration (vgl. 4.5), bereits für Clustering vorkonfiguriert. Bei weiteren Einstellungen ist die cluster-service.xml-Datei anzupassen. Dort wird unter anderem der Name der Partition eingestellt, in der sich die Serverinstanz befindet. Um Objekte oder Interfaces innerhalb des Clusters zu finden, wird ein clusterweiter JNDIService namens HA-JNDI angeboten (HA steht für „high availability“). Wenn vom Client ein JNDI-Lookup durchgeführt wird, wird zuerst der HA-JNDI-Namensraum durchsucht, anschließend der lokale JNDI-Namensraum des Servers, an den die Anfrage gerichtet wurde, und zuletzt, jeder lokale JNDI-Namensraum der verfügbaren Knoten der Partition. Dieser Vorgang ist in Abbildung 4.8 dargestellt. 76 4. JBoss Application Server Node 1 HA-JNDI Local-JNDI HA-JNDI HA-JNDI Local-JNDI Local-JNDI Node 2 Node 3 Abb. 4.8: Ablauf einer clusterweiten JNDI-Namenssuche Wenn eine Enterprise JavaBean ein Interface ermittelt, wird ein lokaler JNDI-Lookup durchgeführt. Wenn das Objekt aber nicht über den lokalen Namens-Dienst verfügbar ist, muss im HA-JNDI-Namensraum gesucht werden. Dazu ist es notwendig, den InitialContext mit der Adresse und Portnummer des HA-JNDI-Dienstes zu erzeugen. In Listing 4.2 ist ein Quelltextabschnitt zu sehen, der das leistet. Zur Kürzung des Beispiels wurde auf Ausnahme-Behandlung verzichtet. Listing 4.2: Beispiel einer Erzeugung eines InitialContext für HA-JNDI (Server) 1 Properties p = new Properties(); 2 p.put( Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces. NamingContextFactory"); 3 p.put( Context.URL_PKG_PREFIXES,"jboss.naming:org.jnp.interfaces"); 4 p.put( Context.PROVIDER_URL,"localhost:1100"); //HA-JNDI Port 5 Context ctx = new InitialContext(p); Um die Clients für HA-JNDI zu konfigurieren ist es notwendig, die Adresse und den Port eines im Cluster befindlichen Servers anzugeben, auf dem der HA-JNDI Service verfügbar ist. Um zu verhindern, dass der angegebene Server ausgefallen ist und damit die Suche fehlschlägt, wird eine Liste von möglichen Servern angegeben. In Listing 4.3 kann dieser Vorgang nachvollzogen werden kann. 4. JBoss Application Server 77 Listing 4.3: Beispiel einer Erzeugung eines InitialContext für HA-JNDI (Client) 1 Properties p = new Properties(); 2 p.put(Context.PROVIDER_URL,"jnp://s1:1100,jnp://s2:1100");//HA-JNDI Port 3 Context ctx = new InitialContext(p); Diese feste Einstellung von Serveradressen ist jedoch schlecht zu warten und erfordert hohen administrativen Aufwand. Daher ist es bei Verwendung des JBoss-HA-JNDI-Dienstes auch möglich, eine Multicast-Nachricht an das Netzwerk zu schicken und somit automatisch eine verfügbare Serverinstanz zu erhalten. Um diese Methode zu verwenden, wird die PROVIDER_URL mit einem Leerstring initialisiert. Um EJB-Komponenten in einem Cluster benutzen zu können, muss für jede Bean die jboss.xml-Datei angepasst werden. Das Tag <Clustered> bekommt dann den Wert true zugewiesen. Weitere Attribute, wie der Lastverteilungs-Algorithmus, können hier ebenfalls konfiguriert werden. Um auch Web-Anwendungen die Cluster-Vorteile zu ermöglichen, benötigt der JBoss einen separaten Lastverteiler. Dazu kann sowohl eine Hardwarelösung eingesetzt werden als auch eine Softwarelösung. Häufig wird dafür ein Apache Web-Server mit mod_jk eingesetzt. Bei Lastverteilung von HTTP-Sessions gibt es zwei Ansätze: • Eine Clientanfrage immer an einen Server geschickt, so dass sich die Last auf alle Knoten gleichmäßig verteilt und keine HTTP-Session-Replikation stattfindet. Beim Ausfall eines Knotens, der mit einer HTTP-Sitzung identifiziert ist, sind die Sessiondaten verloren. • Wenn dies nicht akzeptabel ist, muss zusätzlich eine HTTP-Sessionreplikation durchgeführt werden. Diese verbraucht genau wie die Sessionreplikation bei den Enterprise JavaBeans Ressourcen. Die Konfiguration des Apache Web-Servers mit mod_jk ist in der Tomcat Dokumentation beschrieben [Fou04b]. Ein weiteres praktisches Feature des JBoss ist Farming, was so viel bedeutet, wie verteiltes Deployment. Damit ist es möglich auf einem Server eine Anwendung zu installieren. Jede Instanz innerhalb einer Partition bekommt diese Komponente ebenfalls übergeben. Dieses Feature fügt sich nahtlos in das Hot-Deployment des JBoss ein. Ab JBoss 3.2 gibt es das Cache Invalidation Framework (CIF). Es ermöglicht effiziente 78 4. JBoss Application Server Zwischenspeicherung von Entity Bean-Objekten. Das Framework wird benutzt, um anzuzeigen ob eine Instanz der Entität geändert wurde. Wenn dieser Fall eingetreten ist, wird das alte Objekt aus dem Cache gelöscht. Der Invalidation-Manager sendet dann eine Nachricht, um dies anzuzeigen. Zur Kommunikation kann JMS eingesetzt werden, da asynchrone Kommunikation benötigt wird (vgl. 3.5). Ein besseres Verfahren ist in der all-Konfiguration voreingestellt, die JBossCluster-based Bridge. Über diese Kommunikationsbrücke werden Multicast-Nachrichten versendet. Da dies von jedem Knoten des Clusters aus möglich ist, kann der Dienst nicht ausfallen, was bei der Verwendung einer MOM-Architektur, die einen JMS-Dienst bereitstellt, möglich ist. Das Caching wird durch die Commit-Option beeinflusst, die in der standardjboss. xml eingestellt wird. Voreingestellt ist Option A, welche dem Server garantiert, den alleinigen Zugriff auf die Daten in der Datenbank zu besitzen, Dadurch kann beliebig zwischengespeichert werden kann. Option B erlaubt keine Zwischenspeicherung und Instanzen im Cache werden mit invalid markiert. Option C erlaubt keine Zwischenspeicherung; Instanzen im Cache werden gelöscht. Option D ist JBoss-spezifisch und erlaubt Zwischenspeicherung mit einem „Verfallsdatum“. Nach einer festgelegten Zeit werden Instanzen aus dem Cache gelöscht (hierbei handelt es sich um eine optimistische Herangehensweise). Um das CIF zu benutzen, muss Option A oder D gewählt werden. Die Entity Beans werden nach ihrem Namen oder durch den Eintrag in Listing 4.4 zu einer Cache Invalidation Group zusammengefasst. Der Invalidation-Manager schickt seine Nachrichten an die jeweilige Gruppe. Listing 4.4: Einstellung des Namens einer Cache Invalidation Group 1 2 3 <cache-invalidation-config> <invalidation-group-name>Gruppen-Name</invalidation-group-name> </cache-invalidation-config> Für die meisten Belange ist der JBoss so gut vorkonfiguriert, dass er „out of the box“ funktioniert und man sofort damit arbeiten kann. Die oben beschriebenen Einstellungen sind für größere J2EE-Applikationen und in produktiven Umgebungen bei Bedarf anzupassen. 4. JBoss Application Server 79 4.3. EJB-Container Der EJB-Container des JBoss ist wie alle JBoss-Komponenten als MBean realisiert. Dadurch ist er leicht austauschbar (bei Bereitstellung der benötigten Schnittstellen) und an die speziellen Wünsche anpassbar. Wie in Kapitel 3.2.2 beschrieben, bietet der EJB-Container den EJBs eine Laufzeitumgebung an. Da die verschiedenen EJB-Typen unterschiedliche Anforderungen an den EJBContainer stellen, wird vom JBoss für jede EJB eine eigene Instanz eines EJB-Containers generiert. Diese Instanz ist auch abhängig vom Typ der EJB. Beim Deployment generiert der EJB-Container des JBoss dynamische Proxies, wie sie im JDK 1.313 eingeführt wurden. Diese Proxies fungieren als Stellvertreter-Objekte der Klassen und leiten die Client-Aufrufe an die Bean-Klassen weiter. Sie stellen die Implementierung der Home- und Komponenten-Interfaces dar. Da die dynamischen Proxies zur Laufzeit (mittels Java-Reflection-API) Informationen über die benötigten Methoden sammeln können, ist es bei der Verwendung dieser Technik nicht nötig, Home- und Komponenten-Interfaces beim Deployment-Vorgang zu erzeugen. Die Proxy-Objekte bieten auch die Möglichkeit, die Interceptor-Logik umzusetzen und die funktionalen Aspekte aufzunehmen, die in den Deployment-Deskriptoren eingestellt sind. Sowohl der ClientContainer als auch der EJB-Container benutzen solche Proxy-Objekte, um die InterceptorArchitektur umzusetzen (vgl. Kapitel 4.1.3). Die Konfiguration des Standardverhaltens der Interceptoren findet in der standardjboss. xml-Datei statt. Dieses Verhalten lässt sich für die zu installierende Anwendung in der jboss.xml-Datei überschreiben. Diese Dateien sind jedoch JBoss-spezifisch. Beim Wechsel des EJB-Containers müssen die Einstellungen auf dem neuen Server nachvollzogen werden. 4.4. Webserver Tomcat ist die Referenzimplementierung der JSP- und Servlet-Spezifikation (derzeit JSP 1.2 und Servlet 2.3). Hervorgegangen ist das Tomcat-Projekt, das unter dem Dach der Apache Software Foundation entwickelt wird, aus der Sun Referenzimplementierung des JSWDK (JavaServer Web Development Kit). Sun übergab der Apache Group die Entwick13 Java Development Kit 80 4. JBoss Application Server lung der Referenzimplementierung. Die Apache Group benannte das JSWDK in Tomcat (interner Name bei Sun) um. In Version 4.x bekam der Server dann eine komplett neue Architektur, in der Jasper (der JSP-Compiler) und Catalina der Servletcontainer separat weiterentwickelt werden können. Wie unabhängig Catalina und Jasper entwickelt werden, lässt sich daran festmachen, dass man Jasper auch im Komandozeilenmodus benutzen kann, um aus JSP-Dateien Servlets zu generieren. Tomcat bietet Schnittstellen an um ihn leicht in Application-Server und andere Webserver (z. B. Apache) integrieren zu können. Seine Stabilität beweist Tomcat unter anderem bei der Integration in kommerzielle Server wie IBM Websphere und Borland Enterprise Server. Ein wichtiger Teil in der Spezifikation ist das Load-Balancing, welches vom Tomcat unterstützt wird. So können Anfragen auf verschiedene Instanzen verteilt werden, wodurch eine hohe Skalierbarkeit und Ausfallsicherheit erreicht wird. Der Tomcat ist als Servlet-Container in JBoss integriert. Er wird als ein SAR in der jeweils aktiven Konfiguration installiert. Wenn man den JBoss mit integriertem Tomcat von der JBoss-Webseite lädt, ist dieser unter deploy/jbossweb-tomcat.sar der aktuellen Konfiguration vorinstalliert. Es ist als entpacktes Archiv installiert, wodurch das Ändern der Konfigurationsdatei innerhalb des SARs einfach möglich ist. Die Datei jboss-service.xml, innerhalb des Tomcat-Service-Archivs, enthält die Konfiguration der Tomcat-MBean. Die Einstellungen entsprechen einem eigenständig laufenden Tomcat-Server. Zu konfigurieren sind hier z. B. die Verwendung von SSL-Verschlüsselung14 (HTTPS). Die Konfiguration wird im Kapitel 4.5.3 erläutert. Weiterhin werden in dieser Datei die Ports, auf denen der Tomcat lauscht festgelegt und Einstellungen für Clustering und Session-Replication vorgenommen. Anfragen an JSP-Seiten werden vom Tomcat-Server entgegen genommen und aus dem Aufruf Request- und Response-Objekte gebildet, die dann verarbeitet werden. Dabei werden die JSP-Seiten, falls sie nicht im Cache liegen, durch Jasper in ein Servlet übersetzt und kompiliert und die gelieferten Objekte verarbeitet. Jedem Container können Hilfskomponenten zugeordnet werden, wie z. B. ein Logger oder ein Zugriff auf externe Ressourcen. 14 Secure Socket Layer 4. JBoss Application Server 81 4.5. JBoss-Konfiguration Für den Betrieb des JBoss benötigt man eine aktuelle Java-Umgebung (ab JDK 1.3). Dann ist die Installation durch das Entpacken des Archivs, welches auf www.jboss.org angeboten wird, abgeschlossen. Dabei ist zu beachten, dass der Pfad zum Installations-Verzeichnis kein Leer- und kein Ausrufezeichen enthalten darf, da der JBoss sonst seine benötigten Klassen nicht laden kann. Um einige Programme (IDEs und Management-Programme) zu unterstützen, ist im System die Variable JBOSS_HOME auf das Installationsverzeichnis zu setzen. 4.5.1. JBoss-Standard-Konfigurationen JBoss ist in seiner Voreinstellung in drei Konfigurationen verfügbar: • minimal Diese Konfiguration enthält die nötigsten Dienste um JBoss zu starten. Also den JMX-Kern und die MBeans für Hot-Deployment, JNDI und Log4J • default Die default-Konfiguration beinhaltet alle Dienste um J2EE-Applikationen auf dem JBoss ablaufen zu lassen, so wie auch den Tomcat (oder Jetty), RMI-IIOP, Transaktionen und Sicherheit. • all Die all-Konfiguration bietet alle verfügbaren Dienste, die auch in der default-Konfiguration angeboten werden und zusätzlich die Unterstützung für Clustering mit allen dazugehörigen Diensten sowie WebServices über Axis15 . Beim Start des JBoss kann man die Konfiguration durch den Aufruf des Start-Skripts mit der Option -c (run -c all) auswählen. Um eine eigene Konfiguration zu erstellen, kopiert man den Inhalt der default-Konfiguration in ein neues Verzeichnis unter <JBOSS_ HOME>/server. Der Name des angelegten Verzeichnisses ist nun der Name der neuen Konfiguration und kann mit dem -c Parameter gestartet werden. Im Folgenden werden die Bestandteile der default-Konfiguration näher erläutert. Die speziellen Einstellungen zum Clustering (all-Konfiguration) wurden bereits im Kapitel 4.2.5 15 SOAP-Implementierung der Apache Software Foundation. Als Servlet ist Axis auf einen Container wie Tomcat angewiesen. 82 4. JBoss Application Server beschrieben. Im Verzeichnis der default-Konfiguration liegen mehrere Unterverzeichnisse: • conf: Das conf-Verzeichnis beinhaltet die Haupt-Konfigurationsdateien für die installierten Dienste. • data: Das Dataverzeichnis enthält die Daten der Anwendung und der integrierten Datenbank HSQLDB (wenn diese benutzt wird). Zu den Daten der Anwendung gehören serialisierte Java-Objekte, die z. B. bei der Passivierung entstehen und JMSNachrichten, die gespeichert werden. • deploy: Im Deploy-Verzeichnis sind alle Anwendungen der JBoss-Instanz installiert. Dazu gehören sowohl J2EE-Anwendungen des Application Assemblers als auch die Service Archive (SAR) des JBoss selbst. Auch der Tomcat ist auf diese Weise installiert. • lib: Hier liegen zusätzlich benötigte Bibliotheken als JAR-Dateien. Alle im libVerzeichnis befindlichen Dateien werden in den Classpath des Servers aufgenommen und stehen Anwendungen zur Verfügung. Das lib-Verzeichnis ist also der Ort an dem anwendungseigene Bibliotheken hinterlegt werden können. • log: Das Verzeichnis enthält das Boot-Log des Servers (Start-Meldungen), das Server-Log (Meldungen zur Laufzeit) und das Access-Log (Meldungen über den Zugriff auf den Webserver). Der Server speichert alle Log-Dateien mit Zeitstempel beim Herunterfahren des Servers ab. • tmp: Hier werden temporäre-Dateien, die beim Deployment erzeugt werden gespeichert. Ebenfalls liegen hier die JSP-Dateien und die daraus erzeugten Java- und ClassDateien. Die Haupt-Konfigurationsdatei des JBoss ist die jboss-service.xml-Datei. In ihr werden die wichtigsten Einstellungen vorgenommen wie z. B. der JNDI-Port, der Pfad zur SSL-Schlüsseldatei und deren Passwort, Log-Verhalten, Deployment- und Transaktionsverhalten. In den Dateien standardjaws.xml und standardjbosscmp-jdbc.xml sind die Einstellungen der Datenquellen (Datenbank) verzeichnet. 4. JBoss Application Server 83 JBoss liefert Abbildungs-Informationen von Java-Datentypen auf SQL-Datentypen vieler Datenbank-Hersteller. Diese sind in der Datei standardjaws.xml hinterlegt. Bei Verwendung einer nicht direkt unterstützten Datenbank kann eine eigene Konfiguration hier ergänzt werden. Zusätzlich ist die Datei standardjbosscmp-jdbc.xml anzupassen, die Informationen und Einstellungen zur Datenbank bereitstellt und die default datasource definiert. Die Datentyp-Abbildungen sind in dieser Datei noch einmal aufgeführt und überschreiben, bei Änderung, die Eintragungen in der standardjaws.xml. Weitere Einstellungen betreffen Timeouts, die Möglichkeit, Tabellen der Datenbank zu löschen und seit JBoss Version 3.2 die Einstellungen zur Verwendung einer automatischen Primärschlüssel-Erstellung. Einstellungen zur Nutzung von JAAS In der login-config.xml-Datei werden die Einstellungen zur Nutzung des JAAS16 vorgenommen. Dieser Dienst wird für ein servergesteuertes Login eingesetzt. Dabei kann der Servlet-Container benutzt werden, um seine Informationen über den Nutzer (Username und Passwort) anhand einer hinterlegten Nutzerverwaltung zu überprüfen. Die Nutzerverwaltung kann z. B. als Datenbank, XML-Datei, LDAP-Verzeichnis oder in anderer Form vorliegen. Über das name-Attribut im <application-policy>-Tag wird der Name der Sicherheits-Domäne festgelegt. Über diesen Namen ist sie dann innerhalb der Konfiguration in der Web-Anwendung referenzierbar (vgl. 4.5.2). Die Anwendung, die im Rahmen dieser Diplomarbeit entstand verwendet das Sicherheits-System JAAS Die Konfiguration innerhalb der login-config.xml-Datei ist in Listing 4.5 dargestellt. Listing 4.5: Beispiel-Konfiguration JAAS mit Datenbank-Login-Modul (login-config.xml) 1 <application-policy name="myJBossSec"> 2 3 <authentication> <login-module code="org.jboss.security.auth.spi. DatabaseServerLoginModule" flag="required"> 4 <module-option name="dsJndiName">java:/DefaultDS</module- 5 <!--<module-option name="principalsQuery">alternative SQL- option> Query</module-option> 16 Java Authentication and Authorization Service 84 6 4. JBoss Application Server <module-option name="rolesQuery">alternative SQL-Query</module -option>--> 7 </login-module> 8 </authentication> 9 </application-policy> Die folgenden SQL-Querys stellen die Voreinstellung der benutzten Datenbankabfragen dar. Die principalsQuery erfragt das Passwort eines Benutzers aus der Datenbank: SELECT password FROM PRINCIPALS WHERE user_id = ? Die rolesQuery erfragt die Rolle und Rollengruppe eines Benutzers: SELECT role, role_group FROM ROLES where user_id= ? Wenn die Ergebnismenge der Anfragen gewahrt bleibt, können diese nach Belieben an eine bereits bestehende Nutzerverwaltung angepasst werden. Bei einer Neuentwicklung kann man die Voreinstellung benutzen und legt dafür die folgenden zwei Datenbanktabellen an: Listing 4.6: Tabellen für JAAS mit Datenbank-Login-Modul (login-config.xml) create table PRINCIPALS (PRINCIPALID varchar(16), PASSWORD varchar(16)) create table ROLES (PRINCIPALID varchar(16), ROLE varchar(16), ROLEGROUP varchar(16)) Bei der Verwendung dieser Anfragen stellte der Autor eine Besonderheit beim JBoss fest. Bei der Abfrage der Rollengruppe ist der einzig akzeptierte Wert: „Roles“ (case-sensitiv). Um dies sicherzustellen, wurde in der Referenzanwendung, die im Zusammenhang mit dieser Diplomarbeit entstand, dieser Wert bei der Erzeugung eines Benutzers fest kodiert. Falls sich diese Besonderheit ändert und wenn eine Rollengruppe benötigt wird, sollte dieser Wert wieder dynamisch erzeugt werden. 4.5.2. JBoss-spezifische Deployment-Deskriptoren Um die J2EE-Spezifikation in einigen Belangen zu erweitern, bieten die Hersteller der J2EE-Application-Server proprietäre Erweiterungen an. Dabei können Eigenschaften der EJB-Container, die über die Spezifikation hinausgehen, genutzt werden. Da z. B. EJB-QL einen geringen Sprachumfang bietet, werden hier oft proprietäre Erweiterungen vorgenommen. Auch bei JAAS, dessen Integration nicht bis ins Detail in der J2EE Spezifikation beschrieben ist, greifen die Hersteller auf eigene Umsetzungen zurück. 4. JBoss Application Server 85 Die herstellereigenen Erweiterungen sind jedoch beim Wechsel des J2EE-Servers nicht sofort verfügbar. Es muss eine Migration erfolgen, wobei nicht immer sichergestellt werden kann, dass alle Möglichkeiten eines Servers vom anderen abgedeckt werden. Auch der JBoss Application Server bietet solche Erweiterungen an, die im folgenden Abschnitt beschrieben werden. Der JBoss-spezifische Web-Deploymentdeskriptor In der jboss-web.xml-Datei können JNDI-Namen vergeben werden, auf die innerhalb des Programmcodes zugegriffen wird. Es lassen sich auch EJB-Referenzen festlegen. Falls der Servlet-Container nicht innerhalb der gleichen JVM abläuft, sind diese Einstellungen notwendig, um auf EJBs zugreifen zu können, welche im web.xml-Deployment-Deskriptor angegeben wurden. Eine wichtige Einstellung, die benötigt wird um die URL der Anwendung festzulegen bietet das <context-path>-Element. Bei der Installation einer WAR-Datei auf dem Tomcat. wird der Name der WAR-Datei als URL-Pfadelement benutzt. Dies ist jedoch nicht immer erwünscht (z. B. wenn man die WAR-Archive durch einen Zeitstempel im Namen unterscheidbar halten möchte). Wenn eine entpackte Web-Anwendung installiert wird, benutzt der Tomcat den Namen des Haupt-Verzeichnisses. Bei der Installation der Web-Anwendung foo.war wird also auf die Anwendung über die URL <server-adresse>/foo/ zugegriffen. Um dies zu ändern, kann in der jboss-web.xml (bei WAR-Archiven) beziehungsweise in der application.xml, wenn die Web-Anwendung Teil eines EAR-Archivs ist, der folgenden Eintrag vorgenommen werden: <context-root>/pfadname</context-root>. Eine weitere elementare Einstellung betrifft die Verwendung von JAAS zur Sicherung der Web-Anwendung. Wie bereits im Kapitel 4.5.1 beschrieben wurde kann im JBoss eine Sicherheits-Domäne angelegt werden. Diese kann spezifisch für jede Anwendung definiert werden. Die folgende Einstellung referenziert die Sicherheits-Domäne aus dem Beispiel in Listing 4.5: <security-domain>java:/jaas/myJBossSec</security-domain>. Die Verwendung der JAAS-Sicherheits-Domäne wird anhand der Web-Anwendung im Kapitel 5 erläutert. 86 4. JBoss Application Server Der JBoss-spezifische EJB-Deployment-Deskriptor Die Datei jboss.xml wird benutzt um die EJB-Container-Konfiguration für die Installationseinheit (JAR) anzupassen. Die standardjboss.xml und jboss.xml sind nach der selben DTD geformt. Daher sind die Einstellungen der standardjboss.xml in der jboss.xml-Datei überschreib- und erweiterbar. Die Elemente der jboss.xml sind: • enforce-ejb-restriction: Bei Aktivierung dieses Parameters mit dem Wert true wird beim Deployment die Einhaltung der EJB-Restriktionen überprüft. Fehler werden auf der Konsole bzw. in der Log-Datei angezeigt. • security-domain: Die security-domain referenziert die Einstellung der login-config.xml-Datei und wird zur Einhaltung der Sicherheitsrichtlinien bei der Methoden-Ausführung von EJBs eingesetzt. • unauthenticated-principal: Dieser Eintrag definiert den Rückgabewert der getCallerPrincipal()-Methode, wenn der Aufruf nicht autorisiert ist. • enterprise-beans: Erweitert die Einstellungen der ejb-jar.xml-Datei. Eingetragen werden Umgebungsvariablen und JNDI-Namen. • resource-manager: Abbildung von resource-manager-connectionfactories auf JNDI-Namen • container-configurations: Einstellung aller für dieses Deployment zu konfigurierenden Container-Einstellungen. Die Sicherheits-Domäne ist äquivalent zur jboss-web.xml einzustellen. Wenn auf eine gesicherte Methode einer EJB zugegriffen wird, überprüft der EJB-Container anhand der Sicherheits-Domäne, ob der zugreifende Benutzer die benötigte Rolle inne hat. Die Elemente unterhalb des enterprise-beans-Tag können jeden EJB-Typ und eine oder mehrere diesem Typ zugeordnete EJBs beschreiben. Hier können den EJBs bestimmte JNDI-Namen, Ressourcen, und Umgebungs-Variablen zugewiesen werden. Entity Beans können innerhalb des enterprise-beans-Tag als read-only markiert werden, wodurch der schreibende Zugriff untersagt ist. Bei dem Versuch eines schreibenden Zugriffs wird eine Ausnahme ausgelöst. 4. JBoss Application Server 87 Zusätzlich zu den Einstellungen die speziell für EJBs gelten sind auch Container-Einstellungen in dieser Datei konfigurierbar. Die Standard-Einstellungen der standardjboss. xml-Datei sind meist ausreichend und sollten nicht direkt in dieser verändert werden. Um die Einstellungen der standardjboss.xml zu erweitern, bedient man sich des Attributes extends gefolgt vom Namen des zuständigen Containers wie im folgenden zu sehen: <container-configuration extends="Standard CMP EntityBean"> Unterhalb dieses Tags sind dann alle Container-Einstellungen für den Standard-Container veränderbar. Um die Zuordnung eindeutig zu halten, wird ein neuer Name für den umkonfigurierten Container durch das Tag <container-name> vergeben. Die meisten Einstellungen sind Feinabstimmungen, die die Performance in speziellen Anwendungen positiv beeinflussen können. So ist z. B. die Größe des Pools für Entity- und stateless Session Beans einstellbar. Dabei kann z. B. die maximale Anzahl der Instanzen im Pool durch das Tag <MaximumSize> durch einen ganzzahligen Wert begrenzt werden (z. B. zur Begrenzung des Speicherplatzes einer installierten Anwendung). Bei der Verwendung des Cache Invalidation Frameworks sind unterhalb des Tags <container-cache-conf> unter anderem Einstellungen zur Kapazität des Caches und des maximalen Alters der zwischengespeicherten Instanzen änderbar. Weitere Einstellungen betreffen die Behandlung von Transaktionen und deren Locking-Mechanismen. Die meisten Einträge der standardjboss.xml betreffen die Kette der Interceptoren, die ein Aufruf einer EJB zu durchlaufen hat. Diese Kette sollte in ihrer Reihenfolge beibehalten werden. Wenn jedoch keine Notwendigkeit für die Sicherheitsüberprüfung von Aufrufen besteht, so werden die Einstellungen für die Interceptoren in die jboss.xmlDatei übernommen. Die Sicherheits-Überprüfung wird durch das Entfernen des folgenden Tags unterbunden: Listing 4.7: Entfernen der Sicherheitsüberprüfung <interceptor> org.jboss.ejb.plugins.SecurityInterceptor </interceptor> Eine für das Debugging einer Anwendung interessante aber ressourcen-intensive Einstellung ist <call-logging>, welche die Werte true und false annehmen kann. Die Voreinstellung ist false, da hierbei jeder Methoden-Aufruf einer EJB protokolliert wird. Durch die jboss.xml kann man dieses Verhalten jedoch für bestimmte EJBs konfigurie- 88 4. JBoss Application Server ren, um z. B. Fehler in einer Anwendung aufzuspüren. Kunnumpurath beschreibt in seinem Buch [Kun02] diese und weitere Container-Einstellungen detailliert. Der JBoss erlaubt auch die Verwendung von RMI-Methodenaufrufen, die mittels SSL verschlüsselt werden können. Die Installation des dazu notwendigen SSL-Zertifikats ist im folgenden Abschnitt beschrieben. Um das Zertifikat zu verwenden, muss die jboss-service.xml-Datei erweitert werden. Die notwendigen Einträge sind bei unveränderter Konfiguration auskommentiert und werden an den Pfad der Schlüssel-Datei angepasst. Listing 4.8: Beispiel-Konfiguration SSL für EJBs 1 <mbean code="org.jboss.security.plugins.JaasSecurityDomain" name=" Security:service=JaasSecurityDomain,domain=TomcatSSL"> 2 3 <constructor> <arg type="java.lang.String" value="TomcatSSL"/> 4 </constructor> 5 <attribute name="KeyStoreURL"> 6 ${jboss.server.home.dir}/conf/ssl/keyfile.txt 7 </attribute> 8 <attribute name="KeyStorePass">992007</attribute> 9 <depends>jboss.security:service=JaasSecurityManager</depends> 10 </mbean> 11 12 <mbean code="org.jboss.invocation.jrmp.server.JRMPInvoker" name=" jboss:service=invoker,type=jrmp,socketType=SSL"> 13 <attribute name="RMIObjectPort">4444</attribute> 14 <attribute name="RMIClientSocketFactory">org.jboss.security.ssl. RMISSLClientSocketFactory</attribute> 15 <attribute name="RMIServerSocketFactory">org.jboss.security.ssl. 16 <attribute name="SecurityDomain">jboss.security:service= 17 <depends>jboss:service=TransactionManager</depends> RMISSLClientSocketFactory</attribute> JaasSecurityDomain,domain=TomcatSSL</attribute> 18 </mbean> Anschließend müssen die EJBs, die über SSL aufgerufen werden sollen, den SSL-Invoker zugewiesen bekommen: 4. JBoss Application Server 89 Listing 4.9: Beispiel-Konfiguration SSL für EJBs 21 22 23 <enterprise-beans> <session> <ejb-name>UserSessionFassade</ejb-name> 24 ... 25 <home-invoker>jboss:service=invoker,type=jrmp,socketType=SSL</homeinvoker> 26 <bean-invoker>jboss:service=invoker,type=jrmp,socketType=SSL</beaninvoker> 27 28 29 ... </session> </enterprise-beans> Der JBoss-spezifische CMP-Deployment-Deskriptor JBoss erstellt bei der Installation einer Anwendung, welche Container Managed Persistence benutzt, die benötigten Tabellen in einer relationalen Datenbank. Wenn dieses Verhalten jedoch nicht gewünscht wird, weil bereits Tabellen angelegt wurden, kann mit Hilfe des jbosscmp-jdbc.xml-Deployment-Deskriptors das Mapping konfiguriert werden. Das folgende Listing 4.10 zeigt beispielhaft die Abbildung einer CMP-Entity Bean auf eine vorhandene Datenbanktabelle: Listing 4.10: Beispiel für die Abbildung einer Entity Bean auf eine vorhandene DB-Tabelle 1 2 <enterprise-beans> <entity> 3 <ejb-name>AddressEntity</ejb-name> 4 <table-name>ADDRESSENTITY</table-name> 5 ... 6 <cmp-field> 7 <field-name>stadt</field-name> 8 <column-name>CITY</column-name> 9 10 11 12 </cmp-field> .... </entity> </enterprise-beans> 90 4. JBoss Application Server 4.5.3. Konfiguration für HTTPS-Verbindungen Bei einer durch ein Sicherheitssystem wie JAAS geschützten Anwendung ist die sichere Übertragung von Daten zwischen Web-Server und Client eine essentielle Anforderung. In den meisten Fällen wird für diese Daten-Verschlüsselung SSL eingesetzt. Sun bietet zur Erstellung des Serverzertifikates das Programm Keytool an, das sich im binVerzeichnes des Java SDK befindet. Um ein Zertifikat zu erstellen benutzt man den Aufruf: keytool -genkey -keyalg "RSA"-keystore keyfile -storepass passwort -validity 360. Dabei ist keyfile das Schlüssel-Paar (private/public Key), RSA der Schlüsselalgorithmus und 360 die Gültigkeitsdauer in Tagen. Danach folgen Eingabeaufforderungen zur Identität des Zertifikatinhabers. Dieses Zertifikat kann man dann z.B. bei VeriSign beglaubigen lassen. Wenn man das keyfile erzeugt hat, wird unter dem JBOSS_HOME/server/ <konfiguration>/conf ein neues Verzeichnis /ssl erzeugt und das keyfile dort gespeichert. Um diesen Ort dem Tomcat bekannt zu machen, wird folgender Eintrag in der jbossservice.xml-Datei innerhalb des jbossweb-tomcat.sar vorgenommen (gekürzt): Listing 4.11: Beispiel-Konfiguration HTTPS-Verbindung JBoss-Tomcat 1 <!-- SSL/TLS Connector configuration using the SSL domain keystore --> 2 <Connector className="org.apache.coyote.tomcat4.CoyoteConnector" 3 4 port="443" scheme="https" secure="true"> <Factory className="org.apache.coyote.tomcat4.CoyoteServerSocketFactory" 5 clientAuth="false" 6 keystoreFile="${jboss.server.home.dir}/conf/ssl/keyfile.txt" 7 8 keystorePass="992007" protocol="TLS"/> </Connector> 4.6. JBoss Version 4.0 JBoss wird in der kommenden Version 4.0 seines Application-Servers J2EE 1.4 unterstützen. Dabei werden die neuen APIs der Java Enterprise Edition unterstützt. Hervorzuheben ist hier die Unterstützung der Servlet 2.4 und JSP 2.0 Spezifikation durch die Integration des Tomcat 5.0 Servers. Hinzu kommt die Unterstützung der EJB 2.1 Spezifikation, die 4. JBoss Application Server 91 unter anderem Erweiterungen im Bereich EJB-QL bereitstellt (order by-Statement und Aggregatfunktionen). JBoss unterstützt beim endgültigen Release die gesamte J2EE 1.4 Spezifikation und ist, wie auf der Webseite17 berichtet wird, bereits im Sun-J2EE 1.4 Zertifizierungs-Prozess. Die weiteren Merkmale der J2EE 1.4 sind unter [Sha03] beschrieben. Erweiterungen die nicht zur J2EE Spezifikation gehören, sind unter anderem die Integration des O/R-Mappers Hibernate (vgl. 3.3.6) und das Bereitstellen eines AOP-Frameworks, das im folgenden Abschnitt beschrieben wird. 4.6.1. AOP Eine besondere Neuerung im JBoss 4.0 ist das AOP-Framework (Aspektorientierte Programmierung). AOP wird eingesetzt, um mehrfach auftretende technische Belange innerhalb der Software zentral an einem Ort zu implementieren. Ein gutes Beispiel hierfür ist das Logging. Um Methodenaufrufe zu dokumentieren, muss jede Methode, die dieses Verhalten besitzen soll, selbst Quelltext dafür bereitstellen. Solche systemweiten Belange bezeichnet man als Crosscutting Concerns [BE03]. AOP bietet hier eine Möglichkeit solche Belange nur einmal zu implementieren und die Funktionalität dafür bereitzustellen. Die Klasse, die um den Aspekt zu erweitern ist, kann entweder selbst Anhaltspunkte geben, an welchen Stellen Aspekte benötigt werden oder sie wird mit Hilfe eines Parsers nach bestimmten Konstrukten untersucht, die als Anhaltspunkt gelten. Wenn diese Join Points identifiziert sind, kann der entsprechende Code zur Bereitstellung der Funktionalität eingewoben werden (Code Weaving). Solche Code-Weaver werden z. B. bei AspectJ eingesetzt. In JBoss 4.0 können zur Definition des Aspekts spezielle XDoclet-Tags benutzt werden, aus denen eine XML-Beschreibung (jboss-aop.xml) erstellt wird. Um den Aspekt auszuführen, bedient sich JBoss seiner Interceptor-Architektur (vgl. 4.1.3). Der Interceptor, der den Aspekt implementiert, wird in die Kette der Interceptoren der Klasse eingefügt (Transaktionen, Sicherheit etc.) Aus den Informationen der XML-Beschreibung kann nun der Interceptor feststellen, an welchem Punkt sein Dienst ausgeführt werden soll. Durch das Interceptor-Konzept war es JBoss leicht möglich ein AOP-Framework anzubie17 http://jboss.org/developers/roadmap/JBossRoadmap.html 92 4. JBoss Application Server ten. Auf Systemebene des Servers wurde diese Art der Programmierung schon implizit genutzt. Somit ist es ebenfalls möglich die JBoss-System-Interceptoren zu benutzen, um z. B. einfache Klassen mit Funktionalität auszustatten, die bisher EJBs vorbehalten war. Im Folgenden sind einige System-Interceptoren (Aspekte) aufgeführt, die benutzt werden können. Eine vollständige Auflistung ist der Dokumentation des JBoss 4 zu entnehmen: • Transaktionen: Orientieren sich am Transaktions-Modell von J2EE. Damit wird in einfachen Java-Klassen ermöglicht, Transaktionen wie in J2EE mit den Begriffen Required , RequiresNew, Supports, NotSupported, Never zu definieren. • Sicherheit: Durch Aspekte ist es möglich, in einfachen Java-Programmen Sicherheit so zu konfigurieren, wie es sonst nur in J2EE-Komponenten möglich ist. Die Sicherheits-Aspekte lassen sich ebenso wie in der J2EE-spezifischen ejb-jar.xml definieren und bieten Möglichkeiten wie Zugriffsbeschränkungen auf Methoden je nach Benutzerstatus. • Remoting: Es ist möglich, einfache Java-Klassen mit JBoss-Remoting zu verbinden. Dadurch können entfernte Objekte über eine URL referenziert werden. • Clustered Remoting: Schafft eine Verbindung zum Clustering unter JBoss. Dazu gehört z. B. die Auswahl der Clusterpartition für diese Objekte. Eine weitere Möglichkeit stellen Introductions dar. Hierbei können zu bestehenden Klassen Methoden und Felder hinzugefügt werden. Um dies zu ermöglichen, bedient man sich einer Hilfsklasse, die als Mixin-Klasse bezeichnet wird. Die Mixin-Klasse kann mit den Klassen, die den in der Mixin-Klasse definierten Aspekt erhalten sollen, verbunden werden. Die Verbindung von zwei Klassen resultiert dann in einer Mehrfachvererbung, die in Java normalerweise nicht möglich ist. 4.7. Werkzeuge für den JBoss Application Server Bei der Entwicklung von J2EE-Anwendungen gelten zwei Programme als unerlässlich. Zum einen ist es die Automatisierungs-Anwendung Ant und zum anderen XDoclet. 4. JBoss Application Server 93 4.7.1. Ant Viele Aufgaben bei der Softwareentwicklung werden durch den Einsatz von IDEs wie Eclipse abgedeckt. Bei speziellen Aufgaben, wie aufwändigen Datei-Operationen, ist man jedoch auf den Einsatz von Buildtools wie Ant angewiesen. Ant bietet die Möglichkeit, über XML-Dateien bestimmte Aufgaben abzuarbeiten. Diese Aufgaben (Tasks) sind vordefiniert und es stehen derzeit über 70 davon zur Verfügung. Die Aufgaben können voneinander abhängig bearbeitet werden. Diese Stapel-Verarbeitung ist bei immer wiederkehrenden aufwändigen Aufgaben sinnvoll einsetzbar. Ein gutes Beispiel dafür ist das Packen der einzelnen Enterprise-Archive. Ant stellt dafür spezielle Tasks zur Verfügung, die auf Ordnern, Dateien und Datei-Listen arbeiten. Definiert werden diese über so genannte Wildcards, die Datei-Mengen anhand von bestimmten Namensmerkmalen bereit stellen. Bei einem komfortablen Hot-Deployment-Mechanismus, wie er beim JBoss zur Verfügung steht, ist innerhalb eines Ant-Build Skripts auch das Deployment möglich. Ant bietet zudem die Möglichkeit, die gesamten Java-Quelltexte zu kompilieren. Der Einsatz von Ant wurde bei der Erstellung der Referenzanwendung, die während dieser Diplomarbeit entstand, intensiv genutzt. Das Ant-Skript ist auf der zu dieser Arbeit mitgelieferten CD vorhanden und zeigt die wichtigsten Einstellungen für das Packen einer J2EEAnwendung. Durch die gute Integration von Ant in Eclipse war weiterhin der Komfort der IDE gegeben. Genauere Informationen zu Ant, der Syntax und den verfügbaren Tasks sind unter [Edl02] und [Fou04a] und in zu finden. 4.7.2. XDoclet XDoclet ist ein Code-Generator. Dieses Programm bietet mit verschiedenen Modulen die Möglichkeit, durch einfache Deklaration (JavaDoc-Kommentare) verschiedenen Code zu erzeugen. Im J2EE-Umfeld wird XDoclet mit dem Modul ejbDoclet eingesetzt, um Deployment-Deskriptoren, Interfaces und z. B. Wert-Klassen für Entity Beans zu erzeugen. Durch den Einsatz von XDoclet lässt sich so der Code an einer zentralen Stelle halten. Nachlässigkeiten bei der Anpassung von Deployment-Deskriptoren und Interfaces werden umgangen. XDoclet bietet derzeit Unterstützung für die wichtigsten Application-Server wie JBoss, Tomcat, WebSphere und WebLogic um serverspezifische Deployment-Deskriptoren zu erstellen. 94 4. JBoss Application Server Um mit Hilfe von XDoclet die entsprechenden Dateien zu erzeugen, wird Ant eingesetzt. Das folgende gekürzte Beispiel verdeutlicht die Syntax: Listing 4.12: XDoclet-Beispiel (stateless Session Bean) 1 /** @ejb.bean 2 * name = "MyStatelessClass" 3 * jndi-name = "MyStatelessClassBean" 4 * type = "Stateless" 5 * 6 */ display-name=MySLSB 7 8 9 public class MyStatelessClassBean implements SessionBean{ /** @ejb.interface-method 10 * view-type = "both" 11 * @ejb.transaction 12 * type = "Required" 13 */ 14 15 public void sayIt(String it){ System.out.println(it); 16 17 } Um aus dieser Bean-Klasse die benötigten Interfaces und den ejb-jar.xml-Deployment-Deskriptor zu erzeugen, benutzt man ein Ant-Skript, wie das Folgende: Listing 4.13: XDoclet-Beispiel (stateless Session Bean) 33 34 <target name="xdoclet"> <taskdef name="ejbdoclet" classname="xdoclet.modules.ejb. EjbDocletTask" classpathref="project.classpath"/> <ejbdoclet ejbspec="2.0" destDir="genjava"> 35 <fileset dir="${basedir}\src"> 36 <include name="*EJB.java" /> 37 38 </fileset> 39 <localinterface pattern="{0}"/> <localhomeinterface/> 40 41 42 43 <deploymentdescriptor destdir="META-INF" /> </ejbdoclet> </target> 4. JBoss Application Server 95 4.7.3. Entwickler-Werkzeuge für die JBoss-Plattform Die JBoss-Entwickler stellen zwei Anwendungen zur Unterstützung des Server-Managements zur Verfügung. Die Web-Anwendung JMX-Management-Konsole zeigt an, welche EJBs und Dienste laufen und welche Namen im JNDI-Baum registriert sind. Sie bietet auch die Möglichkeit einige Konfigurationen (Container-Einstellungen, JNDI-Namen etc.) vorzunehmen. Nach erfolgreicher Installation des JBoss ist die JMX-Management-Konsole unter der Adresse: http://<Server-Adresse>/jmx-console/index.jsp zu erreichen. Die Anwendung stellt einen sehr einfachen JMX-HTML-Adapter dar und bietet keinen großen Komfort bei der Navigation und der Eingabe von Parametern. Neu in JBoss 3.2 hinzugekommen ist die Management-Konsole, die unter der Adresse (http://<Server-Adresse>/web-console) zu erreichen ist. Diese bietet eine grafische Benutzeroberfläche durch ein Applet und zeigt die laufenden Prozesse als Übersicht und Baumstruktur an. Sie integriert auch die JMX-Management-Konsole, die dadurch von der Baum-Navigation profitiert. Durch die Umsetzung des JSR-7718 (einer Java-Erweiterung für J2EE-Management) sind jetzt auch einzelne Beans übersichtlich zu überwachen, wenn sie ein remote-Interface bereitstellen. Diese Management-Konsole ist sehr hilfreich bei der Untersuchung von Anwendungen. Neben Informationen über die Häufigkeit von Aufrufen an den EJBs wird auch die Zeit für das Ausführen von Methoden einer EJB ablesbar. Die Bilder im Anhang auf Seite 140 zeigen die Management-Konsole mit verschiedenen Ansichten. Zur Unterstützung der Anwendungsentwicklung stellen die JBoss-Entwickler die JBossIDE bereit. Die JBoss-IDE ist ein Eclipse-Plugin und bietet zahlreiche Unterstützungen bei der Entwicklung von Anwendungen für den JBoss. Zu nennen sind vor allem die XDocletUnterstützung, die Möglichkeit zum Zusammenstellen der Anwendung, die Unterstützung des Deployment-Vorgangs sowie die Überwachung der laufenden JBoss-Instanzen. Die Unterstützung für XDoclet beinhaltet eine automatische Vervollständigung der XDoclet-Komentare. In einer Ansicht zeigt die JBoss-IDE verschiedene konfigurierte JBoss-Instanzen an. Diese können dort direkt gestartet und gestoppt werden. Für das Deployment bietet die JBoss-IDE ein automatisches Kopieren der Anwendungen in das jeweilige deploy-Verzeichnis. Da 18 Java Specification Request 96 4. JBoss Application Server auch die Log-Konsole angezeigt wird, kann man den Vorgang dort mitverfolgen. Durch die Integration der Eclipse-Debug-View lassen sich auf dem Server installierte Anwendungen zur Laufzeit untersuchen. Zu den Werkzeugen, welche die JBoss-Entwickler selbst zur Verfügung stellen, kommen immer weitere Anwendungen hinzu, die zum einen Teil frei erhältlich und zum anderen kommerziell sind. Zu nennen wären im Bereich Management des Servers die Werkzeuge OpenTier von EPIUSE19 und die XtremeJ Management Konsole20 . OpenTier bietet zwei Web-Anwendungen an. Diese sind auf JBoss via Hot-Deployment zu installieren. OpenTier-Config bietet einige wenige Einstellmöglichkeiten für das Deployment (Zeit des Scanner Durchlaufs, Ein- und Ausschalten des rekursiven Scans). Die Einstellungen des Loggings betreffen das Format des Zeitstempels, den Ort der Logging-Datei und den Log-Level für die Konsole. Die letzte Einstellmöglichkeit betrifft die Datenbank, hier können Name, Treiber, URL sowie Benutzername und Passwort gesetzt werden. Die Einstellungen sind übersichtlich angeordnet und stellen eine kontextsensitive Hilfe zur Verfügung. Das Werkzeug OpenTier-Manager bietet bietet in etwa den gleichen Umfang wie die JBoss-Eigene Management-Konsole. Geboten werden ein JMX- und JNDI-Baum, mit einer Detaildarstellung der laufenden Dienste. Zusätzlich ist eine Suche innerhalb der Bäume möglich und in der Professional Version gibt es eine grafische Statistik der Zugriffe und des Speicherverbrauch. Auch der OpenTierManager ist sehr übersichtlich aufgebaut und bietet eine etwas bessere Bedienung, als die JBoss-Management-Konsole. Da die OpenTier-Werkzeuge noch in Version 1.0 vorliegen, sind Weiterentwicklungen mit einer größeren Anzahl von Einstellmöglichkieten zu erwarten. Die Werkzeuge von XtremeJ werden als Eclipse-Plugin-Sammlung bereitgestellt. Zur Verfügung stehen Werkzeuge und Views, die vor allem die Entwicklung und Überwachung von MBeans unterstützen. Durch den offenen MBean-Standard ist es so mit XtremeJ möglich, nicht nur JBoss zu steuern, sondern ebenso BEA WebLogic oder auch IBM WebSphere. Einen genauen Überblick über die Möglichkeiten von XtremeJ findet man auf der Webseite von XtremeJ. Zu den interessantesten Möglichkeiten zählen das Erstellen, Installieren und Überwachen von MBeans direkt aus Eclipse heraus. Die Überwachung der MBeans wird durch verschiedene Views, wie z. B. einer grafischen Anzeige über den Speicherverbrauch 19 20 http://www.opentier.net/ http://www.xtremej.com/ 4. JBoss Application Server 97 von ausgewählten MBeans unterstützt. Ebenso können alle Methoden der MBeans direkt in Eclipse gestartet, Attribute gesetzt und Benachrichtigungen empfangen werden. Für JBoss gibt es speziell noch einen JNDI-Browser und J2EE-Management über JSR-77. XtremeJ bietet somit eine sehr gute Integration in den Entwicklungsprozess. Vor allem Entwickler, die Dienste als MBeans selbst entwickeln, werden diese Plugin-Sammlung einsetzen. Anwendungsentwickler können mit Hilfe der Werkzeuge genauer verfolgen, welche Module des Servers gerade arbeiten. XtremeJ wird in drei Varianten angeboten, die sich in ihrem Funktionsumfang unterscheiden. Darunter befindet sich auch eine kostenlose Variante. 4.7.4. Integrierte Entwicklungsumgebungen In den letzten Jahren wurden viele Entwicklungsumgebungen für Java bereitgestellt. OpenSource-Projekte wie Eclipse und das kostenlose NetBeans von Sun haben diese Werkzeuge einer breiten Menge von Entwicklern verfügbar gemacht. Die Entwicklung von großen Softwareprojekten benötigt erweiterte Fähigkeiten in der Quelltext-Navigation, intelligentes Suchen, Code-Vergleiche und Versionsmanagement. Zudem gehört zu jeder Entwicklungsumgebung ein Quelltext-Editor, der Unterstützung bei den Implementierungsaufgaben bietet. Für die Entwicklung der Referenz-Anwendung, die im Rahmen dieser Arbeit entstand, wurde Eclipse eingesetzt. Eclipse und J2EE Eclipse ist eine reine Java-Entwicklungsumgebung und bietet wenig Unterstützung für J2EE-Anwendungen. Wichtige Editoren, z. B. für JSP oder XML sind nicht integriert, können aber aus einer großen Anzahl von freien und kommerziell verfügbaren Plugins ausgewählt werden. Die Möglichkeiten, die Eclipse beim Build-Management bietet, der ausgereifte Java-Editor und zahlreiche Erweiterungsmöglichkeiten gaben den Ausschlag, Eclipse auch für J2EE-Entwicklung einzusetzen. Eine der reichhaltigsten Unterstützungen im J2EE-Bereich bietet MyEclipse21 . Die MyEclipse-IDE ist eine Sammlung von Eclipse-Plugins. Integriert sind z. B. JSP- und XMLEditoren mit Code-Assistent (für Deployment-Deskriptoren), Serverüberwachung für JBoss und andere Server sowie Deployment-Unterstützung durch die Möglichkeit des Packens 21 myeclipseide.com 98 4. JBoss Application Server und Deployens direkt aus Eclipse. Ebenso ist eine XDoclet-Unterstützung integriert. Hinzu kommen verschiedene Templates und Dialoge zur Erstellung ganzer Enterprise-Anwendungen. Das Lizenz-Modell von MyEclipse bietet eine 30-tägige, voll funktionstüchtige Test-Version. Im Anschluss daran kann man einen Support-Vertrag abschliessen, der circa 30 US$ im Jahr kostet. Darin enthalten ist die vollständige unbegrenzte Nutzung von MyEclipse für die Dauer des Vertrags mit kostenlosen Updates auf die in dieser Zeit entstehenden MyEclipseVersionen. NetBeans von Sun bietet von Hause aus Unterstützung für J2EE-Entwicklung. Dabei ist NetBeans genau wie Eclipse kostenlos und bietet einen großen Funktionsumfang (GUIDesigner, JSP-, XML-Editoren...). Die wichtigsten Eigenschaften wie inkrementelles Kompilieren, automatische Codevervollständigung und CVS-Unterstützung bieten NetBeans, wie auch Eclipse an. Im Vergleich zu Eclipse benötigt NetBeans jedoch mehr Zeit beim Start und das Darstellen von GUI-Elementen dauert ebenfalls länger. Der Grund hierfür ist in der Verwendung von SWT bei Eclipse zu finden. Diese systemnahe Bibliothek bedient sich der Grafikfähigkeiten des zugrunde liegenden Betriebssystems, während NetBeans seine Elemente „selbst zeichnet“. 4.8. Vergleich zwischen J2EE-Application-Servern An dieser Stelle soll ein Überblick über weitere Application-Server gegeben werden, um eine Einordnung des JBoss möglich zu machen. Am Ende des Kapitels wird im Fazit, eine Einschätzung der untersuchten Servern, im Vergleich zum JBoss, gegeben. 4.8.1. JOnAS Der freie JOnAS Application-Server, der ebenfalls wie JBoss unter der LGPL22 steht, ist durch die Initiative von mehreren europäischen Firmen, darunter die France Telecom, INRIA und Bull, in Frankreich entstanden. Diese Firmen gründeten das ObjectWeb Consortium23 , um eine Open-Source-Middleware für die Telekommunikationsbranche zu entwi22 23 Lesser GNU Public License http://www.objectweb.org 4. JBoss Application Server 99 ckeln. Entwickelt werden JOnAS und andere Projekte, die teilweise in den ApplicationServer einfließen, an mehreren Universitäten und innerhalb der beteiligten Firmen. Die Architektur des JOnAS nennen seine Entwickler „ServiceBased“, das bedeutet, dass alle Dienste, die der Server anbietet, in einem eigenständigen Modul entwickelt werden. Somit ist ebenso wie beim JBoss jedes Modul (wie z. B. der Security-Service oder auch JavaMail-Service) austauschbar. Dies ist sowohl durch eigene Applikationen möglich als auch durch neuere Versionen der ObjectWeb-Gruppe. Dieses modulare Konzept ermöglicht technische Anpassungen und Erweiterungen. Der JOnAS-Server nutzt JMX zum Steuern der einzelnen Komponenten. Zusätzlich bietet der JOnAS eine Web-Anwendung zur Administration namens JonasAdmin. Dieses Programm gibt einen guten Überblick über alle Ressourcen des Servers. Es zeigt die verschiedenen Typen von installierten EJBs und Anwendungen (EAR, WAR, JAR) sowie deren Anzahl an. Da ein Hot-Deployment-Mechanismus beim JOnAS fehlt können Deployments mit Hilfe des JonasAdmin durchgeführt werden. Ebenso steht die Verwaltung aller Services, wie Transaction, JMS oder auch Security, zur Verfügung. Das Einrichten der Datenbankparameter, Message-Queues und Topics ist ebenfalls unter der JonasAdmin-Oberfläche vereint. Im Bereich Server/Monitoring ist die Speicher-Auslastung zu sehen. Unter dem Menüpunkt Server kann bei Bedarf der JavaGarbage-Collector explizit gestartet werden. Alternativ kann auch ein Konsolen-Programm (statt jonas start dann jonas admin) eingesetzt werden. Dies ist z. B. von Vorteil, wenn kein Servlet-Container eingesetzt werden soll oder der Server keine grafische Ausgabe unterstützt. Mit der Eingabe -? listet man alle Kommandos des Konsolen-Programms auf. Die Synopsis der einzelnen Befehle sind in der Dokumentation beschrieben. JonasAdmin bietet die Möglichkeit, mehrere Server zu verwalten, die durch Namen unterschieden werden. Mehrere parallel auf einem Rechner laufende Application-Server sind jedoch nicht zwingend notwendig, da die Konfiguration jeder Anwendung auf dem Server individuell angepasst werden kann. Die aktuelle Version des JOnAS unterstützt den J2EE 1.3 Standard und befindet sich genau wie JBoss in der Sun-Zertifizierungs-Phase. Durch die Integration von JORM, ebenfalls ein Projekt von ObjectWeb, unterstützt JOnAS ab Version 3.0 auch CMP 2.x und kann durch JORM auch andere Persistenz-Mechanismen wie JDO direkt einsetzen. Die gut strukturierte Webseite bietet eine Versionshistorie sowie Dokumente, HowTo‘s und Tutorials, die den Einstieg erleichtern. Die Stärke des JOnAS ist seine gute Dokumentation, die gute Serververwaltung durch JonasAdmin und die Bereitstellung von Entwickler- 100 4. JBoss Application Server Werkzeugen wie z. B. JOPE einem Eclipse-Plugin. Zu seinen Schwächen zählt das fehlende Hot-Deployment und die im Vergleich zum JBoss geringere Verbreitung. JOnAS wurde laut Angaben auf der Projekt-Webseite seit Bestehen 100.000 mal herunter geladen, was in etwa der Anzahl der Downloads des JBoss innerhalb von zwei Monaten entspricht. 4.8.2. Oracle 10g und Orion Application Server Oracle setzt bei seinem Angebot eines Application-Servers auf die Integration des Orion Application Servers. Als einer der führenden Datenbank-Hersteller bietet Oracle damit den Service für ein Gesamtpaket aus Application-Server und Datenbank. Erweitert wurde der Orion, um bessere Unterstützung von WebServices, ein Application-Framework und unterstützende Programmen zur einfacheren Erstellung komplexer Anwendungen. Dazu gehört z. B. Oracle JDeveloper, eine reichhaltige IDE, die auf die Verwendung mit dem Oracle 10g Application Server zugeschnitten wurde. Im Folgenden soll der Orion-Server genauer untersucht werden. Die Erweiterungen die Oracle vorgenommen hat, betreffen vor allem die Unterstützung des Server-Administrators und der Entwickler. Auf der technischen Ebene ist vor allem eine Verbesserung der JDBCAnbindung an die Oracle Datenbank zu nennen und Optimierungen von generierten SQLStatements. Der Orion-Server der Firma Ironflare AB aus Schweden ist auch als Einzelprodukt als kommerzieller Server erhältlich. Der Server ist für Entwickler kostenlos, beim kommerziellen Einsatz ist jedoch eine Gebühr von 1500 US$ pro Server (die Anzahl der CPUs spielt keine Rolle) zu entrichten. So kann man ihn ausgiebig testen, bevor er in eine produktive Umgebung eingeführt wird. Orion war einer der ersten verfügbaren kommerziellen J2EE-Server auf dem Markt. Und nach eigenen Aussagen ist er auch der schnellste J2EE-Server. Da die Firma ihr Produkt nicht unter einer Open-Source-Lizenz vertreibt, ist über die Architektur wenig in Erfahrung zu bringen. So wird z. B. JMX auf der Orion-Webseite24 nicht erwähnt. Beschrieben sind jedoch einige Eigenschaften die angeboten werden, wie z. B. das automatische Update via java -jar autoupdate.jar, die automatische Generierung von Primärschlüsseln, das Mitliefern der HSQLDB und ein Mechanismus für automatisches Deployment (Hot-Deployment), wie man ihn bereits aus dem JBoss kennt. Anders als beim 24 http://www.orionserver.com 4. JBoss Application Server 101 JBoss muss das Auto-Deployment erst aktiviert werden. Dazu setzt man in der Datei ORION_HOME/config/server.xml im Tag <application-server> den Wert application-auto-deploy-directory auf den Pfad zum Auto-Deploy-Ordner. Danach verhält sich der Dienst wie der des JBoss und man kann an der Server-Konsole den Deploy-Vorgang verfolgen. Eine weitere Initiative der Orion-Entwickler nennt sich "WAP25 strategy for Orion". Darunter verstehen die Entwickler, dass WML-Clients26 automatisch erkannt werden und die vom Applikations-Entwickler gefertigten (oder generierten) XML-Seiten via XSLT zu einer WML-Seite formatiert werden. Dies ist natürlich auch in anderen Servern möglich, aber der Mechanismus des automatischen Auswählens erleichtert es, diesen Dienst bereitzustellen. Wie es für einen kommerziellen Server üblich ist, bringt auch der Orion entsprechende Werkzeuge zur Administration mit. Einige dieser Werkzeuge, wie das Auto-Update, sind reine Kommandozeilenprogramme (JAR Archive mit Parametern). Es gibt aber auch grafische Programme, die die Erstellung von EJBs unterstützen (ejbmaker.jar), Archive zusammenstellen ( *assembler.jar) und die Orion-Management-Konsole (orionconsole.jar), die zur Überwachung der installierten Anwendungen und für Deployment eingesetzt werden kann. Unter dem Eintrag "Serverinfo"wird der zur Zeit verwendete Speicher angezeigt. Unter den Einstellungen HTTP und RMI kann man auch Einstellungen zum Clustering vornehmen. Die Orion-Konsole befindet sich jedoch im Alpha-Stadium und sollte daher nicht im produktiven Einsatz benutzt werden. Weitere Möglichkeiten sind das Deployment über die Konsole beim Start des Servers oder über Ant, das genauer in der Orion-Dokumentation erklärt wird. In Orion ist bereits, analog zum JBoss, eine HSQLDB integriert. Sie ist als Standard Datenquelle vorkonfiguriert und kann direkt für CMP-Entity Beans eingesetzt werden. Wenn man eine andere Datenquelle benutzen möchte, muss man die Datei ORION_HOME/config/ data-sources.xml anpassen. Der aktuelle Orion-Server ist von Sun für J2EE-Version 1.3 zertifiziert. Um dieses Zertifikat zu erhalten, müssen zahlreiche Tests absolviert werden. Die Dokumentation des Orion ist noch abgerundeter als beim JOnAS Server und bietet umfassende Hilfe. Beispielanwendungen, Tutorials und JavaDoc zu den Server-APIs stehen 25 26 Wireless Application Protocol Wireless Markup Language 102 4. JBoss Application Server den Nutzern auf der Webseite zur Verfügung. Das Forum auf der Seite ist klein, es gibt aber eine direkte E-Mail-Unterstützung vom Hersteller. Dabei werden natürlich lizenzierte Orion-Server-Betreiber bevorzugt. 4.8.3. BEA WebLogic 8.1 Das Unternehmen BEA Systems, Inc. gilt als einer der Marktführer im Bereich Enterprise Application-Server. Mit der aktuellen Version 8.1 des BEA WebLogic-Servers bietet das Unternehmen einen zertifizierten J2EE-1.3-Application-Server, der ebenfalls wie JBoss auf einem JMX-Kern beruht. Zu den zum Standard gehörenden Diensten wie RMI-IIOP, JAAS, Transactions, JMS, EJB 2.0 und der Unterstützung von JSP und Servlets, bietet BEA zusätzliche Werkzeuge und Features an. Dazu gehören die vollständige Integration von WebServices, die kompatibel zu .NET sind, sowie mit jCOM eine Java-COM+ Brücke. Diese erlaubt das Einbinden von COM+-Diensten, die auch in .NET verwendet werden. Wie jeder Hersteller von kommerziellen Softwarelösungen, gibt auch BEA an, das der WebLogic 8.1 einen Performance-Vorteil gegenüber Konkurrenz-Produkten wie Oracle 10g oder IBM WebSphere besitzt. Dies ist jedoch sehr von den Testumgebungen abhängig. BEA entwickelt im Zusammenhang mit dem WebLogic-Server eine eigene JVM, die für Intel-Plattformen optimiert ist. Mit Hilfe dieser JRocket-JVM verspricht BEA eine gesteigerte Performance. JRocket ist kostenlos auch ohne WebLogic verfügbar. Eine der größten Stärken von BEA liegt jedoch im Angebot an unterstützender Software. Dazu gehört z. B. eine Web-Admin-Konsole, die über die Performance, Speicher und Anwendungen Aufschluss gibt und den Server mit Hilfe von SNMP27 überwacht. Eines der aufwändigsten Programme stellt die Entwicklungsumgebung BEA WebLogic Workshop dar. Die integrierte Entwicklungsumgebung WebLogic Workshop bietet nicht nur einen JavaEditor mit Build-Management und Erweiterungen für J2EE-Entwicklung, sondern bietet visuelle Programmerstellung. Dabei helfen Dialoge und grafische Oberflächen beim Zusammenstellen einer komplexen Anwendung. Dieses Vorgehen unterstützt den Anwendungs-Architekten, der zum Abschluss seiner Arbeit ein Gerüst erhält, das bereits wichtige Entwurfsmuster umsetzt. Dabei können sowohl WebServices grafisch generiert werden als auch Abbildungen von Web-Formularen auf Datenbanktabellen. Durch die Integration 27 SNMP: Simple Network Management Protocol 4. JBoss Application Server 103 von Struts ist eine saubere Trennung nach dem MVC-Modell 5.3.2 in der Weboberfläche gegeben. Der Architekt kann die einzelnen generierten Methoden seiner Arbeit von Entwicklern, die genaues Wissen über die fachlichen Anforderungen besitzen, mit Logik füllen lassen. Die Unterstützung des Deployments innerhalb des WebLogic Workshops ist nur eine von sechs Methoden zum Installieren von Anwendungen. Auch BEA bietet seit Version 8.1 einen Auto-Deployment-Mechanismus. Dieser Deployment-Mechanismus ist jedoch nicht für den Produktions-Modus des Servers freigegeben. Daher muss das Start-Skript des Servers die Option -Dweblogic.ProductionModeEnabled=false enthalten. Danach können Web-Applikationen und Enterprise-Applikationen in das Verzeichnis applications kopiert werden. Ein Ändern der Anwendung (so genanntes Redeployment) ist möglich, indem man eine Datei mit dem Namen REDEPLOY im WEB-INF bzw. META-INF erstellt und dieser bei jeder Änderung z. B. über den Befehl touch einen neuen Zeitstempel zuweist. Weitere Methoden zum Deployment sind das Installieren der Anwendungen über die Server Admin Konsole mittels weblogic.Deployer, einem Konsolen-Java-Programm, über den WebLogic Builder, einem grafischen Programm zum Packen und Deployen, über das Editieren der config.xml-Datei und mittels Ant über den ServerDeploy Task. WebLogic stellt zahlreiche Dokumente, Tutorials und Demos, wie z. B. die Avitec-Webanwendung zur Verfügung, um einen einfachen Start in die Entwicklung mit WebLogic zu ermöglichen. 4.8.4. IBM WebSphere Der IBM-Application-Server WebSphere 5 ist ebenso, wie die bereits beschriebenen kommerziellen Server, J2EE 1.3-zertifiziert. Er basiert wie JBoss und WebLogic ebenfalls auf einem JMX-Kern, der das Anbinden verschiedener MBean-Dienste möglich macht. IBM stellt seinen Server in unterschiedlichen Konfigurationen zum Kauf bereit, angefangen vom WebSphere-Express, der keine EJBs unterstützt und somit als Servlet-Container anzusehen ist, bis hin zur Enterprise Edition, die J2EE und Clustering unterstützt. Als ServletContainer und Web-Server integriert WebSphere die Open-Source Projekte Apache 1.3 und Tomcat 4. 104 4. JBoss Application Server WebSphere bietet zusätzlich zu den in der J2EE-Spezifikation geforderten Techniken auch eigene Erweiterungen, welche die Anwendungs-Erstellung vereinfachen oder aber die Performance der Anwendung erhöhen. Eine der interessanten Neuerungen sind die asynchronous Beans. Sie stellen eine asynchrone Möglichkeit der Kommunikation mit verschiedenen Komponenten (EJBs) dar. Anders als die ebenfalls asynchronen MDBs sind sie jedoch nicht auf einen Nachrichtendienst wie JMS angewiesen. WebSphere startet diese asynchronen Beans mit eigenen Threads und verwaltet sie entsprechend. Als eigentlichen JMS-Dienst setzt IBM auf WebSphere-MQ, das ehemalige MQ-Series. Eine andere Erweiterung stellt der Dynamic Query Service (DQS) dar. Dieser ermöglicht SQL-Statements zur Laufzeit zu erzeugen und an die Datenbank zu schicken. Dieser Dienst kann jedoch mit einfachen Mitteln (Session Bean mit JDBC-Logik) auf jedem Server zur Verfügung gestellt werden. Auch IBM bietet einen großen Satz an unterstützenden Programmen für die Erstellung und Verwaltung der Anwendungen sowie Überwachung und Steuerung des Servers. Zur Verfügung stehen für die Serverüberwachung eine Web-Management-Konsole (Wsadmin) und ein ebenso umfangreiches grafisches Programm. Zusätzlich gibt es ein Konsolen-Werkzeug, das durch Skripte gesteuert werden kann. Die Anwendungserstellung erfolgt vorzugsweise mit dem auf Eclipse aufbauenden WebSphere Studio Application Developer 5 (WSAD). Dieses bietet Integration für UML, Datenflussabbildung, Editor und die für Eclipse typische Plugin-Erweiterbarkeit. Durch die Übernahme von Rational Rose ist nun auch die Rational XDE für WebSphere verfügbar und passt sich in die Eclipse-Plattform ein. Damit ist es möglich, gesamte Geschäftsabläufe in UML zu modellieren und daraus Code erzeugen zu lassen. Der Deployment-Vorgang beim WebSphere wird mit Hilfe von grafischen Programmen, der Entwicklungsumgebung und durch die Web-Management-Konsole unterstützt. Ein Hot-Deployment-Mechanismus ist vorhanden, jedoch wird vor dem Einsatz in einem Produktivsystem gewarnt. Die Dokumentation des WebSphere ist umfangreich und wird online durch die IBM RedBooks erweitert. Diese technischen Dokumente informieren über neue Entwurfsmuster und geben Hilfestellungen zur Konfiguration des WebSphere. 4. JBoss Application Server 105 4.9. Fazit Bei der Frage nach dem geeigneten J2EE-Application-Server sind die Szenarios vielfältig. Soll der Server eingesetzt werden, um J2EE zu evaluieren oder als Testumgebung für Entwickler, die einen schlanken Server für die Workstation benötigen oder wird über die Ablösung von kommerziellen Servern wie Weblogic oder Websphere durch einen kostenlosen Open-Source-Server nachgedacht? JBoss und JOnAS bieten die Stabilität und Reife für einen produktiven Einsatz und können kostenlos eingesetzt werden. Die Marktreife der kommerziellen Server steht außer Frage und wurde in zahlreichen Projekten demonstriert (Beispiele findet man auf den jeweiligen Hersteller-Webseiten). Die sehr umfangreiche Dokumentation, die Unterstützung durch Beispiele und Architektur-Vorschläge sowie der 24x7-Support bieten alles, was ein Projekt benötigt. Die Kosten, die beim Einsatz der Lösungen von IBM und BEA entstehen, sind jedoch sehr hoch. JBoss bietet daher einen anderen Ansatz. Der Application-Server steht kostenlos und mit Quelltext zur Verfügung. Die Unterstützung der Anwender wird jedoch nicht durch eine umfangreiche kostenlose Dokumentation unterstützt. Vielmehr ist die Idee der JBossGroup, einen bezahlten Service anzubieten (ebenfalls 24x7). Somit bezahlt man nicht für ein Produkt, sondern für eine Lösung. Die Unterstützung der Projekte wird durch JBoss-zertifizierte Entwickler zur Verfügung gestellt. Man verspricht sich davon, Projekte günstiger und schneller realisieren zu können, als dies mit kommerziellen Servern ohne eine solche Unterstützung möglich ist. Die folgende Tabelle stellt einige Kenngrößen der Application-Server dar. Da sie sich alle am Standard der J2EE 1.3 orientieren, sind die Unterschiede marginal: Tabelle 4.1.: Übersicht Applikationserver (nach [The03] und Hersteller-Informationen) Merkmal Server Version Java Version JBoss JOnAS WebLogic WebSphere Orion v3.2.3x v3.3 v8.1 v5 v2.02 JDK 1.3.1 JDK 1.3.1 JDK 1.4.1 / IBM 1.3.1 JDK 1.4.1 Jrocket J2EE Version J2EE 1.3 J2EE 1.3 J2EE 1.3 J2EE 1.3 J2EE 1.3 Zertifikat im Sun- im Sun- J2EE 1.3 J2EE 1.3 J2EE 1.3 Test Test 106 Merkmal 4. JBoss Application Server JBoss JOnAS WebLogic WebSphere Orion EJB 2.0 2.0 2.0 2.0 2.0 Servlet 2.3 2.3 2.3 2.3 2.3 JSP 1.2 1.2 1.2 1.2 1.2 JMX 1.1 1.0 1.0 1.1 keine Angabe JMS 1.0.2 1.1 1.0.2 1.02 1.0.2 JAAS 1.0 1.0 1.0 1.0 1.0 JavaMail 1.2 1.3 1.1.3 1.2 JNDI 1.2 1.2.1 RMI-IIOP JDBC 2.0 Clustering integrierte DB HSQLDB 1.2 2.0 2.0 2.0 2.0 - - Cloudscape HSQLDB Legende: - Unterstützung vorhanden Je nach bereits vorhandener IT-Infrastruktur eines Unternehmens und dessen Größe können die unterschiedlichen Konzepte ihre Vorteile geltend machen. Durch die Interoperabilität von J2EE-Anwendungen ist die Migration von einem Server auf einen anderen möglich. Alle vorgestellten Unternehmen bieten hierfür Unterstützung an. Durch den kostenlosen Einsatz der Open-Source-Server sind sie auch für Entwickler, welche kommerzielle Server benutzen, interessant. JBoss und JOnAS sind weniger speicherintensiv und können so zu Entwicklungszwecken auch auf Arbeitsrechnern und Notebooks installiert werden. Die stetige Weiterentwicklung und wachsende Verbreitung im Zusammenhang mit kleineren Budgets im IT-Bereich eröffnen die Möglichkeit, vermehrt auch in großen Unternehmen als Produktionsserver eingesetzt zu werden. 5. Referenz-Anwendung Um die, in den voran gegangenen Kapiteln gewonnenen Erkenntnisse praktisch umzusetzen, wurde im Rahmen dieser Diplomarbeit eine Referenzanwendung für den JBoss Application Server entwickelt. Bei der folgenden Beschreibung des praktischen Teils der Diplomarbeit werden sowohl die programmiertechnischen Details als auch die für die Anwendung notwendige Konfiguration des JBoss dargestellt. Für das Verständnis des folgenden Kapitels werden grundlegende Kenntnisse im Bereich Softwareentwicklung vorausgesetzt. 5.1. Zielsetzung Die hier vorgestellte Anwendung soll ein Beispiel einer J2EE-Anwendung darstellen, die auf dem JBoss Application Server lauffähig ist und sich an Entwurfsmustern für J2EE-Systeme orientiert. Es wird nicht der Anspruch erhoben ein vollständiges und praxistaugliches Programm bereitzustellen. Um die wichtigsten von J2EE angebotenen Techniken implementieren zu können, wurde als komplexes Beispiel der Prototyp eines Projektmanagement-Programms entwickelt. Die Anwendung soll dazu benutzt werden, Informationen über aktuelle Projekte auszutauschen. Durch die Möglichkeit Nachrichten zu bestimmten Projekten in das System einzustellen kann es als Bug-Tracking-System benutzt werden. Dazu ist es möglich Nachrichten zu erstellen, zu lesen und sich über Projektdetails zu informieren. Eine der Kernideen in der Planungsphase war es, den einzelnen Benutzern der Anwendung zusätzlich ihre Spezialgebiete und Fähigkeiten zuzuordnen. Mit Hilfe der Angaben der im System registrierten Nutzer kann man so die Wissensbasis eines Unternehmens leichter ergründen und so Spezialisten für bestimmte Aufgabenstellungen ausfindig machen. Dadurch ist es möglich, Probleme die in einem Projekt bestehen, schneller zu lösen. 108 5. Referenz-Anwendung Die möglichen Anwendungsfälle des Systems werden im folgenden Abschnitt mit Hilfe von UML dargestellt. 5.2. Anwendungsfälle - UML Um eine Anwendung zu entwickeln, benötigt man zunächst eine Vorstellung von dem, was sie leisten soll. Dazu ist es sinnvoll, die Anwendung aus der Sicht des Nutzers zu betrachten. Das Modellieren dieser Anforderungen geschieht mittels UML (vgl. 2.3.2). Das unten dargestellte Anwendungsfall-Diagramm zeigt die typischen Aktionen der Nutzer des Systems. Die Nutzer werden je nach Status unterschieden. Es wurden dabei nur die wichtigsten Anwendungsfälle modelliert. Technische Details, wie die Überprüfung der Benutzerkennung durch die Anwendung, werden in diesem Diagramm nicht dargestellt. News lesen News einstellen registrieren Nutzerdaten ansehen nicht registrierter Nutzer eigene Daten ändern angemeldeter Nutzer Nutzer suchen anmelden abmelden Projektdaten anzeigen nicht angemeldeter Nutzer Abb. 5.1: Anwendungsfälle des Benutzers Die Anwendung wird von unterschiedlichen Benutzern mit verschiedenen Benutzer-Rollen verwendet. Neben der Rolle des normalen Benutzers, wie er oben dargestellt ist, wird weiterhin die Rolle des Administrators benötigt. Dieser erhält umfassende Rechte, wie z. B. das Löschen, Ändern und Erstellen von Daten. Abbildung 5.2 zeigt die Anwendungsfälle des Administrators. Da der Administrator eben- 5. Referenz-Anwendung 109 falls ein Benutzer sein kann, sind ihm implizit auch die Anwendungsfälle aus Abbildung 5.1 zuzuordnen. Nutzer freischalten Nutzer löschen Nutzerdaten ändern Projekt bearbeiten anmelden nicht angemeldeter Administrator angemeldeter Administrator Nachrichtentyp bearbeiten Skill-Typen bearbeiten abmelden Skill-Gruppen bearbeiten Bearbeiten umfasst die Aktionen: Erstellen, Löschen und Ändern Abb. 5.2: Anwendungsfälle des Administrators 5.3. Aufbau, Architektur und Entwurfsmuster Eine der häufigsten Formen von J2EE-Anwendungen besitzt ein Web-Interface zur Interaktion mit dem Nutzer. Dabei werden die Daten der Anwendung dem Nutzer in einem Browser dargestellt. Man bezeichnet solche Web-Anwendungen als Thin-Client, da sie kaum Ressourcen auf dem Clientrechner benötigt. Mittlerweile gehören Web-Browser auf fast jede Plattform zur Standardsoftware. Dadurch ist eine große Plattformunabhängigkeit auf der Clientseite gegeben. Ein weiterer Vorteil ist, dass die Browsernutzung zur alltäglichen Arbeit von Entwicklern, die ein solches Projektmanagement-Programm einsetzen, gehört. Web-Oberflächen sind den Nutzern des WWW vertraut und somit ist bei einfachen Anwendungen, ein geringerer 110 5. Referenz-Anwendung Schulungsaufwand notwendig. Da Web-Anwendungen aus oben genannten Gründen nicht clientseitig installiert werden müssen, ist auch die System-Einführung mit weniger Aufwand verbunden. Die Installation und Integration der Anwendung geschieht an einem zentralen Punkt (Server oder Cluster) und steht dann allen Anwendern über das Internet oder Intranet zur Verfügung. Auch die Referenzimplementierung, die im Rahmen dieser Diplomarbeit entstand, verwendet eine Web-Oberfläche. Um auch die Vorgehensweise für die Benutzung von grafischen Client-Anwendungen zu zeigen, wurde ein Prototyp einer Administrator-Anwendung erstellt. Solche grafischen Oberflächen werden auch als Rich-Client bezeichnet. Sie binden selbst Ressourcen auf dem Clientrechner und können dadurch mehr Geschäftslogik beinhalten. Ihnen steht auf dem Client-Rechner eine bestimmte Menge an Speicher und Prozessorleistung zur Verfügung. Die Vor- und Nachteile von Thin- und Rich-Client werden in den entsprechenden Kapiteln aufgezeigt. Durch die Einteilung der Anwendung in verschiedene Schichten kann ein Austausch der Benutzeroberfläche geschehen, ohne Änderungen an den darunterliegenden Schichten vorzunehmen. Daher soll zunächst der Aufbau der gesamten Anwendung beschrieben werden. Danach wird auf die Web-Anwendung eingegangen. Wie die Anbindung der Administrator-Anwendung an den JBoss Application Server geschieht, wird im Kapitel 5.6 erläutert. 5.3.1. Multitier-Anwendung Wie bereits in Kapitel 2.2.1 erläutert, werden Anwendungs-Systeme in verschiedene Schichten unterteilt. Man spricht hierbei von Multitier-Anwendungen. Auch die hier beschriebene Referenzanwendung folgt diesem Design und lässt sich in die folgenden Schichten unterteilen: • Frontend: Das Frontend (Präsentations-Schicht) repräsentiert die Benutzer-Schnittstelle. In der Referenz-Implementierung wurden zwei Arten von Frontends entwickelt. Zum einen der Thin-Client, die Web-Anwendung. Zum anderen der Rich-Client, die Administrator-Anwendung. 5. Referenz-Anwendung 111 • Geschäftslogik: Die Geschäftslogik-Schicht repräsentiert die verschiedenen am System ausführbaren Aktionen. In J2EE-Anwendungen werden zu diesem Zweck Session Beans eingesetzt. • Datenhaltungs-Schicht: In dieser Schicht werden die Daten der Anwendung für die Geschäftslogik bereitgestellt. Eine J2EE-Anwendung ist ein komponentenbasiertes System, dessen Komponenten objektorientiert realisiert sind. Daher müssen die Daten in Form von Objekten zur Verfügung stehen. Daten werden traditionell in relationalen Datenbanken gehalten. Um diese Daten als Objekte bereitstellen zu können, werden Entity Beans eingesetzt. Diese stellen das Objekt-Relationale-Mapping zur Verfügung (vgl. 3.3.3). • Datenbank-System: Die Daten der Anwendung werden in einer Datenbank gehalten. Der Zugriff erfolgt innerhalb der Referenzanwendung nicht direkt, sondern wird durch die Entity Beans verborgen. Als relationale Datenbank wird die in JBoss integrierte HSQLDB eingesetzt. Der Aufbau der verschiedenen Schichten ist auf unterschiedlichste Art und Weise möglich. Durch praktische Erfahrungen zahlreicher Entwickler, wurden die besten Ansätze für die Lösung auftretender Probleme veröffentlicht. Diese Ansätze werden als „best practices“, Pattern oder Entwurfsmuster bezeichnet. Bei der Entwicklung der Referenz-Anwedung wurden diese Entwurfsmuster berücksichtigt. Durch den Einsatz der Entwurfsmuster verspricht man sich eine bessere Performance, Skalierbarkeit und Sicherheit der Anwendung. 5.3.2. Entwurfsmuster: MVC 2 - Web Das Model-View-Controller-Entwurfsmuster (MVC) ist eines der am häufigsten eingesetzten Entwurfsmuster. Dabei wird es nicht nur in Web-Anwendungen eingesetzt sondern ebenso in grafischen Benutzeroberflächen. Erstmals wurde es bei der Programmiersprache Smalltalk-80 eingeführt (vgl. [KP88]). Ziel von MVC ist es, die Anwendung funktional zu unterteilen: • Model: Das Modell kapselt den Zustand und die Daten der Anwendung. 112 5. Referenz-Anwendung • View: Die View (Ansicht) repräsentiert die Daten des Modells und dient zur Interaktion mit dem Benutzer. • Controller: Der Controller empfängt Ereignisse aus der View und entscheidet über die Art der Verarbeitung. Je nach Ereignis kann die View ausgetauscht oder geändert und die Daten der Anwendung beeinflusst werden. Der Controller ist das Bindeglied zwischen der Präsentations- und Datenschicht und stellt die Geschäftslogik dar. Dieses Schema wurde von Sun auch für den Einsatz in verteilten Web-Anwendungen vorgeschlagen. Im Zusammenhang mit J2EE werden für die Darstellung von Web-Anwendungen JSPs und Servlets eingesetzt. JSPs eignen sich durch den deklarativen Stil zur Erzeugung dynamischer Webseiten. Sie sollten daher für die Präsentation eingesetzt werden. Durch die Trennung von Logik und Darstellung ist es so auch möglich, Web-Designern die Erstellung der JSPs zu überlassen. Web-Anwendungen besitzen eine Vielzahl unterschiedlicher Ansichten. Diese ändern sich während der Navigation des Benutzers. Wenn die Web-Anwendung verschiedene, was bei J2EE-Anwendungen häufig der Fall ist, Benutzer unterscheiden muss, wird eine Kontrollinstanz benötigt, die den Zugriff auf die Ressourcen der Anwendung überwacht - der Controller. Damit sich der Benutzer nicht bei jeder neu aufgerufenen Seite identifizieren muss, wird dem Nutzer eine Identität zugeordnet (Single Sign On). Diese Identität bezeichnet man als Session-ID. Um jeden Aufruf zu kontrollieren wird ein zentrales Servlet eingesetzt, welches alle Aufrufe entgegennimmt. Es fungiert als Einstiegspunkt der Anwendung. Der Controller entscheidet sowohl über den Zugriff als auch die Auswahl der anzuzeigenden View. Das Controller-Servlet ist der Vermittler zwischen der Geschäftslogik- und Präsentationsschicht. Der Ablauf einer Benutzerinteraktion mit dem Controller ist in der folgenden Abbildung dargestellt: Client (Browser) Anfrage ControllerServlet Geschäftslogik (Enterprise JavaBeans) Antwort JSP-View Abb. 5.3: MVC 2 Web-Architektur 5. Referenz-Anwendung 113 Diese Architektur hilft die View-JSPs von Programmcode freizuhalten. Das MVC 2-Modell ist je nach Komplexität und Anforderungen der Anwendung erweiterbar. Dazu können JSP-Tag-Bibliotheken erstellt werden, die es ermöglichen, weniger Programmcode auf verschiedene Dateien zu verteilen. Denkbar ist hier z. B. ein Tag zur Erstellung von Tabellen aus bestimmten Datenstrukturen. Eine große Anzahl solcher Tag-Bibliotheken ist bereits frei verfügbar. Eine weitere Möglichkeit der Erweiterung ist der Einsatz vorgefertigter Frameworks, welche das MVC-Pattern umsetzen. Eines der bekanntesten Beispiele hierfür ist Struts1 . Es ist sehr umfangreich und erfordert eine gewisse Einarbeitungszeit. Diese zahlt sich aber bei entsprechender Größe des Projekts aus. Ein weiteres Framework, das für die Erstellung des Frontends eingesetzt werden kann, ist Air2 . Dieses junge Framework bietet die Architekturmerkmale von MVC 2. Es verzichtet jedoch auf viele Merkmale von Struts, wie z. B. Tag-Bibliotheken. Es ist daher kleiner und durch die Beschränkung auf die notwendigsten Merkmale ist Air schnell erlernbar und performant. 5.3.3. Entwurfsmuster: Session-Fassade Die Session-Fassade ist ein Entwurfsmuster, das zum Ziel hat, die Performance der Anwendung zu erhöhen. Zusätzlich stellt es eine bessere Kapselung der Geschäftslogik-Schicht zur Verfügung. Die Session-Fassade bildet eine Schicht zwischen den Entity Beans, die die Datenhaltung darstellen, und der Client-Anwendung. Die Session Beans der Fassade besitzen in der Regel ein Remote-Interface. Dadurch können sie z. B. aus Servlet-Containern oder von Rich-Clients, welche innerhalb einer anderen JVM ablaufen können, angesprochen werden. Auf die Entity Beans wird grundsätzlich per Local-Interface zugegriffen. Wenn Session Bean Zugriff auf andere Session Beans benötigen, sollten diese ebenfalls ein Local-Interfaces anbieten. Die Datenübertragung am Remote-Interface gehorcht den Bestimmungen von RMI-IIOP (vgl. 3.2.2). Bei häufigen Zugriffen auf diese Schnittstelle ergibt sich somit ein Mehraufwand bei der Kommunikation (Marshalling und Unmarshalling), der unerwünscht ist. Die Belastung des Kommunikations-Netzwerkes erhöht sich. Die Session-Fassade kann mehrere zusammengehörige Aufrufe kapseln und auf den Entity Beans arbeiten. Da sie direkt über 1 2 http://jakarta.apache.org/struts/index.html http://www.air-framework.de/ 114 5. Referenz-Anwendung das Local-Interface mit den Entity Beans kommuniziert, wird die Performance gesteigert. Der Zugriff auf die Daten der Entity Beans besteht meistens aus eine Menge von Abfragen mehrerer Parameter. Je häufiger auf einzelne Attribute zugegriffen wird, umso geringer wird der Kommunikations-Overhead bei der Verwendung einer Session-Fassade. Zugriff über eine Session-Fassade in Verbindung mit einem DTO Direkter Zugriff ohne Sessionfassade Client UserEntity findByPrimaryKey():UserID getTitle() AdressEntity Client User SessionFassade usf.create() getUser():UID UserEntity AdressEntity findByPrimaryKey():UserID getTitle() getName() getName() findByUserID():UserID findByUserID():UserID getStreet() getStreet() getCity() getCity() getZip() DTO NetzwerkKommunikation via RMI-IIOP getZip() NetzwerkKommunikation via RMI-IIOP Abb. 5.4: Vergleich des Clientszugriffs mit und ohne Verwendung einer Session-Fassade 5.3.4. Entwurfsmuster: DTO Data Transfer Object Der Einsatz einer Session-Fassade hilft die Komplexität von RMI-IIOP Aufrufen zu vermindern. Die Daten die nun in der Session-Fassade gesammelt wurden, müssen von der Session-Fassade zum Frontend transportiert werden. Da dieser Kommunikationsweg über RMI-IIOP realisiert ist besteht eine ähnliche Problematik. Abhilfe verspricht hier das Entwurfsmuster Data Transfer Object. Eine DTO ist eine einfache JavaBean. Sie besitzt die Attribute der Daten, die in der Client-Anwendung dargestellt oder eingegeben werden. Für diese Attribute stellt die DTO Getter und Setter zur Verfügung. Sie kapseln also die Daten des Backends für den Transport zum Frontend. Da die Bestimmungen von RMI-IIOP verlangen, dass alle Daten serialisierbar sein müssen, implementieren die DTOs das Interface Serializable. Das bedeutet, dass alle Attribute der JavaBean serialisierbar sein müssen. 5. Referenz-Anwendung 115 Wenn diese Voraussetzungen erfüllt sind, kann ein einziges Objekt zum Frontend transportiert werden und muss nur einmal für RMI-IIOP vorbereitet werden. Ein weiterer Vorteil der DTOs ist, dass JSPs durch das <jsp:useBean>-Tag besonders leicht auf die Attribute der DTO zugreifen können. Somit ist es möglich, ein Daten-Objekt vom Frontend bis hin zum Backend zu verwenden. Die DTOs werden im Frontend-Bereich in das implizite Session-Objekt gespeichert und können bis zu ihrer Löschung in allen Frontend-Komponenten verwendet werden. Die DTOs bieten eine hervorragende Möglichkeit zur Erweiterung ihrer Funktionalität. Dadurch, dass diese Daten-Objekte als Java-Klassen realisiert sind, können sie auch Methoden beinhalten. Solche Methoden kann man z. B. einsetzen um Eingaben aus Formularen zu validieren oder sie entsprechend für das Backend bzw. Frontend aufzubereiten. Sinnvoll ist dies bei numerischen Eingaben oder der Eingabe eines Datums. 5.3.5. Entwurfsmuster: UUID Eine der häufigsten Anforderungen an Systeme, die eine Datenbank als Speicher einsetzen, ist die Generierung eines Primärschlüssels. Dieser Primärschlüssel wird verwendet um Datensätze eindeutig zu identifizieren. Die Erstellung eines Primärschlüssels kann auf verschiedene Weise erfolgen. Es kann ein kontextspezifischer Schlüssel verwendet werden wie z. B. die Personal- oder Kontonummer. Dieser ist in seinem Kontext eindeutig zuzuordnen. Bei anderen Daten gibt es keine solchen Schlüssel. Daher muss ein fiktiver Schlüssel generiert werden, bei dem die Gefahr einer doppelten Vergabe ausgeschlossen werden muss. Oftmals wird für solche Belange eine fortlaufende Nummer benutzt oder ein Zufallswert. Algorithmen, welche bei der Zufallszahlenerstellung Verwendung finden, lassen die aktuelle Systemzeit in die Berechnung mit einfließen. Bei verteilten Systemen besteht jedoch auch bei einer solchen Erstellung die Möglichkeit einer doppelten Vergabe. Dies geschieht z. B. bei der gleichzeitigen Erstellung von Schlüsseln. Die Chance ist bei wenigen gleichzeitig ablaufenden Schlüssel-Generierungen noch sehr gering, bei wachsender Benutzeranzahl jedoch immer wahrscheinlicher. Im Bereich Java und J2EE gibt es daher ein Entwurfsmuster, das durch verschiedene Verfahren sicherstellt, dass ein eindeutiger und weltweit einzigartiger Schlüssel erzeugt wird, eine UUID (Universal Unique IDentifier). In [Mar02] beschreibt Floyd Marinescu ein Verfahren 116 5. Referenz-Anwendung zur Erstellung einer UUID. Dabei setzt sich der 32-Bit-Schlüssel aus folgenden Teilschlüsseln zusammen: • Die niederwertigsten 8-Bit von System.currentTimeMillis(), um Schlüssel zu unterscheiden, die zu verschiedenen Systemzeiten erzeugt werden. • Zur Codierung des Ortes werden die nächsten 8-Bit aus der IP-Adresse des Nutzers gebildet. • Durch die nächsten 8-Bit werden Objekte unterschieden, die innerhalb der gleichen JVM auf einem Rechner innerhalb der gleichen Millisekunde erzeugt werden. Hierfür wird System.identityHashCode(this) aufgerufen. • java.security.SecureRandom erzeugt bei jedem Aufruf eine neue Zahl. Dies unterscheidet zwei Schlüssel, die exact zur selben Zeit erstellt wurden. All diese Maßnahmen erzeugen einen Schlüssel, von dem nur mit geringster Wahrscheinlichkeit ein zweiter identischer Schlüssel erzeugt werden kann. Besonders hervorzuheben bei diesem Pattern ist, dass eine einfache Javaklasse ausreicht, um den Schlüssel zu erzeugen. Andere Verfahren, die zuvor generierte Schlüssel in einer Datenbank speichern, verbrauchen zusätzliche Ressourcen und benötigen eine längere Ausführungszeit (vgl. Sequenz-Blöcke in [Mar02]). Als Nachteil dieser Schlüssel könnte man anführen, dass sie auf Menschen sehr kryptisch wirken. Wenn Schlüssel benötigt werden, die von Menschen direkt benutzt werden sollen, muss man auf andere Verfahren zurückgreifen (z. B. Sequenz-Blöcke). Ein Beispiel einer UUID ist der Folgende: "0aa8dc81-3f57fa230191c263-35a8691e". In der Anwendung wurde für die generierung der Benutzer-IDs auf das UUID-Pattern verzichtet, da diese Benutzer-IDs auch zu Login benutzt werden.Um sie zu generieren, wurden alle vorhandenen IDs aus der Datenbank abgefragt. Anschließend wurde über diese Menge iteriert und die nächste freie ID vergeben. Für eine Anwendung mit überschaubarer Benutzeranzahl, bei der sich nicht alle Nutzer gleichzeitig registrieren, ist dieses Verfahren hinreichend. 5. Referenz-Anwendung 117 5.4. Backend der Anwendung An dieser Stelle soll auf den Teil der Anwendung eingegangen werden, der sowohl die Geschäftsprozesse als auch die Datenhaltung darstellt. Wie bereits beschrieben, sollte eine J2EE Anwendung, die Entity Beans als Daten-ZugriffsSchicht einsetzt, über eine Session-Fassade auf diese Entity Beans zugreifen. Diesem Konzept folgend, soll hier das Daten-Modell der Anwendung gezeigt werden. Eine weitere Möglichkeit, um Anwendungen mit kurzen Antwortzeiten zu erzeugen, liegt in der Verwendung von Message-Driven Beans (vgl. 3.5). Durch die asynchrone Verarbeitung kann der Client nach dem Absetzen der Anfrage sofort weiterarbeiten, ohne auf die Beendigung der Methode zu warten. Das Versenden von News innerhalb der Anwendung wurde als Beispiel für eine MDB implementiert. Da eine Nachricht viele Informationen und möglicherweise auch einen langen Nachrichtentext enthalten kann, ist es sinnvoll, das Einstellen der Nachricht in das System vom Nutzer zu entkoppeln. So kann es sein, dass eine Nachricht, die an das System geschickt wurde, erst nach einer kurzen Zeit in der Nachrichtenübersicht erscheint. Der Nutzer, der die Nachricht geschickt hat, wird in der Regel nicht darauf warten wollen und kann sofort weiterarbeiten. Er hat die Gewissheit, dass die Nachricht sobald wie möglich eingestellt wird. 5.4.1. Datenmodell Abbildung 5.5 stellt das Datenmodell der Anwendung in verkürzter Form dar. Die vollständige Darstellung mit Angabe aller Attribute und Kardinalitäten, findet sich im Anhang auf Seite 141. Der zentrale Punkt des Datenmodells ist der User. Er besitzt zu fast allen anderen Entitäten eine Beziehung. So kann man vom User zu allen wichtigen Geschäftsdaten navigieren. Da es sich um ein objektorientiertes Modell handelt, wurde es mit Hilfe der Container Managed Relations auf die Datenbank abgebildet. Wenn nun ein Objekt, z. B. ein User, geladen wird, kann man alle Informationen die dieses Objekt betreffen mit einer Anfrage laden, also seinen Objektbaum. Ebenso ist durch die Bidirektionalität der eingesetzten CMR das Abrufen eines Users für die verbundenen Objekte möglich. 118 5. Referenz-Anwendung MESSAGETYPEENTITY NEWSENTITY PROJECTENTITY COMPONENTSENTITY STATUSENTITY TELEFONENTITY USERENTITY ADDRESSENTITY EMAILENTITY SKILLGROUPENTITY SKILLTYPEENTITY SKILLENTITY Abb. 5.5: Datenmodell: Verkürzte Darstellung Das Entwurfsmuster DTO muss diesem Modell Rechnung tragen und besitzt für verbundene Entitäten eigene Attribute. So besitzt die Klasse UserDTO eine ArrayList aller News des Nutzers. In dieser ArrayListwird eine Menge von NewsDTOs gehalten. Durch das Laden aller Attribute einer News-Entität wird durch die bidirektionale Beziehung zur UserEntität auch der User geladen, welcher selbst die News-Entität kapselt. Dies führt zu rekursiven Objektbäumen, die aufeinander verweisen. Um diese Problematik zu umgehen, werden beim Laden einer Entität nicht alle verbundenen Daten geladen. Die Entity Beans, welche die Daten repräsentieren, haben in der Anwendung eine Methode, die eine DTO zurückliefert. Diese ist mit allen Objekt-Attributen ausgestattet. Es wird jedoch auf die Initialisierung von verbundenen Daten innerhalb der Entity Bean verzichtet. Diese Aufgabe fällt der Session-Fassade zu. Sie besitzt Informationen darüber welche Daten im Frontend benötigt werden und lädt diese aus den entsprechenden Entity Beans. 5.5. Web-Anwendung Die im vorherigen Abschnitt beschriebenen Entwurfsmuster wurden bei der Implementierung der Referenzanwendung eingesetzt. Im Folgenden soll nun beschrieben werden, was die Web-Anwendung leistet und welche Besonderheiten bei der Implementierung und der JBoss-Konfiguration zu beachten sind. 5. Referenz-Anwendung 119 5.5.1. Aufbau und Architektur der Anwendung Wie im vorangegangenen Abschnitt erläutert ist es sinnvoll, die Anwendung in verschiedene Schichten zu unterteilen. Bei einer Web-Anwendung wird das Frontend als MVC 2 realisiert (vgl. 5.3.2). Controller Da die Anwendung Prototypen-Charakter besitzt, wurde der Controller der Anwendung mit einfachen Mitteln realisiert. Im Frontend werden hauptsächlich Formulare benutzt um Aktionen der Anwendung auszulösen. Dabei benutzen die JSPs eine JavaBean, die die Aktionen als numerischen Wert enthält. Diese JavaBean wird innerhalb des Controllers aus den Session-Daten extrahiert und der numerische Wert ausgelesen. Anhand dieses „Action-Wertes“ wird im Controller eine Fallunterscheidung durchgeführt. Jeder Wert ist einer bestimmten Aktion zugeordnet. In Java kann man solche Fallunterscheidungen auf verschiedene Arten durchführen. Eine Möglichkeit ist die Verwendung einer HashTable, die eine Zuordnung eines Schlüssels zu einem Wert erlaubt. Eine weitere Variante, die bei kleinen Anwendungen leicht zu implementieren ist, stellt ein switch - case-Konstrukt dar. Die Anwendung springt zu dem CaseBlock, dessen Wert angegeben wurde und führt diesen aus. Die Referenzimplementierung benutzt genau diese Vorgehensweise. Innerhalb des CaseBlöcke werden dann zusätzlich benötigte Daten aus dem impliziten Session-Objekt der Anwendung ausgelesen und der Zugriff mittels dieser Daten auf die Session-Fassade realisiert. Nach Beendigung der Aktion innerhalb der Fassade wird der Benutzer auf eine bestimmte Seite weitergeleitet. Auf dieser sind dann die Ergebnisse seiner Aktion sichtbar. Daten die aus der Session-Fassade zurückgeliefert wurden, befinden sich entweder innerhalb einer DTO oder bilden eine Menge von DTOs. Als Datentyp für Mengen wurde der Datentyp ArrayList verwendet. Abbildung 5.6 zeigt einen Ablauf einer solchen BenutzerInteraktion. Dabei wird darauf verzichtet, die Vorgänge innerhalb der Geschäftslogik darzustellen. 120 5. Referenz-Anwendung Session g / et se t Client ActionBean action=1082 newSkills ArrayList 1. JSP JSP JSP 3.1 set skillDTOs 1.1 get Controller switch (action) { case 1058 : } 2.setSkills(UID,newSkills) Backend 3. skillDTOs 4. Abb. 5.6: Ablauf eines Aufrufes an den Controller JSP-Frontend Zu Beginn der Interaktion mit dem Benutzer brauchen nicht alle Daten aus der Datenschicht zur Verfügung zu stehen. Daher wird die Initialisierung einer Ansicht erst bei deren Aufruf ausgelöst. Hierbei wird der Controller über verschiedene URLs aufgerufen. Dies ermöglicht anhand einer solchen URL, die Initialisierung einer Ansicht durchzuführen. Ein weiterer Grund den Controller über verschiedene URLs anzusprechen, liegt darin begründet, dass die Darstellung der Oberfläche mittels HTML realisiert wird. Diese HTMLSeiten werden von den JSPs generiert. Zur Umsetzung eines einheitlichen Designs der Oberfläche werden Cascading Style Sheets (CSS) eingesetzt. In diesen Stylesheets werden Design-Angaben zu Farben, Schrift und den benutzten HTML-Elementen definiert. Um die Stylesheets zentral für die Anwendung bereitstellen zu können, werden sie relativ zur jeweiligen JSP-Datei referenziert. Wenn nun aber der Controller über einen bestimmten Pfad aufgerufen wird, so kann die Referenz zum Stylesheet nicht mehr aufgelöst werden. Die Lösung dieses Problem bestand darin, dem Controller im Deployment-Deskriptor keinen absoluten Pfad zuzuordnen, sondern ein Namens-Muster. So wird der Controller generell aufgerufen, wenn die URL auf .ctrl (control) endet. Dadurch war es möglich, eine hierarchische Struktur innerhalb der JSPs beizubehalten und 5. Referenz-Anwendung 121 trotzdem über einen relativen Pfad auf das Stylesheet zuzugreifen. Nach der Initialisierung einer Ansicht stehen dem Benutzer bestimmte Aktionen zur Verfügung. Dazu gehört z. B. das Schreiben einer Nachricht, das Suchen eines anderen Benutzers oder auch das Ändern der persönlichen Daten. Die Anwendungsfälle sind in Abbildung 5.1 dargestellt. Wenn ein Benutzer eine solche Aktion auslöst, werden Formulardaten an den Controller geschickt. Zusätzlich zu diesem Formular wird in einer JavaBean die auszulösende Aktion gespeichert. Diese JavaBean aus dem Package it.rambow.jboss.workerbeans der Anwendung trägt den Namen ActionBean. Sie besitzt lediglich ein Attribut und ein dazugehöriges get- und set-Methodenpaar. Weitere Informationen die zur Bearbeitung der Anfrage nötig sind, werden aus den, im Session-Objekt befindlichen, Formulardaten ermittelt. Nach der Abarbeitung einer Anfrage speichert der Controller neue Daten in das Session-Objekt und leitet den Benutzer auf die angeforderte Seite weiter. Die neue Seite liest dann die Informationen aus dem Session-Objekt und stellt das Ergebnis dar. JSPs können durch die Angabe der benötigten JavaBeans im <jsp:useBean>-Tag direkt auf diese zugreifen. Die JavaBeans bekommen einen eindeutigen Namen zugewiesen und werden, falls sie nicht in der Session unter diesem Namen gespeichert sind, erzeugt. Häufig werden in der entwickelten Anwendung Mengen von Benutzern, Projekten oder News verwendet. Mittels useBean-Tag können auch diese Mengen benutzt werden. Das folgende Tag benutzt eine ArrayList, um die Benutzer der Anwendung verfügbar zu machen: <jsp:useBean id="allUsers" scope="session" class="java.util. ArrayList" />. Wenn das Objekt nicht in der Session liegt, wird der Konstruktor der ArrayList aufgerufen und eine leere ArrayList erzeugt. Eine weitere sehr nützliche Eigenschaft des useBean-Tags ist die, dass die Formularfelder einer Seite automatisch auf die get- und set-Methoden einer JavaBean abgebildet werden können. Mit dem Tag: <jsp:setProperty name="myAddressBean" property="*" /> werden alle Formulardaten der Seite in der JavaBean gespeichert. Dazu ruft der Servlet-Container zu jedem Formularfeld die dem Namen entsprechende set-Methode auf. In der Anwendung wurde dies eingesetzt, um Benutzereingaben zu validieren. Anwendung fand diese Möglichkeit z. B. bei der Eingabe der Adressdaten zur Registration eines neuen Benutzers. 122 5. Referenz-Anwendung Es werden jedoch nicht alle Aktionen des Benutzers durch den Controller bearbeitet. Eine Ansicht, die aufgerufen werden soll und deren Daten sich bereits in der Session befinden, kann direkt angesprochen werden. Ein Beispiel dafür ist z. B. die News-Detail-Ansicht. Diese Ansicht wird aufgerufen, nachdem die News bereits geladen wurden. Da in der Liste aller News auch alle für die Detail-Ansicht benötigten Daten vorhanden sind, ist keine Interaktion mit dem Controller notwendig. Dadurch lässt sich die Antwortzeit verringern und Ressourcen auf dem Application-Server sparen. 5.5.2. Web-Benutzer-Interface Das Benutzer-Interface ist bei etwas Erfahrung im Umgang mit dem World Wide Web einfach zu bedienen. Das Design orientiert sich an einem Karteikarten-System. Oberhalb der angezeigten Seite ist eine Reihe von „Karteikarten-Reitern“ zu sehen, die zur Navigation zwischen den einzelnen Ansichten eingesetzt werden. Abb. 5.7: Ansicht News Unterhalb der Navigationselemente sind die Daten der Anwendung und Formulare zur Dateneingabe angeordnet. Welche Ansicht aktiv ist, wird dadurch dargestellt, dass das aktive Navigationselement im Grau des Inhalts-Feldes dargestellt wird. 5. Referenz-Anwendung 123 5.5.3. Konfiguration der Anwendung Die Konfiguration der Web-Anwendung erfolgt in erster Linie über den Web-DeploymentDeskriptor. Hier werden die Einstellungen vorgenommen, wie z. B. die URL, unter der die Anwendung angesprochen werden kann, die Sicherheitsbestimmungen und der Name des Controllers, bzw. der Servlets. Für serverspezifische Einstellungen wird zusätzlich der jboss-web.xml-Deployment-Deskriptor benötigt. Der Deployment-Deskriptor Die wichtigsten Einstellungen der web.xml-Datei sollen im folgenden erläutert werden, eine vollständige Darstellung ist im Anhang auf Seite A.5 zu finden. In ihr werden zunächst ein oder mehrere Servlets registriert. Dazu wird im <servlet>Tag sowohl ein Name des Servlets vergeben, als auch die Klasse dieses Servlets festgelegt. Unterhalb des <servlet-mapping>-Tags kann nun festgelegt werden, unter welcher URL das Servlet aufgerufen wird. Dabei sind Platzhalter (Wildcards) möglich. Durch *.ctrl wird das Controller-Servlet angesprochen, sobald eine URL auf dem Suffix .ctrl endet. Das Tag <session-timeout> legt fest, nach welcher Zeit ein Nutzer bei Inaktivität automatisch ausgeloggt wird. Im Tag <security-constraint> wird festgelegt, welche URL zugangsbeschränkt ist. Zusätzlich kann eingestellt werden, welche HTTP-Methoden (z. B. get und post) auf das Controller-Servlet, welches unter dieser URL angesprochen wird, angewandt werden dürfen. Das Tag <auth-constraint> legt fest, welche Benutzerrollen für den Zugriff erforderlich sind. Im <transport-guarantee>-Tag kann die Sicherung der Übertragung konfiguriert werden. Die JBoss-Referenzanwendung arbeitet mit dem Wert CONFIDENTIAL, der höchste Sicherheit gewährleistet. Die Daten werden nur über HTTPS übertragen. Dadurch sind die Daten gegen ungewolltes Mitlesen und Ändern ausreichend geschützt. Durch <auth-method> kann festgelegt werden, auf welche Art die Benutzerdaten abgefragt werden sollen. Zur Auswahl stehen BASIC und DIGEST, diese fordern den Benutzer in einem Eingabe-Dialog-Fenster des Browsers auf die Benutzerkennung einzugeben. Der Unterschied zwischen BASIC und DIGEST besteht darin, das DIGEST diese Daten verschlüsselt überträgt. Durch MUTAL kann eine Athentifizierung über Zertifikat-Austausch vorgenommen werden. Mit FORM wird ein HTML-Formular benutzt, das im Design der 124 5. Referenz-Anwendung Anwendung eingebettet werden kann. Die Referenzanwendung benutzt die formular-basierte Authentifikation. Dabei ist zu beachten, dass der Name der Formular-Action und die Namen der Eingabefelder vorgeschrieben sind. Listing 5.1 zeigt ein solches Eingabe-Formular: Listing 5.1: Eingabe-Formular zur Benutzerauthentifikation 1 2 3 4 5 <form method="POST" action="j_security_check"> Name: <input type="text" name="j_username"> Password: <input type="password" name="j_password"> <input class="button" type="submit" name="senden" value="Login"> </form> Der Servlet-Container überprüft mit dieser Einstellung die Benutzereingaben in der konfigurierten Benutzerverwaltung (vgl. 4.5.1). 5.6. Administrator-Anwendung Zur Administration der Anwendung stehen zwei Frontends zur Verfügung. Eine Version ist als Web-Anwendung realisiert und fügt sich in das Design der Benutzer-Anwendung ein. Die folgende Abbildung zeigt die Oberfläche der Web-Administrator-Anwendung: Abb. 5.8: Administrator-Web-Anwendung Wenn sich ein Benutzer mit der Rolle Admin an der Web-Anwendung anmeldet, kann 5. Referenz-Anwendung 125 er sowohl die Benutzer- als auch die Administrator-Anwendung auswählen. Die Anwendungsfälle der Web-Administrator-Anwendung sind in Abbildung 5.2 dargestellt. Alternativ zum Web-Frontend besteht die Möglichkeit, einen Rich-Client als Frontend der Anwendung bereitzustellen. Die Administrator-Anwendung ist ein Prototyp, der zeigt, wie ein solches Frontend für den JBoss entwickelt werden kann. Die Möglichkeiten, die eine solche Adminstrator-Anwendung anbietet, sind in Abbildung 5.2 aufgeführt. Abb. 5.9: Administrator-Rich-Client 5.6.1. Architektur der Administrator-Anwendung Der Prototyp der Adminstrator-Anwendung wurde in Swing, einer häufig verwendeten Java-GUI-API, implementiert. Es gibt verschiedene Möglichkeiten, solche grafischen Oberflächen zu erstellen. Dazu zählen GUI-Editoren, die eine grafische Programmerstellung ermöglichen und Frameworks, die bestimmte Aufgaben bei der Erstellung der Oberfläche vereinfachen. Der Autor entschied sich, das JGoodies-Framework3 einzusetzen. Dieses Framework ermöglicht, auf einfache und schnelle Weise konsistente Oberflächen zu erstellen. Der LayoutManager von JGoodies kann wie eine HTML-Tabelle konfiguriert werden. Man initialisiert 3 http://www.jgoodies.com/ 126 5. Referenz-Anwendung das Layout durch die Angabe von Spalten und Zeilen und setzt dann die GUI-Elemente ein. Es ist auch möglich statt eines vordefinierten Layouts die Elemente dynamisch anzuordnen. Zusätzlich zu den normalen Maßeinheiten wie Pixel und Zentimeter stehen auch die „Dialogeinheiten“ zur Verfügung. Diese Dialogeinheiten passen sich der eingestellten Auflösung und Schriftgröße der Plattform an, auf der das Programm ausgeführt wird. Dadurch ist die Ausrichtung von GUI-Elementen einfach möglich. JGoodies bietet auch ein eigenes Look and Feel (LaF) an. So sehen die Benutzeroberflächen, die dieses Design verwenden, den Standardelementen der Zielplattform ähnlich, wodurch die Akzeptanz der Anwendung erhöht wird. Auf der JGoodies-Webseite werden zahlreiche Vorschläge für gutes Design von Java-Oberflächen gemacht, die durch die Verwendung von JGoodies sehr leicht umzusetzen sind. Wie bereits in 5.3.2 erwähnt, werden auch grafische Benutzeroberflächen nach dem MVCModell entwickelt. Auch der Prototyp benutzt dieses Entwurfsmuster. Dadurch ist eine einfache Weiterentwickelung möglich. Den GUI-Komponenten der Anwendung können Ereignisse zugeordnet werden, z. B. beim Klick auf einen Button. Diese Ereignisse werden vom Controller empfangen und verarbeitet. Wenn der Controller Daten des Modells ändert, wird danach notify aufgerufen. Daraufhin führen die betroffenen Views ihre update-Methode aus und aktualisieren so die Daten ihrer Ansicht. Die Aktualisierung erfolgt, indem die Daten aus dem Modell neu geladen werden. Das Modell der Administrator-Anwendung hält die Daten des serverseitigen Backends. Um nicht bei jeder Aktion des Benutzers die Daten mit dem Backend synchroniseren zu müssen, können diese zu Beginn geladen und auf Wunsch des Benutzers mit der eigentlichen Datenhaltung abgeglichen werden. Der „GUI-Controller“ beinhaltet die Logik, um auf einer Kopie der Daten des Backends zu arbeiten. Bei Anwendungen, deren Daten ständig aktualisiert werden müssen, ist auch ein ständiger oder zyklischer Abgleich der Daten möglich. 5.6.2. Verbindung mit JBoss Um den GUI-Client mit der serverseitigen Logik zu verbinden, muss eine Netzwerkverbindung aufgebaut werden. Die Kommunikation mit dem Backend erfolgt dann über RMIIIOP. 5. Referenz-Anwendung 127 Für die Lokalisierung der Objekte des Servers, benötigt der Client die Angabe des NamensDienstes. Dessen Verbindungsdetails werden in den InitialContext des Clients geschrieben: 1 2 3 4 5 Hashtable env = new Hashtable(); env.put("java.naming.factory.initial", "org.jnp.interfaces. NamingContextFactory"); env.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp .interfaces"); env.put("java.naming.provider.url", "localhost"); //Server URL ctx = new InitialContext(env); Nach der Bereitstellung dieser Informationen kann auf die Session-Fassade der J2EE-Anwendung analog zum Servlet-Controller zugegriffen werden (vgl. 3.4) So wird die Logik der Datenverarbeitung weiterhin serverseitig bereitgestellt, wodurch ist der Austausch des Frontends leichter möglich ist. Der Prototyp der Administrator-Anwendung hat bisher nicht die benötigte Funktionalität, um alle Anwendungsfälle des Administrators abzudecken. So wurde nur der lesende Zugriff auf den Server implementiert. Um Daten auch schreiben zu können, stehen zur Erweiterung die benötigten Methoden in der Session-Fassade bereit. 5.7. WAP-Frontend Bei den Vorüberlegungen zur Realisierung der Referenzimplementierung gab es die Idee, einen kleinen Teil der Anwendung auch mobil zur Verfügung zu stellen. Aufgrund der sehr beschränkten Mittel von WML4 , der Ergonomie und Größe von Mobiltelefon-Displays, wurde jedoch festgestellt, dass ein WAP-Client nicht in der Lage ist, die benötigte Menge an Daten anzuzeigen. Daher wurde die Idee verworfen. Die fortschreitende Technik in Mobiltelefonen ermöglicht es jedoch auch, HTML-Seiten anzuzeigen. Die Displays werden hochauflösender, so dass die Anwendung heute schon über HTML fähige mobile Clients besser zu betrachten ist, als es mit einem neu geschaffenen WAP-Frontend möglich wäre. 4 Wireless Markup Language 128 5. Referenz-Anwendung Durch die konsequente Umsetzung des MVC-Entwurfsmusters ist es bei Bedarf möglich, ein WAP-Frontend für die Anwendung zu entwickeln. 6. Zusammenfassung und Ausblick In diesem Kapitel sollen die Ergebnisse der Arbeit vorgestellt werden. Dabei wird eine Prognose für J2EE-Application-Server abgegeben und auf die Einsatzmöglichkeiten der entwickelten Anwendung eingegangen. 6.1. Zukunftsprognose Durch die Globalisierung und Entwicklung hin zu weltumspannenden Informationssystemen ist der Bedarf an verteilten Anwendungen enorm. Schon heute werden eine Vielzahl von Programmen online zur Verfügung gestellt. Dazu zählen Anwendungen wie OnlineBanking, Shopping-Portale, Auktionshäuser bis hin zur Partnervermittlung. Die Zahl der Menschen die sich mit dem Internet beschäftigen, wächst kontinuierlich. Durch den Einsatz der J2EE-Plattform werden bei der Entwicklung solcher großen verteilten Systeme eine Vielzahl von Problemen beherrschbar. Neuerungen, die in J2EE 1.4 einfließen, wie die bessere Integration von WebServices helfen eine noch breitere Marktdurchdringung zu erreichen. Konkurenzsysteme wie die .NET-Plattform geben weitere Impulse für die Weiterentwicklung der verteilten Anwendungen, halten jedoch noch geringere Marktanteile. Der Markt der J2EE-Application-Server unterliegt einem kontinuierlichen Wachstum. Die Zahl der Anbieter von kommerziellen J2EE-Application-Server nimmt mit jeder neuen J2EE-Version zu [SM04b]. Und J2EE ist ein weltweit eingesetzter Standard für verteilte unternehmensweite Systeme. Die Vorteile der J2EE-Plattform werden von großen Unternehmen genutzt, um mit geringeren Administrationsaufwand maximale Verfügbarkeit zu erreichen. Anfangs waren J2EE-Systeme nur auf teuren Application-Servern wie BEA WebLogic oder auch IBM WebSphere verfügbar. Doch die Verbreitung der Sprache Java und der Kostendruck auf Unternehmen aller Art bieten die Grundlage, um den kostenlosen Konkurenzprodukten neue Märkte zu erschlies- 130 6. Zusammenfassung und Ausblick sen. Der JBoss ist, wenn man die Häufigkeit seiner Downloads betrachtet, der beliebteste kostenfreie J2EE-Application-Server. Er implementiert den kompletten Umfang der J2EESpezifikation und stellt eigene Erweiterungen zur Verfügung (AOP, Farming, Hot Deployment, etc.). Der Bedarf an freien J2EE-Servern scheint jedoch noch nicht abgedeckt zu sein. So entwickelt die Apache Group derzeit einen neuen J2EE-Server unter dem Namen „Geronimo“1 . In der Vergangenheit haben die Projekte der Apache Group sich als sehr beliebt erwiesen und zeugen von hoher Qualität. Daher sollte das Projekt, welches bisher noch nicht als Release freigegeben wurde, weiter beobachtet werden. Sun hat der Apache Group, die als Partner für Sun die Servlet-Referenzimplementierung Tomcat erstellt, eine kostenlose J2EE-Zertifizierung in Aussicht gestellt. Im Open-Source-Bereich wird Geronimo wohl der stärkste Konkurrent des JBoss werden. Allgemein kann man aber an diesen Entwicklungen ablesen, dass die Open-Source-Server generell gegen die kommerziellen Konkurrenten aufholen und Marktanteile erobern. Auf der Hauskonferenz der Orientation in Objects GmbH2 in Mannheim konnte der Autor in Erfahrung bringen, dass auch große Unternehmen wie John Deere3 und Daimler Chrysler4 in Deutschland JBoss, zumindest in einigen Abteilungen, einsetzen. Kostenlose, professionell entwickelte Software trägt entscheidend zur Verbreitung einer Technologie bei. Diesen Vorgang kann man z. B. am enormen Wachstum des Internets erkennen, dessen beliebter Web-Server Apache ein Open-Source Projekt ist. Derzeit ist das JBoss-Projekt in einer marktbeherrschenden Position im Open-Source J2EEBereich. Viele neue Projekte entstehen auf Basis des JBoss und die Liste der Unternehmen, die JBoss erfolgreich einsetzen, sind auf der JBoss-Webseite zu finden5 . Darunter sind große Unternehmen wie Bosch, Siemens oder auch Advanced Micro Devices. Der immer größer werdende Bedarf zusammen mit der heutigen Verbreitung des JBoss führen zu einer positiven Prognose für den Server. Die Verbreitung des JBoss wird auch durch die stets größer werdende Zahl an Entwicklern vorrangetrieben, die JBoss als freies System in kleineren Projekten einsetzen. Dies verbreitert die Wissensbasis, auf die Unternehmen zurückgreifen können. Zusätzlich werden durch die JBoss Group professionelle Support1 http://incubator.apache.org/projects/geronimo.html http://www.oio.de 3 http://www.deere.com 4 http://www.daimlerchrysler.com 5 http://www.jboss.com/services/references/index 2 6. Zusammenfassung und Ausblick 131 Verträge und Schulungen angeboten, welche helfen, Projekte auf der kostenlosen Plattform zu entwickeln. Dieser Ansatz unterstützt die Zunkunftssicherheit des JBoss, die Unternehmen benötigen, um langfristige Strategie-Entscheidungen zu treffen. Das gewonnene Kapital durch die Unternehmensfelder der JBoss Group hilft bei der Expansion des Unternehmens und verspricht, langfristig auf Unterstützung und Weiterentwicklung des JBoss setzen zu können. 6.2. Einsatzmöglichkeiten der entwickelten Anwendung Die entwickelte Anwendung stellt, wie in Kapitel 5 beschrieben, ein Projekt-ManagementProgramm dar. Die Einsatzmöglichkeiten liegen damit im Bereich von kleinen Unternehmen oder Projektgruppen. Die Anwender können sich mit Hilfe eines solchen Systems leicht, auch weltweit, mit hoher Sicherheit austauschen und sind dadurch unabhängig von z. B. E-Mail-Systemen. Die Produktivität dieser Kommunikationart wird jedoch zunehmend durch Spam (massenweise versendete unerwünschte E-Mails) und durch sie verbreitete Viren beeinträchtigt. Durch ein zentral verfügbares Nachrichtensystem können Projektgruppen unabhängig von dieser Technik arbeiten. Durch den einfachen Aufbau der Anwendung ist es sehr leicht möglich, diese auf die Bedürfnisse einer Projektgruppe anzupassen und zu erweitern. Mit dem Einsatz des Systems sind keine Kosten verbunden. Sowohl die Anwendung an sich, die im Quellcode zur Verfügung steht, als auch die Plattform auf der sie lauffähig ist, der JBoss Application Server, sind kostenlos einsetzbar. 6.2.1. Notwendige Erweiterungen für einen produktiven Einsatz Die Anwendung ist nicht als produktives System entwickelt worden und muss auf Wunsch in diesem Fall erweitert werden. Die Anwendung stellt vielmehr einen vertikalen Prototyp dar, der Programmiertechniken aufzeigt. Die gesamte Funktionalität die von einem Projekt-Managementsystem erwartet wird, deckt die Anwendung derzeit nicht ab. Um diese Anwendung für den Einsatz aufzubereiten, empfiehlt sich der Einsatz eines Frameworks wie Air für die Umsetzung des MVC-Web-Modells. Das Backend der Anwendung funktioniert stabil und kann in dieser Form bestehen. Um zusätzliche Belange an die Anwendung abzudecken, müssen jedoch Erweiterungen spezifisch 132 6. Zusammenfassung und Ausblick für den Einsatz im jeweiligen Projekt-Team vorgenommen werden. Die fertige Struktur des Backends erleichtert diese Erweiterungen und ermöglicht ein einfaches Nachvollziehen von Abläufen innerhalb der Anwendung. Der Autor der Anwendung hat, um sich eingehender in die Materie einzuarbeiten (manuelle Erstellung der Deployment-Deskriptoren und Interfaces), auf die Vorzüge von XDoclet verzichtet. In einem Produktivsystem ist der Einsatz von XDoclet oder anderen generativen Ansätzen notwendig, um auf einfache Weise konstistente Metatdaten für die Anwendung bereitzustellen. Zusätzlich ist es erforderlich, die Administrations-Anwendung, entweder als Web- oder Swing-Frontend, fertigzustellen. Da die gesamte Anwendung auch leicht von grafischen Benutzeroberflächen aus ansprechbar ist, besteht auch die Möglichkeit, die gesamte Anwendung auf diese Art bereitzustellen. Eine Einbindung z. B. in Eclipse als Plugin wäre denkbar und würde sich damit gut in die Arbeit Software-Entwicklern integrieren. 6.2.2. Die Anwendung als Beispiel zur Erstellung von J2EE Applikationen Das eigentliche Ziel bei der Erstellung der Anwendung bestand darin, eine Beispielanwendung bereitzustellen, die es ermöglicht, mit Hilfe dieser produktive Systeme für J2EEServer im Allgemeinen und JBoss im Speziellen zu erstellen. Um ein Studienobjekt für Entwickler bereitzustellen, benötigen diese vor allem komplexe Beispiele, die leicht nachvollziehbar sind. Durch den zur Verfügung stehenden Quellcode, die Erläuterungen und Einführungen in die Programmierung mit J2EE und JBoss innerhalb dieser Diplomarbeit wird dieses Ziel erreicht. Durch die vorliegende Diplomarbeit hofft der Autor auch, die Verbreitung des JBoss als kostenfreies J2EE-System zu begünstigen. Die Anwendung, die während dieser Diplomarbeit entstand, wird unter einer freien Lizenz im Quellcode über die Webseite des Autors6 angeboten und weiterentwickelt werden. 6 http://rambow.it 6. Zusammenfassung und Ausblick 133 6.3. Fazit Das in dieser Diplomarbeit gesetzte Ziel sowohl eine Evaluation des JBoss durchzuführen als auch eine J2EE-Implementierung bereitzustellen, die moderne Entwurfsmuster berücksichtigt, ist erreicht worden. Der JBoss hat dabei seine Stabilität unter Beweis stellen können und gute Unterstützung bei der Entwicklung zur Verfügung gestellt. Die Anwendung hat wichtige Entwurfsmuster implementiert und ist damit ein gutes Studienobjekt. Sie zeigt sowohl den Aufbau von J2EE-Applikationen als auch die Implementierung der wichtigsten Entwurfsmuster auf einfach nachvollziehbare Weise. Der Einsatz des JBoss sowohl für Studienzwecke als auch für Produktivsysteme ist nach Ansicht des Autors zu empfehlen. Dabei hilft der JBoss, ohne Verzicht auf Funktionalität oder Komfort, Kosten einzusparen. Die Bereitstellung des JBoss im Quellcode unterstützt dabei auch die Entwickler von Anwendungssystemen, da Sicherheitslücken und Fehler so vollständig entdeckt und behoben werden können. Die steigende Zahl der JBoss-Anwender erhöht weiterhin die Zuverlässigkeit, da sich ihr Wissen über den Server weiter vergrößert und durch Newsgroups allen Anwendern zur Verfügung steht. A. Anhang A.1. Servlet und JavaServer Pages Servlets und JSP-Seiten sind Bestandteile der J2EE-Spezifikation. Sie ermöglichen die Erstellung von Web-Anwendungen mit dynamisch generierten Web-Seiten. Um JSPs und Servlets auszuführen wird ein Web-Container wie Tomcat benötigt, welcher deren Ablaufumgebung bereitstellt (vgl. 4.4). A.1.1. Servlets Als Web-Technologie werden Servlets für gewöhnlich über HTTP angesprochen und verarbeiten die Methoden des Protokolls. Sie sind von der Klasse javax.servlet.http. HttpServlet abgeleitet und überschreiben deren Methoden. Die wichtigsten Methoden von HTTP sind POST und GET. Die doGet()-Methode verarbeitet Anfragen, deren Parameter aus der URL gelesen werden können. Die doPost()Methode verarbeitet POST-Anfragen. Diese werden häufig beim Versand von HTML-Formularen eingesetzt. Als Parameter der Methoden werden die Objekte HttpServletRequest und HttpServletResponse übergeben. Diese Objekte kapseln Daten und stellen Methoden bereit um die Daten zu verarbeiten. Das Response-Objekt bietet die Möglichkeit Daten an den aufrufenden Client zu senden. Dazu wird das PrintWriter-Objekt des HttpServletResponse benutzt. Dieser Writer kann eingesetzt werden um HTML-Seiten oder HTTP-Status-Codes an den Client zu schicken. Servlets eignen sich als Java-Klassen sehr gut, um die serverseitige Logik einer Web- oder HTTP-Anwendung bereitzustellen. Daher werden oftmals als Controller des MVC-Web- 136 A. Anhang Modells eingesetzt (vgl. 5.3.2). Das folgende Listing stellt ein einfaches Servlet dar. Listing A.1: Beispiel eines einfachen Servlets it.rambow.jboss; java.io.*; 3 import javax.servlet.ServletException; 4 import javax.servlet.http.*; 1 package 2 import 5 class SimpleServlet extends HttpServlet{ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 8 response.setContentType("text/html"); 9 PrintWriter out = response.getWriter(); 10 //HTML-Ausgabe 11 out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">"); 12 out.write("<HTML><HEAD><TITLE>Hello</TITLE></HEAD>"); 13 out.write("<BODY><H1>Hello World!</H1></BODY></HTML>"); 14 out.close(); 15 } 16 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 17 } 18 } 6 public 7 A.1.2. JavaServer Pages JavaServer Pages stellen eine Erweiterung der Servlets dar. Sie können durch ihren deklarativen Ansatz besser zur Gestaltung von dynamischen Webseiten eingesetzt werden. Dadurch ist es möglich eine bessere Trennung von Logik und Design bereitzustellen. JavaServer Pages können HTML- und JSP-Syntax-Elemente beinhalten und werden bei ihrem ersten Aufruf in Servlets übersetzt. Diese dynamisch generierten Servlets werden vom Servlet-Container kompiliert. Die folgende Tabelle stellt die JSP-Syntax-Elemente dar. Zusätzlich sind alle HTML-Elemente verfügbar. A. Anhang 137 Tabelle A.1.: JSP-Syntax-Elemente Syntax-Element Erklärung <%@ page attrib="val"%> Direktiven stellen globale Informationen zur <%@ include attrib="val"%> Verfügung. Als Direktiven stehen die Wer- <%@ taglib attrib="val"%> te page, include und taglib zur Verfügung. Page wird benutzt um festzulegen ob eine JSP an einer Session teilnehmen soll und welche Imports von Java-Klassen benötigt werden. Include gibt an ob eine Datei (JSP oder HTML) eingefügt werden soll, taglib gibt die Tag-Bibliothek an die benutzt wird. <jsp:useBean> Diese JSP-Elemente werden als Aktionen <jsp:setProperty> bezeichnet. Mittels useBean können Java- <jsp:getProperty> Beans eingebunden werden. Diese können <jsp:param> dann im Session- oder Request-Objekt der <jsp:include> Seite gespeichert werden. Mit den Aktionen <jsp:forward> get- und setProperty können die Get- <jsp:plugin> ter und Setter der eingebundenen JavaBeans benutzt werden. Mit param können zu den Aktionen Standard-Werte gesetzt werden. Include bindet den Quelltext einer Seite ein (z. B. JSP) und forward leitet das Anfrage-Objekt an eine andere Seite weiter (JSP, Servlet). <%! int right = 42; %> Diese Deklaration fungiert als Klassenvariable des aus der JSP generierten Servlets. <% %> Durch diese Tags wird Java-Code eingebunden. Dieses Element bezeichnet man als Scriptlet 138 A. Anhang Ein Einfaches Beispiel soll verdeutlichen, wie JSPs durch das Einbinden von Java-Code dynamische Webseiten generieren können: Listing A.2: Beispiel einer einfachen JSP <%@ 1 page errorPage="../errorpage.jsp" %> page import="java.util.*" %> <%! int right = 42; %> 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> 4 <HTML><HEAD><TITLE>Simple JSP</TITLE></HEAD> 5 <BODY> 6 <jsp:useBean id="myActionBean" scope="session" class="it.rambow.jboss.workerbeans. 7 ActionBean"/> <jsp:useBean id="myUserBean" scope="session" class="it.rambow.jboss.user.UserDTO"/ 8 > Your right answer Mr. <%=myUserBean.getName()%> should be <%=right%><br> 9 10 <div align="center"><%out.print(new java.util.Date());%></div> 11 </BODY> 12 </HTML> <%@ 2 Diese JSP erzeugt einen Text, der den Namen des Benutzers enthält. Der Name ist in der Session im Objekt myUserBean gespeichert. Am Ende der Datei wird das aktuelle Datum ausgegeben. A.2. Deployment Das folgende Listing zeigt die Konsolen-Ausgaben beim Deployment-Vorgang einer Anwendung auf dem JBoss Application Server: Listing A.3: Konsolenausgabe Deployment 1 15:22:34,296 INFO [MainDeployer] Starting deployment of package:file:/[...]/ JBossSec.jar 2 15:22:34,312 INFO [EARDeployer] Init J2EE application:... 3 15:22:37,273 INFO [EjbModule] Deploying MyTestSessionBean 4 15:22:37,687 INFO [JaasSecurityManagerService] Created securityMgr=... 5 15:22:37,690 INFO [JaasSecurityManagerService] setCachePolicy, c=... 6 15:22:37,691 INFO [JaasSecurityManagerService] Added myJBossSec... 7 15:22:38,565 INFO [StatelessSessionInstancePool] Started jboss.j2ee:jndiName= MyTestSessionBean,plugin=pool,service=EJB 8 15:22:38,567 INFO [StatelessSessionContainer] Started jboss.j2ee:jndiName= MyTestSessionBean,service=EJB 9 15:22:38,568 INFO [EjbModule] Started jboss.j2ee:module=JBossSec.jar,service= EjbModule A. Anhang 139 10 15:22:38,569 INFO [EJBDeployer] Deployed: file:/[...]/JBossSec.jar INFO [EmbeddedTomcatService] deploy, ctxPath=/JBossSec, warUrl=file :[...]/JBossSec.ear-contents/JBossSec.war/ 12 15:22:40,083 INFO [Engine] SingleSignOnContextConfig[/JBossSec]: Added certificates -> request attribute Valve 13 15:22:40,129 INFO [Engine] SingleSignOnContextConfig[/JBossSec]: Configured an authenticator for method FORM 14 15:22:40,290 INFO [Engine] StandardWrapper[/JBossSec:default]: Loading container servlet default 15 15:22:40,945 INFO [Engine] StandardWrapper[/JBossSec:invoker]: Loading container servlet invoker 16 15:22:42,419 INFO [EARDeployer] Started J2EE application: file:/[...]/JBossSec. ear 17 15:22:42,421 INFO [MainDeployer] Deployed package: file:/[...]/JBossSec.ear 11 15:22:38,918 Das folgende Listing zeigt die Konsolen-Ausgaben beim Undeployment-Vorgang einer Anwendung auf dem JBoss Application Server. Listing A.4: Konsolenausgabe Undeployment 15:24:27,680 INFO [EmbeddedTomcatService] undeploy, ctxPath=/JBossSec, warUrl= file:/[...]/JBossSec.war/ 2 15:24:27,699 INFO [Engine] StandardHost[localhost]: Removing web application at context path /JBossSec 3 15:24:27,704 INFO [STDOUT] Destroy 4 15:24:27,713 INFO [EjbModule] Stopping jboss.j2ee:module=JBossSec.jar,service= EjbModule 5 15:24:27,715 INFO [StatelessSessionContainer] Stopping jboss.j2ee:jndiName= MyTestSessionBean,service=EJB 6 15:24:27,716 INFO [StatelessSessionInstancePool] Stopping jboss.j2ee:jndiName= MyTestSessionBean,plugin=pool,service=EJB 7 15:24:27,719 INFO [EARDeployer] Undeploying J2EE application, destroy step: file :/[...]/JBossSec.ear 8 15:24:27,782 INFO [EJBModule] destroy(), remove EJB-Module: jboss.management. local:J2EEApplication=JBossSec.ear,J2EEServer=Local,j2eeType=EJBModule,name= JBossSec.jar 1 140 A. Anhang A.3. JBoss Management Konsole Folgende Abbildung zeigt die Web-Management-Konsolde des JBoss. Die Erste Ansicht zeigt dabei die System-Parameter und eine Baumansicht der installierten Komponenten. Abb. A.1: Systemübersicht der Web-Management-Konsole des JBoss Die folgende Abbildung zeigt Details über eine Session Bean an. Diese muss, um inspiziert werden zu können, ein Remote-Interface anbieten. Abb. A.2: Analyse einer Session-Bean der Web-Management-Konsole des JBoss A. Anhang 141 A.4. Datenmodell der Referenzanwendung In Kapitel 5.4.1 wurde bereits eine verkürzte Darstellung des Datenmodells der Anwendung vorgestellt. Die folgende Grafik zeigt das vollständige Datenmodell, einschließlich Relationen und Kardinalitäten. MESSAGETYPEENTITY NEWSENTITY 1 ID MSGTYPE gehört zu hat N ID DATE N MSG wu rd sch e r ge eib sc t n hr e ie w s be n vo n COMPONENT USER MESSAGETYPE USERENTITY ID ACTIVE NAME VORNAME TITLE PASSWORD ROLE ROLEGROUP 1 1 r fü en ich tlich l t r r wo w o nt nt ra ra ve Ve t ha COMPONENTSENTITY ID COMPONENTNAME N DEADLINE STATUS PROJECT COMPONENTCHIEF STATUS TELEFONENTITY TELNR USER 1 1 N STATUSENTITY ge hat 1 hö rt z ID u N ID hat rt zu gehö 1 PROJECTENTITY 1 hat ID u rt z PROJECTNAME gehö N ADDRESSENTITY hat gehö rt zu N 1 ge ha hö t rt z u t zu ha ört h ge N ID STRASSE NR PLZ STADT USER EMAILENTITY ID EMAIL USER N SKILLENTITY SKILLGROUPENTITY 1 hat N SKILLGROUPID SKILLGROUPNAME gehört zu SKILLTYPEENTITY ID SKILLTYPE SKILLGROUP SKILLID KNOWLEDGEVALUE 1 hat N EVALUATIONMSG gehört zu SKILLUSER SKILLTYPE Abb. A.3: Datenmodell der Anwendung modelliert in UML, mit Kardinalitäten 142 A. Anhang A.5. Konfiguration der Web-Anwendung Zur Konfiguration der Web-Anwendung wird der Deployment-Deskriptor web.xml eingesetzt. Das Listing A.5 zeigt die web.xml-Datei der Referenzanwendung. Darin sind unter anderem die Sicherheitseinstellungen (<security-constraint>) aufgeführt, die es erlauben, den Zugang zur Anwendung über bestimmten URLs zu beschränken. Weiterhin ist die Konfiguration des Login-Formulars und die Registrierung der Servlets zum URLPattern *.ctrl nachvollziehbar. Listing A.5: Darstellung des Deployment"=Deskriptor web.xml der Referenzanwendung 1 <?xml version="1.0" encoding="ISO-8859-1"?> web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" 3 "http://java.sun.com/j2ee/dtds/ web-app_2_2.dtd"> 4 <web-app> 5 <display-name>JBoss refrence application</display-name> 6 <description>JBoss reference application</description> 7 <!--Controller for registration--> 8 <servlet> 9 <servlet-name>RegistrationController</servlet-name> 10 <servlet-class>it.rambow.jboss.RegistrationController</servletclass> 11 </servlet> 12 <!--Controller for application--> 13 <servlet> 14 <servlet-name>ControllerServlet</servlet-name> 15 <servlet-class>it.rambow.jboss.ControllerServlet</servlet-class> 16 </servlet> 17 <!--Controller for application secure access--> 18 <servlet-mapping> 19 <servlet-name>ControllerServlet</servlet-name> 20 <url-pattern>*.ctrl</url-pattern> 21 </servlet-mapping> 22 <!--Controller for Registration, unsecure access--> 23 <servlet-mapping> 24 <servlet-name>RegistrationController</servlet-name> 25 <url-pattern>/registrationcontroller</url-pattern> 26 </servlet-mapping> 27 <!-- Session Configuration --> 28 <session-config> 29 <session-timeout>15</session-timeout> 30 </session-config> 31 <security-constraint> 32 <web-resource-collection> 2 <!DOCTYPE A. Anhang 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 143 <web-resource-name> ControllerServletForApplication </webresource-name> <!--which path is restricted--> <url-pattern>/admin/*</url-pattern> <!--HTTP-Methods that are allowed--> <http-method>GET</http-method> <http-method>POST</http-method> <http-method>PUT</http-method> <http-method>DELETE</http-method> <http-method>HEAD</http-method> <http-method>OPTIONS</http-method> <http-method>TRACE</http-method> </web-resource-collection> <auth-constraint> <!--which roles have access--> <role-name>Admin</role-name> </auth-constraint> <!--using HTTPS--> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> <security-constraint> <web-resource-collection> <web-resource-name> ControllerServletForApplication </webresource-name> <!--which path is restricted--> <url-pattern>/secured/*</url-pattern> <url-pattern>*.ctrl</url-pattern> <!--HTTP-Methods that are allowed--> <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth-constraint> <!--which roles have access--> <role-name>Admin</role-name> <role-name>User</role-name> </auth-constraint> <!--using HTTPS--> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> <!--Form or Basic authentification--> <login-config> <auth-method>FORM</auth-method> 144 A. Anhang <form-login-config> <form-login-page>/login.jsp</form-login-page> 79 <form-error-page>/https-login-cfgerror.html</form-errorpage> 80 </form-login-config> 81 </login-config> 82 <security-role> 83 <role-name>Admin</role-name> 84 </security-role> 85 <security-role> 86 <role-name>User</role-name> 87 </security-role> 88 </web-app> 77 78 A.6. Inhalt der CD Diese Diplomarbeit wird durch die mitgelieferte CD vervollständigt, auf welcher die entwickelte Anwendung im Quellcode vorliegt und in einem für die Anwendung konfigurierten JBoss installiert ist. Der Installationsvorgang des JBoss und die Inbetriebnahme der Anwendung sind in der index.html-Datei im Grundverzeichnis der CD beschrieben, diese Datei dient zur Navigation auf der CD. Glossar ACID AOP API ASP AWT BCEL BMP CIF CLR CLS CMP CMR COBOL COM CORBA CSS CVS CWM DBMS DCOM DDL DLL DML DTD DTO EAR EB ECMA EIS EJB EJB-QL Atromicity Consistency Isolation Durability Aspekt Orientierte Programmierung Application Programming Interface Active Server Pages Abstract Windowing Toolkit Bytecode Engineering Libary Bean Managed Persistence Cache Invalidation Framework Common Language Runtime Common Language Specification Container Managed Persistence Container Managed Relations Common Business Oriented Language Component Object Model Common Object Request Broker Architecture Cascading Style Sheets Concurrent Versioning System Common Warehouse Meta-Model Datenbank Management System Distributed Component Object Model Data Definition Language Dynamic Link Library Data Manipulation Language Document Type Definition Data Transfer Object Enterprise Archive Entity Bean European Computer Manufacturers Association Enterprise Information System Enterprise JavaBeans Enterprise JavaBeans-Query Language 146 FIFO GUI HA-JNDI HTML HTTP IDE IDS IIOP IIS ISO J2EE JAAS JAR JAXM JAXP JAXR JCA JDBC JDK JDO JMS JMX JNDI JSP JSR JTA JVM LGPL MDA MDB MOF MOM MSIL OLE OMG RAR RDBMS RMI RPC SAAJ SAR Glossar first-in first-out Graphical User Interface High Availability Java Naming and Directory Interface Hypertext Markup Language HyperText Transfer Protocol Integrated Development Environment Intrusion Detection System Internet Inter-ORB Protocol Internet Information Server International Organization for Standardization Java 2 Platform, Enterprise Edition Java Authentication and Authorization Service Java Archive Java API for XML Messaging Java API for XML Processing Java API for XML Registries Java Connector API Java DataBase Connectivity(JDBC) Data Access API Java Development Kit Java Data Objects Java Message Service Java Management Extension Java Naming and Directory Interface JavaServer Pages Java Specification Request Java Transaction API Java Virtual Maschine lesser gnu public license Model Driven Architecture Message-Driven Bean Meta-Object Facility Message oriented Middleware Microsoft Intermediate Language Object Linking and Embedding Object Management Group Resource Archive Relationales Datenbank Management System Remote Method Invocation Remote Procedure Call SOAP with Attachments API for Java Service Archive Glossar SB SDL SNMP SOAP SSL SVG UDDI UDP UML URL UTF-8 UUID VDL VPN W3C WAP WAR WebDAV WML WSDL WWW XML XSLT 147 Session Bean Storage Definition Language Simple Network Management Protocol Simple Object Access Protocol Secure Socket Layer Scalable Vector Graphics Universal Description, Discovery and Integration User Datagram Protocol Unified Modeling Language Uniform Resource Locator Unicode Transformation Format, 8-bit kodiert Universal Unique IDentifier View Definition Language Virtual Private Network World Wide Web Consortium Wireless Application Protocol Web Archive Web Distributed Authoring and Versioning Wireless Markup Language WebService Definition Language World Wide Web Extensible Markup Language eXtensible Stylesheet Language Transformation Abbildungsverzeichnis 2.1. Java und J2EE Quelle: [SM97] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 2.2. Beispiel einer Mehrschicht-Architektur . . . . . . . . . . . . . . . . . . . . . . . . 14 2.3. Ausschnitt der Anwendungsfälle der Referenz Anwendung . . . . . . . . . . . . . . 27 2.4. UML 2 - Diagramm (Komponenten und Deployment) . . . . . . . . . . . . . . . . . 28 3.1. J2EE-Architektur (Abkürzungen siehe Glossar Seite:145) . . . . . . . . . . . . . . . 33 3.2. Client-Sicht auf EJBs nach [SDD02] . . . . . . . . . . . . . . . . . . . . . . . . . . 34 3.3. RMI-Kommunikation nach [BG02] . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 3.4. Lebenzyklus: Entity Bean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 3.5. Mapping von Entity Beans auf eine relationale Datenbank . . . . . . . . . . . . . . 41 3.6. Lebenszyklus: stateless Session Bean . . . . . . . . . . . . . . . . . . . . . . . . . 49 3.7. Lebenszyklus: stateful Session Bean . . . . . . . . . . . . . . . . . . . . . . . . . . 51 3.8. Die Modi des JMS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 3.9. Lebenszyklus: Message-Driven Bean . . . . . . . . . . . . . . . . . . . . . . . . . . 54 4.1. JMX-Architektur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 4.2. JBoss-Kern (JMX-Bus) und einige angeschlossene Komponenten . . . . . . . . . . . 64 4.3. Invoker und nachgeschaltete funktionale Aspekte . . . . . . . . . . . . . . . . . . . 65 4.4. Deployment-Komponenten des JBoss . . . . . . . . . . . . . . . . . . . . . . . . . 66 4.5. derzeitiges Partitions-Konzept und zukünftiges Sub-Partitions-Konzept . . . . . . . . 73 4.6. dynamischer Proxy mit Liste verfügbar Knoten . . . . . . . . . . . . . . . . . . . . 74 4.7. Bereitstellung von Clustering für nicht RMI-Clients . . . . . . . . . . . . . . . . . . 75 4.8. Ablauf einer clusterweiten JNDI-Namenssuche . . . . . . . . . . . . . . . . . . . . 76 5.1. Anwendungsfälle des Benutzers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 5.2. Anwendungsfälle des Administrators . . . . . . . . . . . . . . . . . . . . . . . . . . 109 5.3. MVC 2 Web-Architektur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 5.4. Vergleich des Clientszugriffs mit und ohne Verwendung einer Session-Fassade . . . . 114 150 5.5. 5.6. 5.7. 5.8. 5.9. Abbildungsverzeichnis Datenmodell: Verkürzte Darstellung . . Ablauf eines Aufrufes an den Controller Ansicht News . . . . . . . . . . . . . . Administrator-Web-Anwendung . . . . Administrator-Rich-Client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 120 122 124 125 A.1. Systemübersicht der Web-Management-Konsole des JBoss . . . . . . . . . . . . . . 140 A.2. Analyse einer Session-Bean der Web-Management-Konsole des JBoss . . . . . . . . 140 A.3. Datenmodell der Anwendung modelliert in UML, mit Kardinalitäten . . . . . . . . . 141 Tabellenverzeichnis 2.1. Vergleich J2EE und .NET-Plattform . . . . . . . . . . . . . . . . . . . . . . . . . . 23 3.1. Interfaces bei EnityBeans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 3.2. Transaktionsattribute der EJB-Typen (CMT) (nach [SDD02]) . . . . . . . . . . . . . 59 4.1. Übersicht Applikationserver (nach [The03] und Hersteller-Informationen) . . . . . . 105 A.1. JSP-Syntax-Elemente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 Listings 2.1. jboss-web.xml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1. Beispiel eines EJB-QL Statements (ejb-jar.xml) . . . . . . . . . . . . . . . . . . . 3.2. Definition von Container-managed-Relations . . . . . . . . . . . . . . . . . . . . 3.3. Clientaufruf an einer Local-Entity Bean . . . . . . . . . . . . . . . . . . . . . . . 3.4. Clientaufruf an einer Remote-Session Bean . . . . . . . . . . . . . . . . . . . . . 4.1. Beispiel für Applikations-zentriertes Classloading . . . . . . . . . . . . . . . . . . 4.2. Beispiel einer Erzeugung eines InitialContext für HA-JNDI (Server) . . . . . . . . 4.3. Beispiel einer Erzeugung eines InitialContext für HA-JNDI (Client) . . . . . . . . 4.4. Einstellung des Namens einer Cache Invalidation Group . . . . . . . . . . . . . . 4.5. Beispiel-Konfiguration JAAS mit Datenbank-Login-Modul (login-config.xml) 4.6. Tabellen für JAAS mit Datenbank-Login-Modul (login-config.xml) . . . . . . 4.7. Entfernen der Sicherheitsüberprüfung . . . . . . . . . . . . . . . . . . . . . . . . 4.8. Beispiel-Konfiguration SSL für EJBs . . . . . . . . . . . . . . . . . . . . . . . . . 4.9. Beispiel-Konfiguration SSL für EJBs . . . . . . . . . . . . . . . . . . . . . . . . . 4.10. Beispiel für die Abbildung einer Entity Bean auf eine vorhandene DB-Tabelle . . . 4.11. Beispiel-Konfiguration HTTPS-Verbindung JBoss-Tomcat . . . . . . . . . . . . . 4.12. XDoclet-Beispiel (stateless Session Bean) . . . . . . . . . . . . . . . . . . . . . . 4.13. XDoclet-Beispiel (stateless Session Bean) . . . . . . . . . . . . . . . . . . . . . . 5.1. Eingabe-Formular zur Benutzerauthentifikation . . . . . . . . . . . . . . . . . . . A.1. Beispiel eines einfachen Servlets . . . . . . . . . . . . . . . . . . . . . . . . . . . A.2. Beispiel einer einfachen JSP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A.3. Konsolenausgabe Deployment . . . . . . . . . . . . . . . . . . . . . . . . . . . . A.4. Konsolenausgabe Undeployment . . . . . . . . . . . . . . . . . . . . . . . . . . . A.5. Darstellung des Deployment-Deskriptor web.xml der Referenzanwendung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 43 46 47 51 66 76 77 78 83 84 87 88 88 89 90 94 94 124 136 138 138 139 142 Literaturverzeichnis Hinweis: Es wurden sowohl Print- als auch Online-Ressourcen berücksichtigt. Aufgeführt ist zusätzlich Literatur die zur Erstellung der Anwendung verwendet wurde. Bal00 BALZERT, Helmut: Lehrbuch der Software-Technik. Bd. 2. Heidelberg, Berlin : Spektrum, Akademischer Verlag GmbH, 2000 BE03 BACKSCHAT, Martin ; E DLICH, Stefan: J2EE-Entwicklung mit Open-Source-Tools: Coding-Automatisierung-Projektverwaltung-Testen. Spektrum, Akademischer Verlag GmbH, 2003 BG02 BACKSCHAT, Martin ; G ARDON, Otto: Enterprise JavaBeans. Spektrum, Akademischer Verlag GmbH, 2002 Bie01 B IEN, Adam: Enterprise Java Frameworks, Das Zusammenspiel der Java-Architekturen. Addison-Wesley, 2001 Boh03 B OHLEN, Matthias: Enterprise JavaBeans: GE-PACKT. mitp Verlags GmbH, 2003 BS03 B IEN, Adam ; S AWITZKI, Rainer: J2EE Hotspots. Addison-Wesley, 2003 Cur94 C URRAN, James M. Little Endian vs. Big Endian. http://www.noveltheory. com/techpapers/endian.asp. 1994 DP02 D ENNINGER, Stefan ; P ETERS, Ingo: Programmer’s Choice. Bd. 2: Enterprise JavaBeans 2.0. Addison-Wesley, 2002 Edl02 E DLICH, Stefan: Ant, kurz&gut. O´Reilly Verlag GmbH & Co. KG, 2002 FL02 F LEURY, Marc ; L INDFORS, Juha: JMX Managing J2EE with Java Management Extensions. Sams, 2002 Fou04a F OUNDATION, The Apache S. http://ant.apache.org/manual/index.html. 2004 Apache Ant 1.6.1 Manual. 156 Literaturverzeichnis Fou04b F OUNDATION, The Apache S. Tomcat Online Dokumentation. http://jakarta. apache.org/tomcat/tomcat-4.1-doc/. 2004 Gra03 G RASL, Oliver: J2EE und .NET: kein Vergleich? In: HMD - Praxis der Wirtschaftsinformatik (2003), April, Nr. 230 Hal01 H ALL, Marty: Core Servlets und JavaServer Pages. Markt+Technik Verlag, 2001 HS00 H EUER, Andreas ; S AAKE, Gunter: Datenbanken: Konzepte und Sprachen. Bd. 2. Bonn : mitp Verlags GmbH, 2000 KP88 K RASNER, Glenn E. ; P OPE, Stephen T.: A cookbook for using the model-view-controller interface paradigm in Smalltalk-80. In: Journal of Object-Oriented Programming 1 (1988), August/September, Nr. 3, S. 26–49 Krü02 K RÜGER, Guido: Handbuch der Java-Programmierung. Addison-Wesley, 2002 Kun02 K UNNUMPURATH, Meeraj: JBoss 3.0 Deployment and Administration. wrox, 2002 LB03 L ABOUREY, Sacha ; B URKE, Bill. JBoss Clustering. www.jboss.org. August 2003 Mar02 M ARINESCU, Floyd: EJB Design Patterns: Advanced Patterns, Processes, and Idioms. John Wiley, Februar 2002 McM02 M C M ANUS, Eamonn. JSR 3: Java Management Extension (JMX) SPezification. http: //www.jcp.org/en/jsr/detail?id=3. Dezember 2002 MHC01 M ONSON -H AEFEL, Richard ; C HAPPEL, David: Java Message Service. O´Reilly & Associates, Inc., 2001 Oes00 O ESTEREICH, Bernd: Objektorientierte Softwareentwicklung, Analyse und Design mit der Unified Modeling Language. R. Oldenburg Verlag, 2000 OHE97 O RFALI, Robert ; H ARKEY, Dan ; E DWARDS, Jeri: Abenteuer Client/Server. AddisonWesley, 1997 Poh03 P OHMANN, Peter: Das .NET-Komponentenmodell. In: HMD - Praxis der Wirtschaftsinformatik (2003), April, Nr. 230 Pro03 P ROULX, Emmanuel. www.ejb-ql.com. www.ejb-ql.com Die URL www.ejb-ql.com ist nicht mehr erreichbar. Eine Kopie dieser Seite liegt auf der CD, die mit dieser Diplomarbeit ausgeliefert wird. 2003 Literaturverzeichnis 157 Qui04 Q UIN, Liam. Extensible Markup Language (XML) 1.0 (Third Edition). http://www. w3.org/XML/. Februar 2004 Ric01 R ICCARDI, Greg: Datenbanksysteme:mit Internet- und Java-Applikatrionen. AddisonWesley, 2001 Sch01 S CHWICHTENBERG, Dr. H.: COM-Komponenten-Handbuch. Addison-Wesley, November 2001 SDD02 S CHMIETENDORF, Andreas ; D IMITROV, Evgeni ; D UMKE, Reiner: Enterprise JavaBeans. Bonn : mitp Verlags GmbH, 2002 SF02 S TARK, Scott ; F LEURY, Marc: JBoss Administration and Development. Sams Publishing, 2002 Sha03 S HANNON, Bill. Java 2 Platform Enterprise Edition Specification, v1.4. http://java.sun.com/j2ee/. November 2003 SM97 S UN -M ICROSYSTEMS. The JavaBeans 1.01 specification. http://java.sun.com/ products/javabeans/. August 1997 SM01a S UN -M ICROSYSTEMS. Enterprise JavaBeans Specification, Version 2.0. 2001 SM01b S UN -M ICROSYSTEMS. Java 2 Platform Enterprise Edition Specification, v1.3. http://java.sun.com/j2ee/1.3/docs/index.html. 2001 SM04a S UN -M ICROSYSTEMS. Enterprise BluePrints. http://java.sun.com/blueprints/enterprise/. Februar 2004 SM04b S UN -M ICROSYSTEMS. J2EE Compatible Implementations. com/j2ee/compatibility.html. April 2004 http://java.sun. The03 T HE S ERVER S IDE . COM. TheServerSide Application http://www.theserverside.com/reviews/matrix.tss. Dezember 2003 Server Matrix. TS03 TANENBAUM, Andrew S. ; S TEEN, Maarten v.: Verteilte Systeme. Pearson Studium, 2003 TSS01 T URAU, Volker ; S ALECK, Krister ; S CHMIDT, Marc: Java Server Pages und J2EE. dpunkt.verlag, 2001 Ull03 U LLENBOOM, Christian: Java ist auch eine Insel - Programmieren für die Java 2Plattform in der Version 1.4. Galileo Press, Mai 2003 Selbstständigkeitserklärung Ich erkläre hiermit, dass die vorliegende Arbeit von mir selbst und ohne fremde Hilfe verfasst wurde. Alle benutzten Quellen sind im Literaturverzeichnis angegeben. Die Arbeit hat in gleicher oder ähnlicher Form noch keiner Prüfungsbehörde vorgelegen. Brandenburg an der Havel, 22. Mai 2004