Impressum

Dirk Weil
Java EE 6
Enterprise-Anwendungsentwicklung leicht gemacht

ISBN: 978-3-86802-600-9
© 2012 entwickler.press

Ein Imprint der Software & Support Media GmbH

Bibliografische Information Der Deutschen Bibliothek
Die Deutsche Bibliothek verzeichnet diese Publikation in der Deutschen
Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über
http://dnb.ddb.de abrufbar.

Ihr Kontakt zum Verlag und Lektorat:
Software & Support Media GmbH
entwickler.press
Darmstädter Landstr. 108
60598 Frankfurt am Main

Tel.: +49 (0)69 630089-0
Fax: +49 (0)69 930089-89
lektorat@entwickler-press.de
http://www.entwickler-press.de

Lektorat: Sebastian Burkart
Korrektorat: Frauke Pesch
Satz: Dominique Kalbassi

Alle Rechte, auch für Übersetzungen, sind vorbehalten. Reproduktion jeglicher Art (Fotokopie, Nachdruck, Mikrofilm, Erfassung auf elektronischen Datenträgern oder anderen Verfahren) nur mit schriftlicher Genehmigung des Verlags. Jegliche Haftung für die Richtigkeit des gesamten Werks kann, trotz sorgfältiger Prüfung durch Autor und Verlag, nicht übernommen werden. Die im Buch genannten Produkte, Warenzeichen und Firmennamen sind in der Regel durch deren Inhaber geschützt.

Vorwort

Java steht uns als leistungsfähige Basis für die Softwareentwicklung schon seit mehr als 15 Jahren zur Verfügung, einen großen Teil davon auch inklusive der Enterprise Edition, d. h. der Plattform für Unternehmensanwendungen, die verteilte Systeme mit oder ohne Browser als Client, (Web-) Services, Clustering, integrierte Systemlandschaften etc. beherrschbar machen soll. Warum dann jetzt ein Buch über die Softwareentwicklung mit Java EE?

Java EE ist zweifellos schon seit vielen Jahren eine verlässliche und tragfähige Plattform zur Entwicklung von Enterprise-Anwendungen. Die hohe Komplexität der ersten Versionen hat aber viele bewogen, sich ganz oder teilweise zugunsten anderer Frameworks abzuwenden. Die Kritik war bis zur Version 1.4 auch durchaus berechtigt – nun aber sind die Weichen neu gestellt in Richtung Einfachheit der Softwareentwicklung.

Ein Wert von Java EE besteht sicher in ihrer abwärtskompatiblen Weiterentwicklung. Für ältere Versionen erstellte Anwendungen bleiben also weiter lauffähig. Als Kehrseite der Medaille sind somit auch die alten Strukturen der Plattform noch vorhanden. Um in den Genuss der leichtgewichtigen Softwareentwicklung zu kommen, muss man sich somit auf die neuen Wege konzentrieren und alten Ballast rechts und links liegen lassen.

Dieses Buch soll Ihnen bei der Auswahl aus dem großen Angebot der Java EE eine Hilfe sein. Es hat nicht den Anspruch einer allumfassenden Darstellung, sondern beschränkt sich auf die Teile der Gesamtspezifikation, mit denen sich ein leistungsfähiger, aber überschaubarer Stack für Enterprise-Anwendungen zusammensetzen lässt. Es zeigt anhand vieler Beispiele, wie einfach Software für die Java-EE-Plattform erstellt werden kann. In einem durchgängigen „Real World“-Projekt werden am Ende alle behandelten Teile zu einer kompletten Anwendung zusammengesetzt und so das Zusammenspiel der Einzelteile verdeutlicht.

Begleitprojekte

Die im Buch gezeigten Beispiele stammen aus den Begleitprojekten zu den jeweiligen Buchkapiteln. Sie stehen unter dem URL http://www.gedoplan.de/veroeffentlichungen/javaee6buch zum Download bereit. Dort ist auch das erwähnte übergreifende Projekt enthalten.

Weiterführende Dokumentation

Im Sinne der Auswahl der zur leichtgewichtigen Softwareentwicklung benötigten Teile der Java EE geht das Buch nicht auf sämtliche Details der Plattformbestandteile ein, sondern verweist für weniger häufig genutzte Informationen auf die jeweiligen Spezifikationen. Sie können über http://jcp.org auf diese Texte zugreifen. Am Anfang der Buchkapitel finden Sie jeweils einen entsprechenden Link.

Wir haben weitgehend darauf verzichtet, die Java-Dokumentation der Plattformklassen im Buch abzudrucken, da sie online verfügbar ist. Sie kann unter http://docs.oracle.com/javaee/6/api/ direkt gelesen werden und ist unter http://www.oracle.com/technetwork/java/javaee/documentation/ downloadbar.

1 Java EE im Überblick

1.1 Aufgabenstellung

Java EE steht für „Java Platform, Enterprise Edition“ und ist eine Dachspezifikation mit gut drei Dutzend einzelnen Spezifikationen, die als Ergänzung der Standard Edition für unterschiedliche Bereich der Anwendungsentwicklung dienen. Im Kern geht es um verteilte Anwendungen, die ggf. auf mehreren Servern laufen, von Clients unterschiedlichen Typs genutzt werden und mit anderen Anwendungen im Unternehmensverbund vernetzt sind. Einige Teilspezifikationen sind aber auch im reinen Standard-Umfeld anwendbar.

Die Spezifikationen legen die Schnittstellen und Umgebungseigenschaften sehr strikt fest und definieren zudem eine Menge standardisierter Infrastrukturdienste wie bspw. Transaktionssteuerung oder Komponentenregistrierung. Entwickler erhalten dadurch einen vorgegebenen Rahmen, in dem sie Software erstellen können, ohne stets die komplexe Laufzeitumgebung vor Augen zu haben. Sie können sich idealerweise auf das konzentrieren, was ihre eigentliche Aufgabe ist: Fachlogik implementieren.

1.2 Architekturmodell

Java-EE-Anwendungen lassen sich grob aufteilen in eine Clientschicht, die serverseitige Implementierung und eine Schicht, in der Daten abgelegt oder von anderen Systemen weiterverarbeitet werden.

Als Clients von Java-EE-Anwendungen werden häufig Browser eingesetzt. Die Präsentationslogik wird in diesem Fall serverseitig bereitgestellt, vielfach durch JavaServer Faces in einem Web Container.

Desktopclients implementieren die Präsentationslogik i. d. R. selbst. Sie greifen entweder direkt auf die Geschäftslogik zu oder bedienen sich bspw. Web Services.

Die Geschäftslogik kann mittels CDI und/oder EJB programmiert werden und diverse weitere serverseitige Techniken wie Java Persistence, Connector, Messaging etc. verwenden.

Die verarbeiteten Daten werden häufig in Datenbanken abgelegt, können aber auch in anderen Backend-Systemen liegen, die auf unterschiedliche Weise angebunden werden können.

Abbildung 1.1 zeigt dieses Modell schematisch. Es ist aus Gründen der Übersichtlichkeit etwas vereinfacht:

Neben Browser und Desktop sind andere Clients denkbar wie bspw. mobile Geräte

In der Webschicht sind andere Framework als JavaServer Faces einsetzbar

Aus der Geschäftslogikschicht ließen sich die eher technische Aspekte wie Connector, Messaging etc. in eine Infrastrukturschicht extrahieren

Abbildung 1.1: Java-EE-Architekturmodell

1.3 Anwendungsbestandteile und Formate

Java-EE-Anwendungen sind aus wohldefinierten Teilen aufgebaut, die sich grob an den Architekturbestandteilen orientieren. Technisch werden die Teile in separaten Jar-Dateien bereitgestellt.

Da in den weiteren Kapiteln des Buches näher auf die Bestandteile eingegangen wird, soll hier zunächst nur ein grober Überblick geschaffen werden.

Webanwendung

Dieser Anwendungsteil fasst die Webdokumente, Servlets etc. zusammen, die für die serverseitige Präsentationslogik der Anwendung benötigt werden, und zwar in ein Jar-File mit der Endung .war. Ein optionaler Deployment Descriptor WEB-INF/web.xml erlaubt die Konfiguration der Anwendung.

Enterprise JavaBeans

Im ursprünglichen Ansatz der Java EE waren EJBs der Platz für die serverseitige Geschäftslogik. Die Klassen und Interfaces mehrerer EJBs werden dann zu einem Jar-File zusammengepackt. Auch hier können Konfigurationswerte in einem Descriptor META-INF/ejb-jar.xml beigefügt werden. Die Endung .jar lässt leider keine direkte Unterscheidung von einer einfachen Bibliothek zu.

CDI

Die Aufgaben von EJBs können weitgehend von CDI übernommen werden. Java EE definiert dafür kein spezielles Anwendungsformat. Vielmehr werden die CDI-Klassen und Interfaces direkt oder als einfache Bibliothek in die gesamte Anwendung integriert. Hier ist ein Descriptor namens beans.xml notwendig.

Enterprise-Anwendung

Hierin werden die zuvor genannten Bestandteile nochmals zusammengefasst, und zwar zu einem Jar-File mit der Endung .ear. Zusätzlich können auch Konnektoren und Application Clients integriert werden, worauf hier aber nicht weiter eingegangen werden soll. Konfigurationsparameter dürfen in META-INF/application.xml eingetragen werden. In einem speziellen Verzeichnis – üblicherweise lib genannt – können Bibliotheken eingetragen werden, die der gesamten Anwendung zur Verfügung stehen sollen.

Abbildung 1.2 zeigt schematisch den Aufbau einer Enterprise Application, wobei die Inhalte der Applikationsteile – ihrerseits Jar-Files – exemplarisch angegeben sind.

Abbildung 1.2: Aufbau einer Enterprise-Anwendung inklusive der Inhalte der Anwendungsteile

Deployment-Formate

Im Sinne der Spezifikation sind Web- und Enterprise-Anwendungen deploy-fähig. Das eigentliche Deployment-Verfahren ist abhängig vom verwendeten Application Server. Vielfach wird ein Autodeploy-Ordner angeboten, in den die .war- bzw. .ear-Dateien kopiert werden können. Alternativ oder zusätzlich bieten die Hersteller Administrationswerkzeuge an, mit denen ein Deployment von Anwendungen vorgenommen werden kann.

Einige Server erlauben auch das Deployment von Verzeichnissen. Sie haben die interne Struktur der genannten Archivdateien, sind aber eben nicht gepackt. Die gängigen Entwicklungsumgebungen nutzen dies häufig für ein schnelles und inkrementelles Deployment-Verfahren direkt aus der IDE heraus.

Die Entscheidung für eines der beiden „offiziellen“ Deployment-Formate ist weniger technischer, sondern eher organisatorischer Natur:

Das EAR-Format eignet sich recht gut, wenn die Anwendungsteile klar abgegrenzt sind und sich das auch in der erstellten Dateistruktur widerspiegeln soll. Die Anwendung wird im Betrieb mit mehreren Classloadern geladen, die einander in der Art referenzieren, dass die Webanwendungen die Klassen der gesamten Anwendung nutzen können, umgekehrt aber die Klassen einer Webanwendung für andere Anwendungsteile nicht sichtbar sind. Die Abhängigkeiten der Anwendungskomponenten untereinander spiegeln sich hier also im Classloading passend wider.

In vielen Fällen benötigt man die zwar klare, aber doch komplexe Struktur des EAR-Deployments nicht. Dann kann ein WAR-Deployment gewählt werden (entsprechend dem oberen umrahmten Teil der Abbildung 1.2). Obwohl es sich nun dem Namen nach um eine Webanwendung handelt, können auch EJBs oder CDI Beans integriert werden1, sodass das WAR-Format keine Nachteile im Hinblick auf die verwendbaren Teile hat. Die Anwendung wird nun allerdings mit nur einem Classloader geladen, sodass zwischen den Anwendungsklassen keinerlei Isolation gegeben ist.

Die Begleitprojekte zu den Buchkapiteln sind als WAR-Deployments aufgebaut.

1.4 Profile

Beginnend mit der Version 6 der Java EE wurde eine Gruppierung der Teilspezifikationen in sog. Profile eingeführt. Damit wird der Tatsache Rechnung getragen, dass für viele Anwendungstypen nur bestimmte Teile der Java EE benötigt werden. Ein Serverhersteller ist damit nicht mehr gezwungen, für einen Java-EE-Server die gesamte Bandbreite der Spezifikation abzudecken. Er kann vielmehr einen Server anbieten, der ein bestimmtes Profil unterstützt.

Derzeit ist neben dem Gesamtumfang – dem Full Profile – nur das Web Profile definiert, das die Teile der Java EE enthält, die man i. d. R. zum Aufbau von webbasierten Anwendungen benötigt (Abb. 1.3). In der Zukunft werden sicher weitere Profile definiert werden, z. B. zur Unterstützung von Web Services oder Messaging.

Abbildung 1.3: Web und Full Profile mit den von ihnen umfassten Teilspezifikationen2 3

1.5 Plattformen

Java-EE-Anwendungen können weitgehend unabhängig vom Laufzeitsystem entwickelt werden. Für den späteren Betrieb stehen diverse Server zur Verfügung, teilweise als Open Source, teilweise kommerziell mit entsprechendem Serviceangebot Tabelle 1.1 zeigt einige der derzeit zur Verfügung stehenden Server.

Server

unterstütztes Profil

Oracle GlassFish 3

Full (Referenzimplementierung)

JBoss AS 6 und 7.0

Web

JBoss AS 7.1

Full

Caucho Resin 4

Web

Apache Tomcat + (TomEE, Siwpas)

Web

IBM WebSphere 8

Full

Oracle WebLogic 12

Full

Tabelle 1.1: Einige zur Verfügung stehende Java-EE-6-Server

1 Die Descriptoren aus META-INF werden im WAR-Deployment in WEB-INF platziert.

2 JSR 45: Debugging Support for Other Languages
JSR 77: J2EE Management
JSR 88: Java EE Application Deployment
JSR 196: Java Authentication Service Provider Interface for Containers
JSR 250: Common Annotations for the Java Platform

3 JAXR, JAX-RPC und JSR 88 sind für die nächste Version nur noch optional geplant

2 CDI

2.1 Was ist das?

CDI steht für Contexts and Dependency Injection for the Java EE Platform und ist ein Standard innerhalb des Webprofils der Dachspezifikation JavaEE6. Der Arbeitsbereich von CDI ist die Bereitstellung und Verknüpfung von Komponenten und Diensten als Basis für Enterprise-Applikationen. CDI ist allerdings nicht nur im EE-Umfeld nutzbar, sondern kann auch ohne Applikationsserver eingesetzt werden.

CDI wurde im JSR 299 lange Zeit unter den Namen WebBeans entworfen und standardisiert viele Ideen und Konzepte von populären Open-Source-Frameworks wie Seam und Spring(-Core). Die Spezifikation ist für Java-EE-Verhältnisse angenehm kurz: ca. 100 gut lesbare Seiten1.

Neben der Referenzimplementierung JBoss Weld2 stehen u.a. Apache OpenWebBeans3 und Resin CanDI4 als CDI-Container zur Verfügung.

2.2 Wozu braucht man das?

Professionelle Anwendungen sind nicht monolithisch aufgebaut, sondern bestehen aus Komponenten. Zum einen ergeben sich bei der Entwicklung von Software aus der Analyse der Aufgabenstellung fachliche Bereiche, die durch fachliche Komponenten abgebildet werden können. Innerhalb dieser Komponenten lassen sich wieder Teile abgrenzen, diesmal eher technischer Natur. Die Komponenten benutzen andere Komponenten und die Plattformdienste, sind aber weitgehend abgegrenzt (Abb. 2.1).

Abbildung 2.1: Anwendungskomponenten

Eine Aufgabe der Softwareentwicklung ist es nun, diese Komponenten untereinander zu verknüpfen, sodass eine saubere Anwendungsarchitektur entsteht. Das kann natürlich mit einfachen Sprachmitteln von Java geschehen. Eine Komponente kann in ihrem Programmcode andere Komponenten instanziieren, indem sie new benutzt. Dadurch wird die Kopplung der Komponenten aber sehr stark, denn die aufrufende Komponente muss die benutzte sehr genau kennen, Änderungen sind aufwändig, der Einsatz einer alternativen Komponente unmöglich.

Zudem profitieren solche Objekte kaum von der Umgebung der Anwendung: Der Applikationsserver „kennt“ sie nicht, kann also bspw. kein Monitoring und keine Laufzeitsteuerung dafür durchführen. Flexibler ist es, die benötigten Objekte vom Application Server herstellen zu lassen. In den früheren Versionen der Java EE – damals noch J2EE – hat man dazu weitgehend String-basierte Referenzen benutzt, hat also bspw. die benötigte Komponente per Namen im JNDI-Dienst adressiert. Hier stellt sich aber das Problem der „Zielgenauigkeit“: Ist ein Objekt unter dem verwendeten Namen überhaupt vorhanden und hat es den richtigen Typ (Listing 2.1)?

// Unsicher: Ist ein Objekt mit dem Namen konfiguriert?
//            Falls ja, hat es den korrekten Typ?
MyService myService
  = (MyService) jndiContext.lookup("ejb/myService");

Listing 2.1: Referenzierung einer Komponente über ihren Namen

Ein weiteres Problem ist die Abhängigkeit der aufrufenden Komponente von ihrer Umgebung: Der Code im Beispiel setzt unumstößlich voraus, dass es einen JNDI-Dienst gibt. Ein Test des Codes außerhalb des Applikationsservers ist damit unmöglich. Hier setzt die Idee Inversion of Control an, die den aktiven Teil der Komponentenverknüpfung aus der Komponente herauslöst und in die Laufzeitumgebung – den Container – verlagert: Nicht die Komponente besorgt sich die von ihr benötigten Serviceobjekte, sondern der Container liefert sie an. Dieses Verfahren firmiert unter dem Namen Dependency Injection – Injektion von benötigten Objekten, womit wir auch schon die beiden letzten Drittel des Namens CDI erklärt hätten (Abb. 2.2).

Abbildung 2.2: Dependency Injection

Die Komponente „weiß“ jetzt nicht mehr, woher sie die von ihr genutzten Objekte erhält. Damit ist die Kopplung zu ihrer Umgebung so klein geworden, dass ein Austausch leicht möglich wird: Im Produktivsystem werden Komponenten und Ressourcen vom Container bspw. weiterhin im JNDI-Dienst verwaltet, während sie in einer Testumgebung ohne Container von der Testklasse geliefert werden.

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!

Lesen Sie weiter in der vollständigen Ausgabe!