Wintersemester 2007/2008 FernUniversität Hagen
Fakultät für Mathematik und Informatik
 Kurs 1794 - Software Engineering II - Methodische Entwicklung von Webapplikationen
 Lehrgebiet Software Engineering, Prof. Dr. Six

Projektstrukturen und Ant

Übersicht

Projektstrukturen

Projektstruktur für Webapplikationen

In Kurseinheit 1 wurde die Verzeichnisstruktur einer Webapplikation vorgestellt. Ein Web Container (z.B. Tomcat oder der Sun Application Server) erwartet diese Verzeichnisstruktur und kann so die darin liegenden Servlets, JSPs und Konfigurationsdateien finden. Während der Entwicklung wird im Allgemeinen nicht direkt innerhalb des Webapplikationsverzeichnisses des Web Containers gearbeitet, sondern - meistens mittels einer integrierten Entwicklungsumgebung (kurz IDE für Integrated Development Environment) - eine eigene Projektstruktur verwendet. Zum Testen werden die Dateien der Webapplikation dem Web Container bekannt gemacht. Dies kann entweder die IDE automatisch übernehmen oder es wird ein WAR erstellt, das dann beim Web Container angemeldet oder in das Webapplikationsverzeichnis des Container hineinkopiert wird.

Da wir im Rahmen dieses Kurses nicht auf die Besonderheiten verschiedener IDEs (wie z.B. JBuilder, NetBeans oder Eclipse) eingehen können, haben wir auf die Erstellung IDE-spezifischer Projektstrukturen verzichtet. Wir liefern die Vorlagen für Aufgaben und Musterlösungen in einer allgemein gehaltenen Struktur. Die Vorgaben enthalten ein Build-Skript, um die Quelldateien auch ohne IDE in ein WAR überführen zu können. Dafür wird das Java-Tool Ant (siehe unten) benötigt, welches beim Sun Application Server bereits enthalten ist, aber auch separat installiert werden kann.

Die von uns gelieferten Vorlagen und Musterlösungen verwenden folgende Verzeichnisstruktur:

Projektstruktur WAR
Verzeichnis bzw. DateiInhalt
/buildErzeugte Dateien außer Klassendateien
/build/distErzeugtes WAR
/lib Bibliotheken, die nur zur Übersetzung benötigt werden, also nicht ins war-Archiv aufgenommen werden sollen. Kann meist leer bleiben. Man kann Dateien wie javaee.jar, die mit dem Web Container geliefert werden, hierher kopieren, wenn man nicht das lib-Verzeichnis des Web Containers mit in den classpath für die Übersetzung aufnehmen möchte. Wenn Sie das unten beschriebene asant-Tool benutzen, ist das aber nicht nötig.
/srcJava-Quelldateien
/webappVerzeichnis der Webapplikation wie im Kurstext besprochen.
/webapp/META-INFBleibt im Normalfall leer, muss aber (für unser Build-Skript) existieren.
Dateien in diesem Verzeichnis werden (neben den bei der WAR-Erzeugung generierten Metadaten) mit ins META-INF-Verzeichnis des war-Archivs kopiert.
/webapp/WEB-INF(siehe Kurstext)
/webapp/WEB-INF/classesDas Build-Script legt hier die compilierten Klassen ab, außerdem werden alle Ressourcen aus dem src-Verzeichnis, die keine Java-Quellen sind, hierher kopiert.
/webapp/WEB-INF/libBibliotheken, die mit der Webappliaktion zusammen ausgeliefert werden sollen, z.B. die Struts-JARs.
/build.xmlAnt-Buildscript, siehe unten
/build.propertiesKonfigurationsdatei zum Buildscript

Tabelle 1 Verzeichnisstruktur eines Webapplikation-Projekts

Projektstruktur für Jar-Module wie z.B. EJB-Jars

Analog zur oben eingeführten Projektstruktur für Webapplikationen haben wir eine weitere Projektstruktur mit vorgefertigtem Ant-Buildscript zur Erstellung von EJB-Jar-Modulen, Persistenz-Modulen (oder auch beliebiger anderer Jar-Module) erstellt:

Projektstruktur JAR
Verzeichnis bzw. DateiInhalt
/build/classesCompilierte Klassen & Ressourcen aus dem src-Verzeichnis (s. Tabelle 1).
/build/distErzeugtes JAR
/lib Bibliotheken, die nur zur Übersetzung benötigt werden (s. Tabelle 1)
/META-INFMetadaten.
Bei EJB-Modulen z.B. der (optionale) Deployment Descriptor ejb-jar.xml.
Bei Persistence Units ist hier der Deployment Descriptor persistence.xml abzulegen.
Der Ordner bleibt in unseren Beispielen oft leer, muss aber (für das Ant-Script) existieren.
/srcQuelldateien
/build.xmlAnt-Buildscript, siehe unten
/build.propertiesKonfigurationsdatei zum Buildscript

Tabelle 2 Verzeichnisstruktur eines Jar-Projekts

Projektstruktur für Enterprise Applications (Ear)

Mehrere Module, wie z.B. eine Webapplikation und die EJBs und Persistence Units, die sie benutzt, können zu einer Enterprise Application zusammengestellt werden. Als solche kann die gesamte Applikation ein einem Archiv (Enterprise Application Archive, EAR) zusammengefasst und in einem Schritt auf einem Application Server installiert werden.

Dem tragen wir Rechnung, indem wir folgende Projektstruktur für eine Enterprise Application festlegen, die beliebig viele Teilprojekte der beiden oben vorgestellten Strukturen (Webapplikationen und Jar-Module) als Subprojekte umfassen kann:

Projektstruktur EAR
Verzeichnis bzw. DateiInhalt
/build/distErzeugtes EAR
/META-INFMetadaten.
Der (optionale) Deployment Descriptor application.xml ist ggf. hier abzulegen. Der Ordner bleibt in unseren Beispielen i.d.R. leer, muss aber (für das Ant-Script) existieren.
Subprojekt i
(Name beliebig)
Ein Jar-Projekt oder ein Webapplikations-Projekt nach einer der beiden oben vorgestellten Projektstrukturen.
/build.xmlAnt-Buildscript, siehe unten
/build.propertiesKonfigurationsdatei zum Buildscript

Tabelle 3 Verzeichnisstruktur eines Ear-Projekts

Download eines leeren Projekts
Wir bieten ein leeres Ear-Projekt mit Verzeichnissen für EJB- und Struts-Webapplikations-Teilprojekten und allen benötigten ANT-Buildscripten zum Download an.

Anmerkung zur Benennung der Subprojekt-Verzeichnisse:
Damit beliebig viele Subprojekte beliebigen Namens in das Ear-Projekt aufgenommen werden können, ohne diese in einer Konfigurationsdatei für das Buildscript explizit bekannt machen zu müssen, arbeitet das Buildscript wie folgt:
Es sucht in jedem Unterverzeichnis des Ear-Projekts nach einem build.xml-Script und führt dieses ggf. aus. Die Reihenfolge ist nicht fest definiert, aber scheint -- zumindest unter Windows -- der alphabetischen Sortierung der Verzeichnisse zu entsprechen. Soll also die Webpplikation nach den EJB-Modulen, die sie benutzt, compiliert werden, sollte der Verzeichnis-Bezeichner für das Web-Modul später im Alphabet kommen. Andernfalls ist ggf. das Build-Script des Ear-Projektes zweimalig nacheinander auszuführen.

Wir schlagen als Benennungsschema für die Subprojekte den Gesamtprojekt-Namen mit einem Suffix wie -db für Persistence Units, -ejb für EJB-Jars und -war für Webapplikationen vor (vgl. Beispielprojekte).

SubprojektVorgeschlagener Name für das Unterverzeichnis
Persistence Unit
(JAR mit Entities)
<projectname>-db
EJB-Modul
(JAR mit EJBs)
<projectname>-ejb
Webapplikation<projectname>-war

Tabelle 4 Benennungsvorschlag für Teilprojekte

Ant

Verwendung von Ant

Ant ist ein von der Apache Software Foundation in Java geschriebenes Tool zur automatischen Durchführung bei der Entwicklung benötigter Aufgaben. Beispielsweise können mit Ant Quelltexte übersetzt oder JAR-Dateien der Pakete erstellt werden. Ant ist im Sun Application Server bereits enthalten, kann aber auch einzeln hier heruntergeladen werden.

Ant führt beim Aufruf das im aktuellen Verzeichnis befindliche Buildskript build.xml aus. Dort sind im XML-Format Anweisungen und Angaben zum Übersetzen usw. aufgeführt. Sie müssen das bei unseren Beispielen mitgelieferte Buildskript nicht bearbeiten, es wird über die beiliegende Datei build.properties konfiguriert. Die meisten der Einstellungen in dieser Konfigurationsdatei müssen Sie nicht ändern, von Interesse sind im Normalfall nur die folgenden:

propertyBeschreibung
name.archiveName für das zu erstellende (war-, jar- oder ear-)Archiv
name.projectEin Name für das Projekt
subprojects.classes.pathFalls das Teilprojekt (beispielsweise eine Webapplikation) auf Klassen eines anderen Teilprojekts (z.B. EJBs) angewiesen ist, sind die /build/classes-Verzeichnisse der entsprechenden Teilprojekte hier (durch Semikolon getrennt) anzugeben.
deploy.targetdirAutodeploy-Verzeichnis des Application Servers
Dies müssen Sie setzen, falls Sie das deploy-Target des war- oder ear- Buildscripts benutzen möchten, s.u.

Tabelle 5 Anzupassende Einträge der build-properties


Ein Ant-Buildscript kann verschiedene Aufgaben, Targets genannt, ausführen. Dazu wird einfach ant aufgerufen, ergänzt um den Bezeichner des Targets, z.B.:
ant war,
bzw. bei der von uns empfohlenen Verwendung des asant-Scripts:
asant war.

In den folgenden Beispielen werden wir immer asant schreiben, bei entsprechender Einrichtung von Ant kann der Aufruf aber jeweils auch äquivalent durch ant ersetzt werden.

Die folgenden Tabellen enthalten die wichtigsten Targets unserer mitgelieferten Ant-Buildscripts. Sie erhalten auch jeweils eine Übersicht der Targets, indem Sie ant -p (bzw. asant -p) aufrufen.

TargetBeschreibung
buildÜbersetzt die Quelldateien in src nach webapp/WEB-INF/classes
war (oder dist)Erstellt eine WAR-Datei in build/dist
javadocErstellt die API-Dokumentation in build/doc/api
cleanAllLöscht alle erzeugten Dateien
rebuildAlle erzeugten Dateien löschen und neu übersetzen.
Entspricht cleanAll gefolgt von build.
rewarAlles neu übersetzen und WAR erzeugen
Entspricht rebuild gefolgt von war
deployErstellt eine WAR-Datei und kopiert diese in das Autodeploy-Verzeichnis des Application Servers, das in der property deploy.targetdir (siehe Tabelle 5) eingestellt ist. Dies veranlasst den Server dazu, die Webapplikation zu installieren.
undeployLöscht die WAR-Datei wieder aus dem Autodeploy-Verzeichnis. Zumindest beim Sun Application Server wird dadurch die Deinstallation der Webapplikation ausgelöst.

Tabelle 6 Targets des Buildskripts für Webapplikationen

TargetBeschreibung
buildÜbersetzt die Quelldateien in src nach build/classes
jar (oder dist)Erstellt eine JAR-Datei in build/dist
javadocErstellt die API-Dokumentation in build/doc/api
cleanAllLöscht alle erzeugten Dateien
rebuildAlle erzeugten Dateien löschen und neu übersetzen.
Entspricht cleanAll gefolgt von build.
rejarAlles neu übersetzen und JAR erzeugen
Entspricht rebuild gefolgt von jar

Tabelle 7 Targets des Buildskripts für Jar-Archive

TargetBeschreibung
buildÜbersetzt und packt sämtliche Teilprojekte, indem jeweils das dist-Target jedes Teilprojekts aufgerufen wird.
Muss ggf. mehrfach ausgeführt werden, falls die Teilprojekte in falscher Reihenfolge übersetzt wurden, d.h. z.B. ein Web-Modul zuerst übersetzt wird, aber auf noch nicht übersetzte Klassen aus einem EJB-Modul angewiesen ist.
ear (oder dist)Erstellt eine EAR-Datei in build/dist, welche die WAR- bzw. JAR-Archive der Subprojekte bündelt.
cleanLöscht das build-Verzeichnis des Ear-Projekts.
cleanAllLöscht rekursiv alle erzeugten Dateien, auch in allen Teilprojekten.
deployErstellt eine EAR-Datei und kopiert diese in das Autodeploy-Verzeichnis des Application Servers, das in der property deploy.targetdir (siehe Tabelle 5) eingestellt ist. Dies veranlasst den Server dazu, die Enterprise Application zu installieren.
undeployLöscht die EAR-Datei wieder aus dem Autodeploy-Verzeichnis. Zumindest beim Sun Application Server wird dadurch die Deinstallation der Applikation ausgelöst.

Tabelle 8 Targets des Buildskripts für Enterprise Applications

Beispiel 1: WAR

Um z.B. eine WAR-Datei zu einer Musterlösung aus KE1 oder KE4 zu erzeugen, gehen Sie wie folgt vor:

  1. Laden Sie das Archiv der Musterlösung über die OKB herunter.
  2. Entpacken Sie das Archiv an beliebiger Stelle.
  3. Rufen Sie die Kommandozeile (Windows) oder eine Shell (Unix) auf und wechseln Sie in das Verzeichnis der Musterlösung
  4. Rufen Sie Ant mit Angabe des gewünschten Targets auf, in diesem Fall also:
    asant war
    Ant findet das Buildskript automatisch im aktuellen Verzeichnis.
  5. Das fertige WAR finden Sie unter build/dist/<projektname>.war

Um die so erstellte Webapplikation zu installieren und auszuprobieren, haben Sie folgende Möglichkeiten:

Die folgende Abbildung zeigt die Ausgabe von Ant beim Übersetzen der Musterlösung einer der Selbsttestaufgaben aus Kurseinheit 1:

C:\1794-ant-projekte\Zahlenraten-Loesung>asant war
Buildfile: build.xml

init:

compile:
    [mkdir] Created dir: C:\1794-ant-projekte\Zahlenraten-Loesung\webapp\WEB-INF\classes
    [javac] Compiling 2 source files to C:\1794-ant-projekte\Zahlenraten-Loesung\webapp\WEB-INF\classes

build:

war:
    [mkdir] Created dir: C:\1794-ant-projekte\Zahlenraten-Loesung\build\dist
      [war] Building war: C:\1794-ant-projekte\Zahlenraten-Loesung\build\dist\KE1.Zahlenraten.war
   [delete] Deleting: C:\1794-ant-projekte\Zahlenraten-Loesung\build\dist\Manifest.txt

BUILD SUCCESSFUL
Total time: 6 seconds

Abbildung 1 Ausgabe von Ant

Beispiel 2: EAR

Um ein Beispiel zu einer Enterprise Application aus KE5 zu installieren, gehen Sie prinzipiell genauso wie oben beschrieben vor, nur dass Sie statt des WARs das EAR erzeugen und deployen. Der Befehl zum Erstellen des EARs lautet entsprechend:

asant ear

Da das so ausgeführte Ant-Script mehrere andere Build-Scripte der Subprojekte ausführt und bei Fehlern in einem dieser Scripte (absichtlich) nicht selbst abbricht, prüfen Sie bitte gründlich das ausgegebene Protokoll auf Fehlermeldungen, auch wenn am Ende "BUILD SUCCESSFUL" steht.

Das Deployment funktioniert wieder über das Kopieren des EARs ins Autodeploy-Verzeichnis, Deployment über die Server-Admin-Konsole oder Eintragen des Pfades zum Autodeploy-Verzeichnis in der build.properties-Datei des Ear-Projekts und Ausführen von:

asant deploy

asant-Script des Sun Application Servers

Wie bereits gesagt, enthält der Sun Application Server bereits eine ausführbare Version von Ant. Damit beim Übersetzen der Sourcen während der build-Targets der Java-Compiler auch Zugriff auf Java EE-Bibliotheken und damit auf benötigte Pakete z.B. der Servlet-API bekommt, muss die mit dem Application Server gebündelte javaee.jar-Library in den Classpath aufgenommen werden.

Sun legt seinem Application Server ein Skript namens asant bei (wobei "as" für Application Server steht), das unter anderem diese Bibliothek zur Verfügung stellt, so dass Ant hierfür nicht manuell konfiguriert werden muss. Rufen Sie einfach an Stelle von ant jeweils asant auf, wie auch in den obigen Beispielen gezeigt.

Damit das möglich ist, ist lediglich sicherzustellen, dass das bin-Verzeichnis des Application-Servers im Pfad (Umgebungsvariable PATH) eingetragen ist, was das Setup des Application Servers normalerweise automatisch erledigen sollte.

Andere Ant-Installtionen / IDEs

Zur Installation einer direkt heruntergeladenen Ant-Version ist zunächst das heruntergeladene Archiv in ein beliebiges Verzeichnis zu entpacken. Anschließend wird die Umgebungsvariable ANT_HOME angelegt (bei Windows XP: Rechtsklick auf Arbeitsplatz --> Eigenschaften --> Erweitert --> Umgebungsvariablen) und auf das Installationsverzeichnis gesetzt. Zusätzlich wird noch in die Umgebungsvariable Path das bin-Verzeichnis (%ANT_HOME%\bin) der Ant-Installation aufgenommen. So kann ant nun aus einem beliebigen Projektverzeichnis heraus aufgerufen werden.

Sowohl bei Verwendung der so installierten Ant-Version über die Kommandozeile als auch bei Verwendung von Ant in IDEs wie Eclipse ist jeweils noch die JavaEE-Bibliothek (beim Sun Application Server heißt sie javaee.jar und findet sich im lib-Unterverzeichnis der AppServer-Installation) in den Classpath aufzunehmen. Bei Eclipse geschieht das z.B. über einen speziellen Ant-Konfigurationsdialog.

Weitere Hinweise

Mögliche Probleme beim Undeployment / Redeployment

Das Undeployment, also die Deinstallation einer Web- oder Enterprise-Applikation vom Application Server, die Sie z.B. über oben erwähntes undeploy-Target der Ant-Scripte auslösen können, funktioniert leider nicht immer. Gerade bei Struts-Applikationen ergibt sich oft folgendes Problem:

Der Application Server kann mitunter einige Dateien nicht löschen, da diese von einem Prozess noch blockiert werden.

Das passiert zumindest unter Windows z.B. oft mit Struts-Libraries, die in der Webapplikation eingebunden sind. Ob das Problem auch unter Linux auftritt, haben wir nicht getestet. Unseres Wissens soll das Problem aber mit Sun Application Server 9.0 Update 2 behoben worden sein. Sollte es aber doch auftreten, so ist nach dem (unvollständigen) Undeployment der Application Server herunterzufahren und dann das Verzeichnis mit den Resten der Applikation zu löschen (im Verzeichnis domains/domain1/applications/j2ee-apps für Enterprise Applications bzw. domains/domain1/applications/j2ee-modules für einzeln installierte Module wie z.B. reine Webapplikationen, die als WAR deployed wurden).

Das Problem betrifft auch das Redeployment (Aktualisieren einer Applikation), da dies einem Undeployment gefolgt von einem neuen Deployment gleichkommt. Ist das Undeployment aufgrund obigen Problems unvollständig, wird das anschließende Deployment fehlschlagen.
In diesem Fall ist zunächst ein Undeployment auszulösen, der Server herunterzufahren, die Relikte zu löschen, der Server neu hochzufahren und die Applikation dann neu zu deployen.


Copyright © 2007 FernUniversität in Hagen Stand: 02.10.2007, Autor: Immo Schulz-Gerlach