Automatisierte Erstellung von plattformspezifischen Installationspaketen für Java-Anwendungen Masterthesis Dipl.-Ing. Christian Elberfeld Fachbereich Elektrotechnik und Informatik, FH Münster Betreuer / Prüfer Prof. Dr. Nikolaus Wulff Prof. Dr. Gernot Bauer 1 Erklärung Ich versichere hiermit, dass ich diese Masterthesis ohne fremde Hilfe selbstständig verfasst und nur die angegebenen Quellen und Hilfsmittel benutzt habe. Wörtlich oder dem Sinn nach aus anderen Werken entnommene Stellen sind unter Angabe der Quelle kenntlich gemacht. Münster, den 19.05.06 2 Danksagung An dieser Stelle möchte ich allen danken, die mich während der Entstehung dieser Masterthesis und während meines Studiums in vielfacher Art und Weise unterstützt haben. Mein besonderer Dank gilt meinen Eltern und meiner Freundin, ohne deren Unterstützung diese Arbeit nicht möglich gewesen wäre. Für die Ermöglichung dieser Masterthesis möchte ich mich bei meinem Betreuer Prof. Dr. Nikolaus Wulff bedanken, der sich bereit erklärt hat, dieses selbstgewählte Thema zu betreuen, und mich mit Anregungen und konstruktiver Kritik bei der Umsetzung dieser Arbeit unterstützt hat. Für die freie Software, die in dieser Masterthesis Verwendung gefunden hat, und ohne welche sie nicht in diesem Umfang möglich gewesen wäre, gebührt den jeweiligen Autoren ebenfalls mein Dank. 3 Kurzzusammenfassung Diese Arbeit widmet sich der Problematik der automatisierten Installer-Erstellung für JavaAnwendungen. Im Verlauf der Arbeit werden verschiedene Installationstechnologien betrachtet, die auf Windows und Linux bereits verwendet werden. Anhand zweier ausgewählter Technologien, dem Windows Installer und dem Debian Package Manager, und einer Beispielanwendung werden die notwendigen Arbeitsschritte für die Erzeugung von Installer-Paketen betrachtet. Aus dieser theoretischen Betrachtung heraus wird ein Toolkit entwickelt, um die Erstellung von Installationspaketen so weit wie möglich zu automatisieren. Mit Abschluss dieser Arbeit wird das hier entwickelte Toolkit unter der LGPL als Open Source freigegeben und steht so allen interessierten Personen zur Benutzung und Weiterentwicklung offen. Die Projektseite ist unter der URL http://sourceforge.net/projects/install-toolkit zu finden. Die Formatierung des Textes erfolgte nach den folgenden Regeln: – Die Basisschriftart des Textes ist Times New Roman. – Sourcecodeabschnitte sowie Kommandozeilenbefehle sind als Textblöcke in Courier New hervorgehoben. – Verweise auf Java-Klassen und Verzeichnisse innerhalb des Textes sind kursiv hervorgehoben. – Querverweise innerhalb des Texte sowie URLs sind blau und unterstrichen hervorgehoben. 4 Inhaltsverzeichnis 1 Einleitung.......................................................................................................................................... 7 2 Auswahl der Betriebssysteme............................................................................................................9 3 Installationstechnologien................................................................................................................. 10 3.1 Java-basierte Lösungen............................................................................................................10 3.2 Microsoft Windows Lösungen.................................................................................................11 3.2.1 Nullsoft Scriptable Install System....................................................................................11 3.2.2 Der Windows Installer und das WiX Toolkit.................................................................. 13 3.2.3 Auswahl einer Technologie für Windows........................................................................15 3.3 Linux/Unix...............................................................................................................................15 3.3.1 RedHat Package Manager ............................................................................................... 15 3.3.2 Debian Package Manager.................................................................................................16 3.3.3 Autopackage ....................................................................................................................16 3.3.4 Klik...................................................................................................................................17 3.3.5 Auswahl einer Technologie für Linux ............................................................................ 17 4 Erstellen von Installationspaketen................................................................................................... 18 4.1 Die Demoanwendung DemoApp ............................................................................................18 4.2 Ein erstes Windows Installer Paket......................................................................................... 20 4.2.1 Installer Beschreibung......................................................................................................20 4.2.2 Erstellen des Installer-Paketes..........................................................................................26 4.3 Ein erstes DEB-Paket...............................................................................................................27 4.3.1 Vorbereitung ................................................................................................................... 27 4.3.2 Erstellen der Dateien im Verzeichnis debian................................................................... 28 4.3.2.1 control.......................................................................................................................28 4.3.2.2 changelog..................................................................................................................30 4.3.2.3 copyright...................................................................................................................30 4.3.2.4 compat...................................................................................................................... 30 4.3.2.5 Maintainer-Skripte....................................................................................................31 4.3.3 Bauen des DEB-Paketes...................................................................................................32 4.3.4 Installieren des DEB-Paketes...........................................................................................33 4.3.5 Prüfen des Paketes mit lintian.......................................................................................... 37 4.4 Java Laufzeitumgebung und Startskripte.................................................................................38 4.5 Verknüpfungen im Startmenü..................................................................................................42 4.5.1 Windows ......................................................................................................................... 42 4.5.2 KDE, Gnome und andere................................................................................................. 44 4.6 Update der Anwendung........................................................................................................... 47 4.7 Eine GUI für den Installer....................................................................................................... 50 4.7.1 Eine Standard GUI .......................................................................................................... 51 4.7.2 Erweiterung der GUI........................................................................................................52 4.8 Bedingungen beim Windows Installer.....................................................................................55 5 Automatisierung der Installer-Erstellung als Toolkit...................................................................... 56 5.1 Apache Ant.............................................................................................................................. 56 5.1.1 Eigene Ant Tasks erstellen...............................................................................................56 5.1.2 Ein einfacher Ant Task.....................................................................................................57 5.1.3 Ein Ant Task mit inneren Tags........................................................................................ 58 5.1.4 Einen Ant Task innerhalb eines Ant Tasks aufrufen....................................................... 60 5 5.2 Ant Tasks als Wrapper für die verwendeten Tools .................................................................61 5.2.1 Tasks für das WiX Toolkit...............................................................................................61 5.2.2 Tasks für die Debian Tools.............................................................................................. 62 5.3 Installer-Metainformationen.................................................................................................... 66 5.4 Verarbeitung der Installer-Metainformationen in einem Ant-Task.........................................72 5.5 Erzeugen des Windows Installer Paketes................................................................................ 72 5.5.1 Die Datei License.rtf erzeugen.........................................................................................73 5.5.2 Die Dateiliste erzeugen ................................................................................................... 74 5.6 Erzeugen des DEB-Paketes .................................................................................................... 75 5.7 Erstellung des Toolkits ........................................................................................................... 76 6 Erstellung von einfachen Installationspaketen................................................................................ 77 6.1 Installer Metainformationen.................................................................................................... 77 6.2 Erstellen der Anwendung ........................................................................................................79 6.3 Windows Installer.................................................................................................................... 80 6.4 DEB-Paket............................................................................................................................... 82 7 Erstellung von komplexen Installationspaketen.............................................................................. 83 7.1 Der JBoss Application Server..................................................................................................83 7.2 Modifikationen an der Verzeichnisstruktur............................................................................. 85 7.3 Log4J Anpassungen.................................................................................................................86 7.4 JBoss als Systemservice..........................................................................................................89 7.4.1 Konfiguration des JavaServiceWrappers......................................................................... 90 7.4.2 Startskripte für den JavaServiceWrapper.........................................................................91 7.5 Versionierung der Installer-Pakete.......................................................................................... 92 7.6 Metainformationen der Installer-Pakete.................................................................................. 92 7.7 Vorbereitung des JBoss........................................................................................................... 93 7.8 Serverkonfiguration „current“ des JBoss ................................................................................94 7.9 Bau des Windows Installer Paketes......................................................................................... 95 7.10 Bau der DEB-Pakete..............................................................................................................98 8 Zusammenfassung und Ausblick...................................................................................................102 9 Abbildungsverzeichnis.................................................................................................................. 103 10 Literaturverzeichnis..................................................................................................................... 104 6 1 Einleitung 1 Einleitung Ist eine Anwendung nach langer Zeit der Entwicklung fertiggestellt, muss diese Anwendung auch an den Anwender bzw. Endkunden weitergegeben werden. Hierfür ist es schon seit vielen Jahren üblich, dass eine Anwendung in Form eines Installationspaketes ausgeliefert wird, das der Anwender auf seinem System installieren kann. Auf Windows Systemen werden diese Installationspakete in den meisten Fällen mittels eines Install-Wizards installiert, der den Anwender schrittweise durch die Installation führt. Auf Linux-Systemen erfolgt die Installation meistens über die Paketverwaltung der eingesetzten Linux-Distribution. Insbesondere bei Java-Anwendungen gibt es allerdings auch immer wieder Beispiele von Anwendungen, die vom Anwender selbst installiert werden müssen. Zum einen wird der Benutzer den gewohnten Komfort eines Install-Wizards oder einer Paketverwaltung vermissen. Zum anderen sind das Entpacken der Anwendung und das Anpassen von Startskripten oder Konfigurationsdateien, sowie das Anlegen von Verknüpfungen im Startmenü für den Benutzer bestenfalls lästige Tätigkeiten. Ziel dieser Masterthesis ist es. nach einer Möglichkeit zu suchen, für eine bestehende Anwendung mit möglichst wenig Aufwand Installationspakete für verschiedene Betriebssysteme bereitzustellen. Zum einen wird hier der Entwickler einer Software (eine Firma oder Entwickler eines Open Source Projektes) angesprochen, dem die Möglichkeit gegeben werden soll, mit geringem Zusatzaufwand Installationspakete für verschiedene Plattformen zu erzeugen. Zum anderen soll aber auch ein Administrator, der eine bestehende Anwendung nicht verändern kann oder will, die Möglichkeit erhalten, ohne Modifikation einer Anwendung Installationspakete zu erzeugen. Insbesondere dann wenn eine Anwendung auf vielen Rechnern in einem Netzwerk installiert werden muss, kann so einiges an Arbeitszeit eingespart werden. Hierfür soll keine neue Installationstechnologie entwickelt werden, sondern die bereits auf den verschiedenen Betriebssystemen existierenden Technologien sollen soweit wie möglich genutzt werden. So wird auch die Möglichkeit offengehalten, die so erzeugten Installationspakete für automatisierte Softwareverteilung zu nutzen, wie es z.B. mittels Active Directory oder einer Software wie m23 [M23] möglich ist. Die Kapitel Auswahl der Betriebssysteme und Installationstechnologien stellen zunächst die zur Verfügung stehenden Technologien vor und betrachten die Unterschiede zwischen den Technologien. Für den weiteren Verlauf dieser Arbeit werden zwei verschiedene Betriebssysteme, sowie entsprechende Installationstechnologien für eine exemplarische Umsetzung ausgewählt. Das Kapitel Erstellen von Installationspaketen zeigt anhand der Beispielanwendung „DemoApp“ die Schritte auf, die zur Erstellung der Installationspakete notwendig sind. In dem Kapitel Automatisierung der Installer-Erstellung als Toolkit wird auf Basis des vorhergehenden Kapitels ein Toolkit entwickelt, dass die Erstellung von Installationspaketen vereinfachen und automatisieren soll. Dieses Toolkit steht als praktisches Ergebnis im Mittelpunkt dieser Arbeit. Mit Abschluss der Arbeit wird das Toolkit als Open Source Projekt auf der Open 7 1 Einleitung Source Plattform SourceForge [SF] freigegeben und steht so allen interessierten Personen zur Verfügung. Der Name des Projektes lautet „install-toolkit“. Die Projekthomepage ist unter der URL http://sourceforge.net/projects/install-toolkit erreichbar. Die Anwendung des Toolkits zeigt das Kapitel Erstellung von einfachen Installationspaketen. Hier werden noch einmal Installationspakete für die Beispielanwendung „DemoApp“ erzeugt. Dieses Kapitel zeigt, wie die Erzeugung von Installationspaketen mit dem Toolkit vereinfacht werden kann. Da die reale Welt aber nicht nur aus einfachen Beispielanwendungen besteht, wird in dem Kapitel Erstellung von komplexen Installationspaketen anhand des J2EE Applikationsservers JBoss beispielhaft die Erzeugung von Installationspaketen für eine komplexe Anwendung gezeigt. 8 2 Auswahl der Betriebssysteme 2 Auswahl der Betriebssysteme Für die Betrachtung systemintegrativer Installationsmethoden ist es notwendig, die entsprechenden Betriebssysteme separat zu untersuchen und für jedes Betriebssystem wiederum eine geeignete Installationstechnologie auszuwählen. Zum einen soll hier Microsoft Windows betrachtet werden, dass nach wie vor das verbreitetste Betriebssystem sowohl im Server- als auch im Clientbereich ist. Entsprechend der von Heise [HN1] veröffentlichten Studie des Marktforschungsinstitutes IDC [IDC] lag der Anteil von Servern mit Windows Betriebssystemen im Jahr 2002 bei 50,5 Prozent. Eine noch stärkere Dominanz erreicht Microsoft entsprechend dieser Studie im Clientbereich mit 93,8 Prozent im Jahr 2002. Auch eine aktuelle Studie der Marktforschungsinstitute IDC und Gartner [Gartn] (veröffentlicht in [HN2]) bescheinigt Microsoft mit 37 Prozent des Umsatzes im Serverbereich einen erheblichen Marktanteil. Als zweites wichtiges Betriebssystem soll Linux betrachtet werden, dass entsprechend der in [HN3] veröffentlichten Studie von IDC, immerhin mittlerweile einen Marktanteil von 16 Prozent hat. Als Distribution soll hier Debian [Debian] verwendet werden, die entsprechend einer Netcraft Studie [Netcr] über Linux Distributionen im Web-Hosting Bereich vom 5.12.2005 mit 25 Prozent die verbreitetste freie Linux Distribution ist. Lediglich die kommerzielle Distribution RedHat [RH] ist demnach verbreiteter. Für Linux basierte Clients gibt es keine derartige Studien. Allerdings zeigt sich hier die Verbreitung von Debian indirekt dadurch, dass es viele von Debian abgeleitete Distributionen speziell für den Desktopbereich gibt. Einige Vertreter sind die Distributionen Wiener Stadtverwaltung [WIENUX], der Behördendesktop [BD] des Bundesministeriums für Sicherheit in der Informationstechnik [BSI] oder die von Mark Shuttleworth initiierte Distribution Ubuntu [Ubuntu]. 9 3 Installationstechnologien 3 Installationstechnologien Die wohl älteste und teilweise heute noch verwendete Installationsmethode ist das XCopyDeployment. XCopy-Deployment meint, dass die Dateien der Anwendung in ein beliebiges Verzeichnis auf der lokalen Festplatte kopiert werden und die Anwendung von dort ausgeführt werden kann. Wenn auch für viele Anwendungen ausreichend, stößt die Installation mittels XCopyDeployment durchaus an Grenzen, sobald die Anwendung komplexer wird. Oft müssen einige Dateien der Anwendung in verschiedene Verzeichnisse des Systems kopiert werden (z.B.: Programmbibliotheken in /usr/lib bzw. C:\WINDOWS\System32) oder einzelne Komponenten der Anwendung müssen bei der Installation im System registriert werden (Systemdienste, COM+ Komponenten). Unter Linux/Unix, wo eine Vielzahl der Programme im Quelltext verbreitet wird, ist oft ein Installationsmechanismus in dem zugehörigen Makefile eingebaut, der die einzelnen Programmdateien in die entsprechenden Verzeichnisse des Systems kopiert bzw. entfernt. Mit der Entstehung von Linux Distributionen, die eine Vielzahl an Softwarepaketen beinhalten, werden die Anwendungen in Pakete verpackt, deren (De-) Installation von einem zentralen Paketmanager gesteuert wirde. Unter Windows wurden zu diesem Zweck oft Install-Wizards eingesetzt, die den Benutzer anhand mehrerer Bildschirmmasken durch die Installation führen. In diesem Zusammenhang ist unter anderem die Firma InstallShield1 [IS] bekannt geworden, die mit zu den ersten Firmen gehörte, die ein kommerzielles Toolkit zur Erstellung von Install-Wizards entwickelte. 3.1 Java-basierte Lösungen Da Java selber plattformunabhängig ist, gibt es verschiedene Ansätze, einen Installer auch in Java zu erstellen. Allen voran ist hier die Firma ZeroG2 mit ihrem Produkt InstallAnywhere [IA], die ein kommerzielles Toolkit für einen solchen Java basierten Installer anbietet. Neben der Problematik, dass ein solcher Installer nicht unbedingt an die Zielplattform angepasst ist und somit auch nicht von den plattformspezifischen Installations- und Updatemechanismen profitieren kann, stellt sich hier generell die Frage nach der geeigneten Oberfläche für die Benutzerführung. Während auf Windows Systemen generell eine grafische Oberfläche angeboten werden kann, kann auf Linux/Unix Systemen eine grafische Oberfläche (insbesondere im Serverbereich) nicht unbedingt vorausgesetzt werden. Auf der anderen Seite haben Text-basierte Oberflächen, die natürlich immer verfügbar sind, insbesondere auf viele Windows Benutzer eine abschreckende Wirkung. 1 InstallShield wurde im Juli 2004 von der Firma Macrovision aufgekauft 2 ZeroG wurde im Juni 2005 von der Firma Macrovision aufgekauft. 10 3 Installationstechnologien 3.2 Microsoft Windows Lösungen Abgesehen von Installationsprogrammen aus der DOS-Ära haben fast alle Installationsprogramme unter Windows ein ähnliches Aussehen: Ein Install-Wizard, der mit Hilfe mehrerer Dialoge den Benutzer durch die Installation führt. Abbildung 1: Ein typischer Install-Wizard 3.2.1 Nullsoft Scriptable Install System Für den Freeware mp3-Player Winamp [WAmp] hat die Firma Nullsoft mit dem Nullsoft Scriptable Install System (NSIS) [NSIS] ein eigenes Toolkit zum Erstellen von Windows Installern entwickelt und unter der LGPL freigegeben. NSIS wird durch eine Skriptdatei gesteuert, in der die Abfolge der Dialoge sowie die Aktionen zum Installieren und Deinstallieren der Programmdateien definiert sind. Der NSIS Compiler erzeugt aus der Skriptdatei und den zu installierenden Dateien dann eine Setup.exe, die dann auf dem Zielsystem als Install Wizard ausgeführt wird. Für die Deinstallation wird beim NSIS ebenfalls eine Uninstall.exe erzeugt, die zusammen mit den Programmdateien auf dem Zielsystem installiert und in der Software Liste der Windows Systemsteuerung registriert wird. Die Uninstall.exe enthält die notwendigen Aktionen, um die Anwendung wieder zu entfernen. 11 3 Installationstechnologien Beispiel eines sehr einfachen Skriptes zur Erzeugung eines NSIS-Installers (ohne Deinstallation): ; The name of the installer Name "Example1" ; The file to write OutFile "example1.exe" ; The default installation directory InstallDir $PROGRAMFILES\Example1 ; Pages Page directory Page instfiles ; The stuff to install Section "" ;No components page, name is not important ; Set output path to the installation directory. SetOutPath $INSTDIR ; Put file there File example1.nsi SectionEnd ; end the section Bei Verwendung des NSIS muss allerdings beachtet werden, dass nicht nur die Anweisungen zum Installieren der Programmdateien, sondern auch die Anweisungen zum Entfernen der Programmdateien3 programmiert werden müssen. Werden hier Anweisungen vergessen, kann es vorkommen, dass Programmdateien nach der Deinstallation auf dem System verbleiben oder der Uninstall-Eintrag in der Software Liste der Windows Systemsteuerung bei der Deinstallation nicht entfernt wird. Auch muss bei der Verwendung von NSIS beachtet werden, dass eine Installation nicht atomar behandelt wird. Sollten während der (De-) Installation Probleme bzw. Fehler auftreten, so kann es vorkommen, dass die Anwendung nur halb installiert oder deinstalliert wird. 3 Gleiches gilt B. auch für Registry-Einträge und die Registrierung des Uninstallers in der Softwareliste der Windows Systemsteuerung 12 3 Installationstechnologien 3.2.2 Der Windows Installer und das WiX Toolkit Bei der Entwicklung von Microsoft Office 984 wurde bei Microsoft der Windows Installer als neue Installationstechnologie für Windows Programme entwickelt. Hauptziel war es, hierbei das eigentliche Installationspaket (die Dateien und die Informationen, welche Datei wohin installiert werden soll) von dem Programm, dass die eigentliche Installation durchführt, zu trennen. Der Windows Installer ist mittlerweile fester Bestandteil eines jeden Windows Systems. Aktuell ist er in Version 3.1 vorhanden und wird automatisch über das Windows Update bzw. Microsoft Update auf dem System installiert. Das Installer-Paket wird beim Windows Installer als MSI-Datei (Microsoft Installer Package) bereitgestellt. Die MSI-Datei ist prinzipiell eine relationale Datenbank5, die die Metainformationen (welche Datei wohin installiert werden muss, etc.) für den Installer enthält. Eine ausführliche Übersicht über die Tabellen der MSI Datenbank bietet [WI:Knecht] im Kapitel 8. Die eigentlichen Dateien können entweder zusammen mit der MSI-Datei in einem Verzeichnis liegen oder als gepacktes Archiv an die MSI-Datei angehängt werden. Mit dem Programm ORCA aus dem Windows Installer SDK kann man den Inhalt einer MSI-Datei betrachten und auch verändern. Abbildung 2: Ansicht einer MSI-Datei mit ORCA 4 Ausschlaggebend war für diese Entscheidung die Komplexität der Office Installation, für die die bisherigen Installer Produkte nicht mehr ausreichend waren. 5 Eine sehr genaue Beschreibung des MSI-Formates enthält das Referenzwerk [WI:Kerl] im Kapitel 2. 13 3 Installationstechnologien Die Ausführung der Installation übernimmt der Windows Installer Service (msiexec.exe), der mit dem Windows Installer auf dem System installiert ist. Der Installer sorgt dann für die eigentliche (De-)Installation der Anwendung. Im Gegensatz zu Installern wie dem NSIS erfolgt die Installation beim Windows Installer transaktional. Das bedeutet, dass beim Auftreten eines Fehlers während der Installation die bisherige Installation rückgängig gemacht wird (Rollback) und das System wieder in den Ursprungszustand zurückversetzt wird6. Durch die Trennung von Metainformationen, die bei der Installation im System gespeichert werden, hat der Windows Installer die Möglichkeit, eine Anwendung zu reparieren, indem die Anwendung auf den Zustand nach der Installation zurückversetzt wird. Generell werden beim Windows Installer die Installation, Deinstallation und Reparatur als Transformation zwischen Systemzuständen beschrieben. Die MSI-Datei beschreibt hierbei den SollZustand des Systems nach einer erfolgreichen Installation. installieren Ist-Zustand System vor der Installation der Anwendung Soll-Zustand System nach der Installation der Anwendung reparieren deinstallieren Abbildung 3: Windows Installer - Zustandsdiagramm Neben weiteren Features, wie dem Erstellen von Patches, die nur einen Teil der Anwendung auf eine neue Version updaten, können MSI Pakete auch in einer Windows Domäne über das Active Directory auf verschiedenen Rechnern unbeaufsichtigt installiert werden (z.B. Anwendung XY wird für alle Mitarbeiter der Buchhaltung installiert). Mittlerweile basieren die mit Tools wie InstallShield [IS] oder Wise [WISE] erzeugten Installer nahezu alle auf dem Windows Installer. Auch mit dem Visual Studio können einfache Windows Installer Pakete für eigene Anwendungen erstellt werden. Einen gänzlich anderen Ansatz als das „Zusammenklicken“ eines Installers mit einem grafischen Tool wie InstallShield oder dem Visual Studio verfolgt Microsoft mit dem Windows Installer XML Toolkit WiX [WIX], das von Microsoft als Open Source Software freigegeben wurde. Hier wird das Installer Paket aus einer XML Beschreibung mittels eines Compilers (und eines Linkers) erzeugt7. Durch die XML Beschreibung und die Erzeugung mittels Compiler eignet sich das WiX Toolkit recht gut, um einen Installer im Verlauf einer Programmerstellung automatisiert mit zu erstellen. 6 Siehe auch [WI:Knecht], Kapitel 4.2 7 Siehe auch [WI:Kerl], Kapitel 1 14 3 Installationstechnologien 3.2.3 Auswahl einer Technologie für Windows Durch die hohe Systemintegration und die Möglichkeit der transaktionalen Installation ist der Windows Installer dem NSIS klar überlegen. Auch existiert mit dem WiX-Toolkit einen freie Software zum Erstellen der Windows Installer Pakete, die von Microsoft aktiv weiterentwickelt wird. Auch bietet der Windows Installer weitere Möglichkeiten, wie die Verteilung von Software über ein Active Directory, was insbesondere beim Einsatz in Unternehmensnetzwerken interessant ist. 3.3 Linux/Unix Durch die verschiedenen Linux/Unix Distributionen wurden auch verschiedene Paketmanagement Tools entwickelt, um die Installation der zahlreichen Softwarepakete einer Distribution zu verwalten. Allen gemeinsam ist hierbei, dass die Paketverwaltungen Abhängigkeiten zwischen Paketen automatisch auflösen können, indem die benötigte Software von der Paketverwaltung mit installiert wird. 3.3.1 RedHat Package Manager Vom Linux Distributor RedHat wurde der RedHat Package Manager [RPM] zur Verwaltung der Softwarepakete der RedHat Distribution [RH] entwickelt. Die Programmpakete werden als RPMDatei gepackt, die sowohl die zu installierenden Dateien wie auch die Metainformationen enthält. Alle zur Erstellung des RPM Paketes notwendigen Informationen werden aus einer Spec-Datei ausgelesen. Das Format der Spec-Dateien ist im RPM Guide [RpmG] im Anhang B beschrieben. Eine RPM Datei besteht aus einem Header, der die Metainformationen enthält, und einem, mittels gzip komprimierten, Anhang, der die zu installierenden Dateien enthält. Der RedHat Package Manager wird auch von Distributionen, die ursprünglich auf RedHat basieren, verwendet. Darunter sind unter anderem openSUSE [OSuse] (ehemals SuSE Linux) der Firma Novell [Novell] und Mandriva Linux [MD]. Problematisch bei den RPM basierten Distributionen ist allerdings, dass die Pakete für die gleiche Software in den verbreiteten Distributionen (RedHat, openSUSE und Mandriva) teilweise unterschiedlich benannt sind, so dass es oftmals nicht ohne weiteres möglich ist, ein RedHat-RPM auf einem openSUSE System zu installieren. 15 3 Installationstechnologien 3.3.2 Debian Package Manager In direkter Konkurrenz zum RedHat Package Manager steht der Debian Package Manager des Debian Projektes. Hier sind die Installationsdateien und Metainformationen als DEB-Dateien gepackt. Eine DEB-Datei ist ein AR-Archiv, das zwei Dateien (control.tar.gz und data.tar.gz) enthält. Die Datei control.tar.gz enthält die Dateien mit Metainformationen und die data.tar.gz enthält die Datendateien, wobei die Verzeichnisse relativ zum root-Verzeichnis sind. Die Datei data.tar.gz wird also praktisch in das root-Verzeichnis entpackt. Seine Mächtigkeit erhält der Debian Package Manager durch das zugehörige Advanced Package Tool (APT), das die automatische Auflösung von Abhängigkeiten und das Herunterladen von Paketen aus verschiedenen Repositories verwaltet. Ein Repository ist eine Paketsammlung, die unter anderem auf einer CD oder einem Mirror im Internet zu finden ist. Der Debian Package Manger wird unter anderem von allen Debian-basierten Distributionen wie Ubuntu [Ubuntu], Kubuntu [Kubuntu] oder Knoppix [Knoppix] verwendet. 3.3.3 Autopackage Autopackage [AP] ist ein Projekt, dass eine Install-Wizard basierte Installationstechnologie für Linux Distributionen entwickelt. Autopackage ist allerdings von der systemeigenen Paketverwaltung getrennt und verwaltet die über Autopackage installierten Anwendungen selber. Somit gehen bei der Verwendung von Autopackage die zusätzlichen Möglichkeiten wie automatische Updates und Softwareverteilung verloren. Der Artikel [LM:A] weist allerdings auch auf Probleme hin, falls identische Dateien über den Paketmanager der Distribution und über Autopackage installiert wurden. Diese Probleme sollen allerdings in kommenden Versionen behoben werden. 16 3 Installationstechnologien 3.3.4 Klik Ein ähnliches System ist Klik [klik]. Bei Klik werden die Anwendungen allerdings in ein eigenes Root-Verzeichnis installiert, das als Datei im Home-Verzeichnis des Benutzers abgelegt ist. Klik ermöglicht es daher auch Benutzern ohne Root-Rechte bzw. ohne Eingabe des Root-Passwortes eine Anwendung zu installieren. Klik eignet sich daher besonders gut, um Programme zu testen oder auf einer Live-CD Distribution wie Knoppix [Knoppix] zu verwenden. Der Artikel [LM:K] zeigt für Klik allerdings deutliche Grenzen auf. Zum einen ist die Anzahl der parallel eingebundenen Dateisysteme über das loop-Device standardmäßig im Kernel auf acht begrenzt, so dass nicht mehr als acht Klik-Anwendungen gleichzeitig ausgeführt werden können. Zum anderen wird hier auch benannt, dass es Performanceeinbußen geben kann und Klik-Anwendungen daher teilweise recht langsam laufen. 3.3.5 Auswahl einer Technologie für Linux Da in dieser Arbeit hauptsächlich die auf dem System vorhandenen Paketverwaltungen genutzt werden sollen, kommen nur RPM und DEB in Frage. Im Kapitel Auswahl der Betriebssysteme wurde Debian [Debian] als Linux Distribution für diese Arbeit ausgewählt. Obwohl auch, unter Verwendung des Programmes alien, RPM Pakete auf einem Debian-System installiert werden können, ist es naheliegend, hier DEB als Format für die Installationspakete auszuwählen. Vergleicht man RPM und DEB, so sind diese in vielen Punkten ähnlich. Diese Arbeit sollte daher auch auf RPM als Paketformat übertragbar sein. Auch kann mit dem Programm alien das erzeugte DEB-Paket in ein RPM-Paket konvertiert werden. Bei diesem Vorgang gehen allerdings einige Informationen, wie z.B. die Paketabhängigkeiten verloren. Eine Installation des Paketes über den RPM-Paketmanager ist aber prinzipiell möglich. 17 4 Erstellen von Installationspaketen 4 Erstellen von Installationspaketen Die Vorgehensweise zur Erstellung von Installationspaketen wird zunächst anhand der Anwendung „DemoApp“ erläutert. DemoApp ist möglichst einfach konzipiert, greift aber dennoch einige typische Probleme auf, die bei der Erstellung von Installationspaketen auftreten können. DemoApp besteht hierfür aus einen JAR-Archiv (demoapp.jar) mit entsprechenden Startskripten für Windows (demoapp.bat) und Linux (demoapp) sowie einer Konfigurationsdatei (demoapp.properties), die von dem Benutzer angepasst werden kann und einer Anwenderdokumentation (manual.txt). Die Erstellung der Anwendung wird von dem im Java-Umfeld weit verbreiteten Build-Tool Apache Ant [Ant] gesteuert. Das Projektverzeichnis besteht aus dem Haupverzeichnis mit der Dateie demoapp.properties, dem Build-Skript build.xml und der Datei build.properties, die lokale Einstellungen für das Build-Skript enthält. Die Java-Sourcedateien liegen in dem Verzeichnis src/java. Zusätzliche Dateien wie die Startskripte und die Dokumentation liegen im Verzeichnis src/files. Alle vom Build-Skript erzeugten Dateien werden im Verzeichnis target angelegt. Die erzeugten Klassen-Dateien werden im Verzeichnis target/classes abgelegt und in das jar-Archiv target/build/demoapp.jar gepackt. 4.1 Die Demoanwendung DemoApp Die Anwendung DemoApp besteht aus einer Java-Klasse, die in ihrer main()-Methode die Konfigurationsdatei demoapp.properties einliest und Text auf der Konsole ausgibt. Nach der Ausgabe wartet DemoApp bis die Return-Taste gedrückt wurde. Name und Pfad der Konfigurationsdatei werden der Anwendung als Kommandozeilenparameter übergeben. Die Klasse demoapp.DemoAppMain (Auszug): public static void main(String[] args) throws FileNotFoundException, IOException { String configfile = ""; if (args.length > 0) configfile = args[0]; System.out.println(); System.out.println("=== Install-Toolkit DemoApp "+VERSION+" ==="); System.out.println(); System.out.println("Arguments: "+args.length); for (String arg : args) System.out.println("=> "+arg); 18 4 Erstellen von Installationspaketen System.out.println(); System.out.println("Config File: "+configfile); System.out.println(); Properties p = new Properties(); p.load(new FileInputStream(new File(configfile))); System.out.println(); System.out.println("DemoApp says: "+p.getProperty("message")); System.out.println(); BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); in.readLine(); } Die Java-Klassen der Anwendung werden in einer JAR-Datei demoapp.jar gepackt. Hinzu kommt noch eine Textdatei manual.txt, die stellvertretend für die Anwenderdokumentation steht. Der Build-Prozess ist so aufgebaut, dass alle beim Build erzeugten Dateien im Unterverzeichnis target erzeugt werden. Die Java-Klassen werden im Verzeichnis target/classes kompiliert und schließlich in der Datei target/build/demoapp.jar gepackt. 19 4 Erstellen von Installationspaketen 4.2 Ein erstes Windows Installer Paket Unter Windows ist es üblich, dass der Benutzer bei der Installation einer Anwendung angeben kann, in welches Verzeichnis die Anwendung installiert werden soll. Die Auswahl erfolgt über einen Dialog des Install-Wizards. Alle Dateien (mit Ausnahme von Verknüpfungen im Startmenü und auf dem Desktop) werden innerhalb dieses Verzeichnisses abgelegt. Um die Erstellung des Installationspaketes vorzubereiten, kopiert das Build-Skript in dem Target „installer-win“ zunächst die Dateien der Anwendung DemoApp in das Verzeichnis target/installerwin. Die Verzeichnisstruktur entspricht dabei der Verzeichnisstruktur innerhalb des Installationsverzeichnisses. In diesem Fall wird das Startskript demoapp.bat sowie die Konfigurationsdatei demoapp.properties direkt in das Verzeichnis kopiert, das Archiv demoapp.jar in einen Unterordner lib und die Datei manual.txt in einen Unterordner doc. Die Struktur innerhalb von target/installer-win sieht schließlich folgendermaßen aus: demoapp.bat demoapp.properties lib/demoapp.jar doc/manual.txt 4.2.1 Installer Beschreibung Zum Erstellen des Installationspaketes benötigt das WiX Toolkit eine Beschreibungsdatei Setup.wxs, die zunächst einmal im Verzeichnis src/wix erstellt wird. Setup.wxs ist eine XML-Datei. Der Namespace „http://schemas.microsoft.com/wix/2003/01/wi“ ist vom WiX Toolkit vorgegeben. Das XML-Tag „Product“ unterhalb des Root-Tags „WiX“ definiert das zu installierende Produkt. Alle weiteren Informationen werden innerhalb des „Product“-Tags abgelegt. Das „Id“-Attribut des „Product“-Tags enthält einen Globally Unique Identifier (GUID) der das Produkt eindeutig identifiziert8. <?xml version="1.0" encoding="UTF-8"?> <Wix xmlns="http://schemas.microsoft.com/wix/2003/01/wi"> <Product Id="C4C79496-E1CA-4C8F-B7C4-7bA8171250C7" Name="DemoApp" 8 GUIDs werden auch bei „Package“-Tags sowie „Component“-Tags verwendet. Das Kapitel Erzeugen des Windows Installer Paketes geht näher auf die GUIDs ein. Zum Erzeugen einer GUID kann z.B. der Online Generator GuidGen [GGen] oder das im Microsoft Visual Studio integrierte Tool GuidGen verwendet werden. 20 4 Erstellen von Installationspaketen Language="1033" Version="1.0.0.0" Manufacturer="Christian Elberfeld" > </Product> </Wix> Innerhalb des Produktes wird zunächst eine Beschreibung des Installationspaketes als „Package“-Tag abgelegt. Diese Informationen sind sichtbar, wenn man sich die Details der MSIDatei ansieht. Auch das „Package“-Tag enthält in dem Attribut „Id“ eine GUID, mit der es eindeutig identifiziert wird. <Package Id="4619D250-D7BB-4bAE-957B-26AF69975936" Description="Java Application Installer Demo" Comments="Version: 1.0.0.0" Manufacturer="Christian Elberfeld" InstallerVersion="200" Compressed="yes" /> Die Abbildungen 4 und 5 zeigen die Darstellung der Eigenschaften des Installationspaketes im Windows Explorer. Abbildung 4: Ansicht des Installer Paketes im Explorer 21 4 Erstellen von Installationspaketen Abbildung 5: Dateiinformationen des Installer Paketes Zudem ist es notwendig festzulegen, von welchem Ort das Installationspaket die Dateien installieren soll. Der Windows Installer bietet hier unter anderem die Möglichkeit, die Dateien im gleichen Verzeichnis wie die MSI-Datei abzulegen oder mehrere CDs als Installationsmedien zu verwenden. Am einfachsten ist es allerdings, die Dateien mit in das Installationspaket zu packen. Der folgende Abschnitt innerhalb des „Product“-Tags legt eine Archivdatei fest, die in die MSIDatei integriert wird: <Media Id="1" Cabinet="product.cab" EmbedCab="yes"/> Mit Hilfe von „Directory“-Tags wird die Verzeichnishierarchie der zu installierenden Dateien beschrieben. Das oberste Verzeichnis „TARGETDIR“ ist das Verzeichnis, in das später die Anwendung installiert wird. Dieses Verzeichnis kann vom Benutzer im Verlauf der Installation festgelegt werden. Hierbei muss beachtet werden, dass der Windows Installer generell zu den MSDOS basierten Windows Versionen (Windows 95/98/ME) kompatibel ist und daher die Verzeichnis- und Dateinamen (das Attribut „Name“) dem 8.3 Format entsprechen müssen. Bei längeren Verzeichnis- und Dateinamen kann der lange Name mit dem Attribut „LongName“ angegeben werden. Ein 8.3 Dateiname muss jedoch zusätzlich angegeben werden. 22 4 Erstellen von Installationspaketen <Directory Id="TARGETDIR" Name="SourceDir"> <Directory Id="docdir" Name="doc"> </Directory> <Directory Id="libdir" Name="lib"> </Directory> </Directory> Innerhalb der Verzeichnishierarchie bilden Komponenten die einzelnen installierbaren Einheiten. Wie das „Product“-Tag enthält auch das „Component“-Tag im Attribut „Guid“ eine GUID, mit der die Komponente eindeutig identifiziert wird. Eine Komponente enthält dann die einzelnen Dateien, die installiert werden. Das Attribut „Vital“ gibt an, dass die Installation nur erfolgreich sein kann, wenn diese Datei auch wirklich installiert werden kann. Zudem kann pro Komponente eine Datei als „KeyPath“ markiert werden. Die KeyPath-Datei wird bei einer Reparaturinstallation überprüft. Sollte die KeyPath-Datei fehlen, wird die Komponente dann neu installiert. Da pro Komponente nur eine Datei als KeyPath markiert sein kann, empfiehlt es sich, jede Datei in einer eigenen Komponente unterzubringen. <Component Id="DemoApp_bat" Guid="417CD339-AE7C-41BA-B80B-B9BE0E20060A" DiskId="1" > <File Id="DemoApp_bat" Name="da.bat" LongName="DemoApp.bat" KeyPath="yes" Vital="yes" /> </Component> 23 4 Erstellen von Installationspaketen Die Komponenten wiederum werden zu installierbaren Einheiten, den Features, verknüpft. Ein Feature ist die installierbare Einheit, die im Install Wizard zur Installation ausgewählt werden kann (s. Abbildung 6). Auch wenn diese Auswahl nicht vorgesehen ist, muss mindestens ein Feature vorhanden sein. Abbildung 6: OpenOffice.org Installer - Auswahl von Programmkomponenten Features werden in dem „Feature“-Tag innerhalb des „Product“-Tags definiert. Innerhalb des „Feature“-Tags sind die Referenzen auf die zu installierenden Komponenten, sowie „Feature“-Tags von untergeordneteren Features enthalten. Eine Komponente kann hierbei durchaus in mehreren Features enthalten sein. Um die Installer-Erzeugung einfacher zu halten, soll hier auf verschachtelte Features verzichtet werden. <Feature Id="fature1" Title="DemoApp" Description="DemoApp" TypicalDefault="install" Display="expand" Level="1" > <ComponentRef Id="DemoApp_bat"/> </Feature> 24 4 Erstellen von Installationspaketen Das Zusammenspiel von Features und Komponenten lässt dich am Beispiel OpenOffice [OO] grafisch darstellen: – Komponente „c_writer“: OpenOffice.Org Writer – Komponente „c_impress“: OpenOffice.Org Impress – Komponente „c_spell“: Rechtschreibprüfung – Feature „f_writer“: OpenOffice.Org Writer benötigt „c_writer“ und „c_spell“ – Feature „f_impress“: OpenOffice.Org Impress benötigt „c_impress“ und „c_spell“ Die Komponente „c_spell“ wird installiert, wenn entweder das Feature „f_writer“, das Feature „f_impress“ oder beide Features installiert werden. Wird später eines der beiden Features deinstalliert bleibt die Komponente erhalten. Abbildung 7 zeigt die Abhängigkeiten der Komponenten als grafische Darstellung. Feature: „f_impress“ Feature: „f_writer“ Komponente: „c_writer“ Komponente: „c_spell“ Komponente: „c_impress“ Abbildung 7: Windows Installer - Features und Komponenten Zu guter letzt muss für das Installationsverzeichnis noch ein Standardwert gesetzt werden. Hierzu wird eine „CustomAction“ benötigt, die die variable TARGETDIR auf einen Wert setzt, wobei (in eckigen Klammern angegeben) wiederum andere Variablen referenziert werden können. Diese „CustomAction“ wird dann in die „InstallExecuteSequence“ und die „InstallUISequence“ eingefügt. 25 4 Erstellen von Installationspaketen <CustomAction Id="SET_TARGETDIR" Property="TARGETDIR" Value="[ProgramFilesFolder]\[ProductName]" Execute="firstSequence" /> <InstallExecuteSequence> <Custom Action="SET_TARGETDIR" Before="CostInitialize">TARGETDIR=""</Custom> </InstallExecuteSequence> <InstallUISequence> <Custom Action="SET_TARGETDIR" Before="CostInitialize">TARGETDIR=""</Custom> </InstallUISequence> Zu diesem Zeitpunkt enthält der Installer allerdings noch keine Definition einer Benutzeroberfläche. Bei der Installation ist lediglich ein Fenster mit einem Fortschrittsbalken zu sehen. 4.2.2 Erstellen des Installer-Paketes Um das Installer-Paket zu erstellen, kopiert das Build-Skript die Setup.wxs in das Verzeichnis target/installer-win und führt dort den WiX Compiler candle.exe aus, der die Objektdatei Setup.wixobj erzeugt. Anschließend wird der WiX Linker light.exe ausgeführt, der aus der Objektdatei Setup.wixobj die MSI-Datei target/DemoApp.msi erstellt und die zu installierenden Dateien mit einbindet. candle Setup.wxs light -out ../DemoApp.msi Setup.wixobj 26 4 Erstellen von Installationspaketen 4.3 Ein erstes DEB-Paket Beim Debian Projekt ist es üblich, dass es für jedes Paket einen Paketbetreuer (Maintainer) gibt, der das Debian Paket für eine Anwendung betreut. Dieser Maintainer ist in vielen Fällen eine andere Person als der Entwickler der Anwendung. Die Werkzeuge zum Erstellen von DEB Paketen berücksichtigen diesen Umstand, indem alle zum Erstellen des Paketes erforderlichen Zusatzinformationen in einem Unterverzeichnis debian abgelegt werden. Der Maintainer kann diese Informationen pflegen und gegebenenfalls (sofern er die Zugriffsrechte dafür besitzt) in die Versionsverwaltung der Anwendung einchecken. Da der Maintainer oft nicht der Entwickler der Anwendung ist, gehen die DEB-Werkzeuge desweiteren davon aus, dass der Maintainer den Sourcecode der Anwendung heruntergeladen und in ein Verzeichnis mit dem Namen <Paketname>-<Versionsnummer> entpackt hat. Die Paketerstellung erfolgt in den meisten Fällen dann mit dem Werkzeug dpkg-buildpackage, das in dem Verzeichnis gestartet wird. dpkg-buildpackage führt dann das Makefile debian/rules aus, das die Anweisungen enthält, mit denen die Anwendung compiliert und installiert wird, wobei das Verzeichnis debian/tmp als RootVerzeichnis für die Installation angenommen wird. Anschließend werden von der debian/rules Makefile verschiedene Skripte aus dem Debhelper-Paket ausgeführt die unter anderem MD5Summen für die in dem Paket enthaltenen Dateien berechnen. Als letztes Debhelper-Skript dh_builddeb aufgerufen, welches das DEB-Paket erstellt und im übergeordneten Verzeichnis ablegt. 4.3.1 Vorbereitung Auf Linux/Unix Systemen werden, im Unterschied zu Windows, Anwendungsdateien in festgelegten Verzeichnissen installiert. – Ausführbare Dateien, in diesem Fall das Startskript für DemoApp, werden in dem Verzeichnis /usr/bin/ installiert. – Dateien, die nur von der Anwendung selbst benötigt werden, werden üblicherweise im Verzeichnis /usr/share/<Anwendungsname>/ abgelegt. In diesem Fall ist das die Datei demoapp.jar. – Konfigurationsdateien werden üblicherweise in /etc/ installiert. Das trifft für die Datei demoapp.properties zu. – Die Dokumentation, in diesem Fall die /usr/share/doc/<Anwendungsname>/ abgelegt. manual.txt, wird in dem Verzeichnis Um das Erstellen des Paketes vorzubereiten, kopiert das Target „installer-deb“ des Ant-Skriptes zunächst die Dateien in das Unterverzeichnis target/installer-deb. In diesem Verzeichnis werden die Dateien so angeordnet, dass von target/installer-deb ausgehend die Pfade denen auf dem Zielsystem ausgehend vom Root-Verzeichnis entsprechen. 27 4 Erstellen von Installationspaketen Die Struktur innerhalb von target/installer-deb ist jetzt: usr/bin/demoapp usr/share/demoapp/demoapp.jar usr/share/doc/demoapp/manual.txt etc/demoapp.properties 4.3.2 Erstellen der Dateien im Verzeichnis debian Im Verzeichnis target/installer-deb/debian müssen jetzt die Steuerdateien für das DEB-Paket erstellt werden. Diese Dateien sollen später aus der Installer-Beschreibung erzeugt werden. 4.3.2.1 control Die debian/control Datei enthält die Metainformationen für das Paket. Das Format der Datei ist: Name: Wert. – Source: demoapp Name des ursprünglichen Paketes. Sofern die Anwendung nicht aus mehreren DEB-Paketen besteht, ist das der Name des Paketes. – Section: contrib/misc Paketsektion, der das Paket in der Paketliste zugeordnet wird. Verfügbare Hauptsektionen sind „main“ (wenn das Paket frei ist und nur von freier Software abhängt), „contrib“ (wenn das Paket selber frei ist, aber von unfreier Software abhängt) und „non-free“ (wenn das Paket selber nicht frei ist).9 Verfügbare Untersektionen sind: „admin“, „base“, „comm“, „devel“, „doc“, „editors“, „electronics“, „embedded“, „games“, „gnome“, „graphics“, „hamradio“, „interpreters“, „kde“, „libdevel“, „libs“, „mail“, „math“, „misc“, „net“, „news“, „oldlibs“, „otherosfs“, „perl“, „python“, „science“, „shells“, „sound“, „tex“, „text“, „utils“, „web“, „x11“. – Priority: optional Das Feld Priority gibt an wie wichtig das Paket für das Gesamtsystem ist. Sofern es sich nicht um systemwichtige Software handelt, sollte „optional“ verwendet werden. Die Prioritäten sind in der Debian-Policy [DP] im Kapitel 2.5 beschrieben. 9 Die Zuordnung zu den Hauptsektionen ist in der Debian-Policy [DP] festgelegt. Welche Software frei ist, ist in dem Debian Gesellschaftsvertrag [DSC] festgelegt. 28 4 Erstellen von Installationspaketen – Maintainer: Christian Elberfeld <[email protected]> Name und Email Adresse des Paketbetreuers. Das Format ist der Debian-Policy [DP] im Kapitel 2.5.6 auf das RFC822 [RFC:822] Format festgelegt. Dieser Eintrag kann aus dem Herstellernamen und der Email aus der Installer-Beschreibung generiert werden. – Package: demoapp Der Name des Paketes wie in der Installer-Beschreibung vorgegeben. Kapitel 5.6.7 der DebianPolicy [DP] schreibt vor, dass der Paketname nur aus Kleinbuchstaben, Zahlen sowie den Zeichen „+“, „-“ und „.“ bestehen darf. Gegebenenfalls muss der Paketname aus der Installer Beschreibung in Kleinbuchstaben umgewandelt werden. – Architechture: all Prozessorarchitektur, auf der die Anwendung lauffähig ist. Bei Java-Anwendungen kann generell „all“ verwendet werden, wenn die Anwendung keine nativen Bibliotheken enthält. Sollte die Anwendung auch native Bibliotheken enthalten ist es notwendig für jede Prozessorarchitektur, die unterstützt werden soll, ein eigenes Paket zu erstellen. Die verfügbaren Architekturen sind in der Debian-Policy [DP] im Kapitel 11.1 beschrieben. – Depends: bash, java2-runtime Liste von Paketen, von denen dieses Paket abhängt. Die Liste ist durch Kommata getrennt und enthält den Paketnamen und optional eine Versionsangabe. Das Paket „bash“ wird generell für Startskripte benötigt. „java-runtime“, „java2-runtime“ sind virtuelle Pakete, die durch eine beliebige Java 1.1 bzw 1.2 kompatible Runtime bereitgestellt werden. Wird Java 5.0, bzw speziell die Sun Implementierung benötigt, so können hier die Pakete „j2re1.5“ bzw „sunj2re1.5“ referenziert werden. Es ist auch möglich die Version des Paketes, von denen dieses Paket abhängig ist, näher zu spezifizieren. Die Versionsnummer wird in Klammern zusammen mit einem Vergleichsoperator angegeben. Das Kapitel 7.1 der Debian-Policy [DP] listet die verschiedenen Möglichkeiten auf. – Recommends, Suggests Liste von Paketen, die zur Installation empfohlen (recommends) bzw. vorgeschlagen (suggests) werden. Diese Pakete werden nicht zwingend benötigt, damit die Anwendung ausgeführt werden kann. Der Syntax der Angaben entspricht dem Feld „Depends“. – Description: Java Application Installer Demo Kurzbeschreibung des Paketes (eine Zeile). Die ausführliche Beschreibung folgt dieser Zeile, wobei jede Zeile mit einem Leerzeichen beginnt. 29 4 Erstellen von Installationspaketen 4.3.2.2 changelog Die Debian-Policy [DP] schreibt für das DEB-Paketformat eine Liste mit Änderungen an der Anwendung vor. Bei Paketen der offiziellen Debian Distribution [Debian] wird diese Datei automatisiert ausgewertet, um gelöste Bugs zu erkennen. Das Format der changelog-Datei ist in der Debian-Policy [DP] im Kapitel 4.4 beschrieben. Wenn die Änderungen an der Software anderweitig protokolliert werden, kann hier eine DummyDatei erzeugt werden, die folgenden Inhalt hat: demoapp (1.0.0.0) unstable; urgency=low * Autogenerated Package -- Christian Elberfeld <[email protected]> Thu, 02 Feb 2006 21:36:44 +0100 Die erste Zeile muss unter anderem Paketname und Versionsnummer enthalten. Die letzte Zeile muss Name und Email-Adresse des Paketbetreuers sowie Datum der Änderung im RFC822 Format [RFC:822] enthalten. 4.3.2.3 copyright In der Datei debian/copyright wird die Lizenz der Anwendung hinterlegt. Diese Datei wird bei der Installation des Paketes in dem Verzeichnis /usr/share/doc/<Paketname>/ komprimiert abgelegt. 4.3.2.4 compat Die Datei compat gibt an, mit welcher Version der Debhelper-Skripte das Paket erstellt werden soll. Der Inhalt der Datei ist „5“für Version 5 der Debhelper-Skripte. Die Debhelper-Skripte geben eine Warnung aus, wenn eine andere Version verwendet wird. 30 4 Erstellen von Installationspaketen 4.3.2.5 Maintainer-Skripte Die optionalen Maintainer Skripte preinst, postinst, prerm und postrm können als Shell-Skripte beliebige Befehle enthalten, die beim Installieren und Deinstallieren des Paketes auf dem System ausgeführt werden. Ausführlichere Informationen zu den Maintainer-Skripten enthält die DebianPolicy [DP] im Kapitel 6. – preinst: wird bei der Installation oder einem Update ausgeführt, bevor die Dateien aus dem Paket kopiert werden. – postinst: wird bei der Installation oder einem Update ausgeführt, nachdem die Dateien aus dem Paket kopiert wurden. – prerm: wird bei der Deinstallation oder einem Update ausgeführt, bevor die Dateien aus dem Paket gelöscht werden. – postrm: wird bei der Installation oder einem Update ausgeführt, nachdem die Dateien aus dem Paket gelöscht wurden. Wichtig bei den Maintainer-Skripten ist, dass das Skript mit der Zeile „exit 0“ endet, da ein Rückgabewert, der größer null ist, angibt, dass ein Fehler aufgetreten ist. In diesem Fall wird die Installation abgebrochen. Auch sollte die Zeile „#DEBHELPER#“ enthalten sein, da die Debhelper-Skripte hier eventuell noch zusätzliche Befehle einfügen (s. Kapitel Bau der DEB-Pakete). 31 4 Erstellen von Installationspaketen 4.3.3 Bauen des DEB-Paketes Normalerweise wird zum Bauen des Paketes „dpkg-buildpackage“ verwendet, das allerdings eine zusätzliche Steuerdatei target/rules benötigt. dpkg-buildpackage kopiert alle Dateien im Verzeichnis target/installer-deb in das Unterverzeichnis debian/tmp und führt dann eine Reihe von Debhelper-Skripten aus. Die Debhelper-Skripte passen unter anderem die Dateirechte an und übertragen die Steuerdateien aus debian/ in debian/tmp/DEBIAN. Als letztes Debhelper-Skript erstellt „dh_buildpackage“ das DEBPaket. Beim Erstellen des Paketes muss beachtet werden, dass die Debhelper-Skripte einige Operationen an Dateien durchführen, die nur für den Benutzer root erlaubt sind (z.B. Ändern des Dateibesitzers auf den Benutzer root). Um die Erstellung des Paketes auch für Benutzer ohne root-Rechte zu ermöglichen, kann das Tool fakeroot [Froot] verwendet werden, dass den damit ausgeführten Programmen eine Umgebung mit root-Rechten simuliert. Das erzeugte Paket hat den in der Debian-Policy „<Paketname>_<Version>_<Prozessorarchitektur>.deb“. [DP] festgelegten Dateinamen Soll das Paket, sofern es plattformabhängige Komponenten enthält, für eine andere Prozessorarchitektur als die des aktuellen Rechners erstellt werden, verweigern die DebhelperSkripte ihren Dienst.10 In diesem Fall muss der Aufruf der Debhelper Skripte mit Hilfe des Kommandos dpkg-architekture -a<Architektur> -c <Kommando> gekapselt werden. Eine Liste der möglichen Prozessorarchitekturen, kann mit dpkg-architekture -L abgerufen werden. Weitere Informationen hierzu bietet die Manpage von dpkg-architekture. 10 Dieses Problem tritt auf, wenn z.B. ein Paket mit Zielplattform „i386“ auf einem AMD64-Rechner erstellt werden soll. Ist die Zielplattform „all“, tritt dieses Problem nicht auf. 32 4 Erstellen von Installationspaketen 4.3.4 Installieren des DEB-Paketes Am einfachsten kann das Paket direkt mit dem Debian Paketmanager mit dem Befehl “dpkg -i <Paketname.deb>“ installiert werden. In diesem Fall werden allerdings keine Abhängigkeiten zu anderen Paketen aufgelöst. Fehlen benötigte Pakete, so wird die Installation verweigert. Um auch die Auflösung der Paketabhängigkeiten nutzen zu können, muss das Paket dem Advanced Package Tool (APT)11 bekannt gemacht werden. Hierzu wird in dem Verzeichnis, in dem sich das erzeugte Paket befindet, mit dem Befehl dpkg-scanpackages ./ /dev/null | gzip > Packages.gz eine Paketliste („Packages.gz“) erzeugt. Durch Eintragen der Zeile deb file:/home/chris/demoapp/target ./ in die Datei /etc/apt/sources.list werden die Pakete aus der Paketliste dem APT bekannt gemacht. Durch Aufruf von „apt-get update“ liest APT die verfügbaren Paketlisten neu ein. Das Paket kann jetzt mittels „apt-get install demoapp“ installiert werden. Stehen aktuellere Versionen bereit, so wird das Paket beim Aufruf von „apt-get upgrade“ automatisch mit aktualisiert. Anstelle der APT-Befehle kann auch ein grafisches Frontend wie synaptic [Sapt] verwendet werden. Die Abbildungen 8 bis 12 zeigen die Ansicht des Paketes in dem Frontend synaptic. Insbesondere die in der control-Datei definierten Eigenschaften sind in der Eigenschaften-Ansicht wiederzuerkennen. 11 Das Advanced Package Tool (APT) ist auch für das Herunterladen von Paketen aus dem Internet verantwortlich. 33 4 Erstellen von Installationspaketen Abbildung 8: synaptic - demoapp im nicht installierten Zustand 34 4 Erstellen von Installationspaketen Abbildung 9: synaptic - Eigenschaften (allgemein) von demoapp Abbildung 10: synaptic - Eigenschaften (Abhängigkeiten) von demoapp 35 4 Erstellen von Installationspaketen Abbildung 11: synaptic - Eigenschaften (Beschreibung) von demoapp Abbildung 12: synaptic - demoapp im installierten Zustand (Update verfügbar) 36 4 Erstellen von Installationspaketen 4.3.5 Prüfen des Paketes mit lintian Die Debian Distribution hat recht umfangreiche Richtlinien, wie die Dateien einer Anwendung auf einem System installiert bzw. verteilt werden sollen. Die Vorgaben macht wie bei den Konfigurationsdateien auch hier die Debian-Policy [DP], die sich maßgeblich am Filesystem Hierachy Standard [FHS] orientiert. Das Werkzeug lintian [Lintian] unterstützt Debian-Entwickler, indem es DEB-Pakete gegen die Vorgaben der Debian-Policy prüft und Abweichungen anzeigt. Mit dem Kommando lintian <Paketdatdei> wird das Paket geprüft. Mit dem Parameter -i gibt lintian bei jeder Abweichung von der DebianPolicy einen kurzen Text zur Erklärung mit Verweis auf die Debian-Policy aus. 37 4 Erstellen von Installationspaketen 4.4 Java Laufzeitumgebung und Startskripte Zum Ausführen einer Java-Anwendung ist eine Java-Laufzeitumgebung notwendig. Bei der Verwendung von DEB-Paketen kann die benötigte Java-Laufzeitumgebung als Paketabhängigkeit deklariert werden. Der Debian Paketmanager prüft bei der Installation, ob das entsprechende Paket bereits installiert ist und installiert es, falls es noch nicht installiert und verfügbar ist, automatisch mit. Als etwas problematisch stellt es sich dar, dass die Java-Laufzeitumgebung von SUN nicht in der Debian Distribution enthalten ist, da die Lizenz von SUN entsprechend den Richtlinien des Debian Projektes nicht frei genug ist. Mit dem Paket „java-package“ steht allerdings ein Werkzeug zur Verfügung, dass aus dem Download des JDK bzw JRE von Sun12 ein DEB-Paket erstellt. Alternativ können auch die Pakete des Projektes Debian-Unofficial [DU] verwenden wo unter anderem diese DEB-Pakete der Java Laufzeitumgebung von SUN bereitgestellt werden. Durch den Eintrag der folgenden Zeile in der Datei /etc/apt/sources.list kann der Debian Paketmanager das Paket selbstständig bei Bedarf installieren: deb http://ftp.debian-unofficial.org/debian sarge main contrib non-free Wenn die Anwendung eine Java-5.0-Laufzeitumgebung13 benötigt, muss auf jeden Fall die Laufzeitumgebung von SUN installiert werden, da diese momentan die einzige vollständig Java-5.0 kompatible Laufzeitumgebung ist. In diesem Fall muss die eigene Anwendung direkt von dem entsprechenden Paket abhängen. Wird „nur“ eine Java-Laufzeitumgebung der Version 1.1 oder 1.2 benötigt, kann die Anwendung auch von dem Meta-Paket „java-runtime“bzw. „java2-runtime“ abhängen. Dieses Meta-Paket wird von einer beliebigen Java-Laufzeitumgebung bereitgestellt. Neben der Laufzeitumgebung von SUN gibt es hier noch die Laufzeitumgebung von IBM oder die freie Java VM Kaffee, um nur einige zu nennen. Ein Startskript für die Anwendung ist auf Linux-Systemen recht einfach gestaltet, da die ausführbare Datei „java“ sich in jedem Fall im Systempfad befindet. Alternativ kann auch der volle Pfad zu ausführbaren Datei „java“ verwendet werden, was auch ohne Probleme möglich ist, da der Pfad in dem Paket der Java-Laufzeitumgebung fest vorgegeben ist. Da das Startskript selber ein bash-Skript [BASH] ist, muss das Paket auch von dem Paket „bash“ abhängen. #!/bin/bash java -cp /usr/share/demoapp/demoapp.jar ↵ installtoolkit.demo.DemoApp /etc/demoapp.properties 12 Hierfür wird der Download der „Self Extracting File“ für Linux benötigt. Das Erstellen des Debian Paketes ist dann mit dem Befehl fakeroot make-jpkg <Dateiname> möglich. 13 Die Version 1.5 wurde von SUN in 5.0 umbenannt, um sich von dem Microsoft.NET Framework abzusetzen, das bereits in Version 2.0 vorliegt. Intern wird allerdings noch 1.5 als Versionsnummer verwendet. 38 4 Erstellen von Installationspaketen Auf Windows-Systemen ist die Erkennung der Java-Laufzeitumgebung nicht so einfach, da hier keine Abhängigkeit zwischen Paketen definiert werden. Zudem befindet sich die ausführbare Datei java.exe nicht im Pfad für ausführbare Dateien, so dass zusätzlich zur Existenz der JavaLaufzeitumgebung auch der Installationspfad, der unter Windows ja vom Benutzer frei gewählt werden kann, ermittelt werden muss. Der Windows Installer bietet hierfür die Möglichkeit, eine Suche in der Registry durchzuführen und diese Ergebnisse in einer Variable abzuspeichern. Das JDK bzw. JRE von SUN registriert sich bei der Installation in der Registry unterhalb des Registry-Schlüssels HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft. Für die Java Runtime ist der Installationspfad in dem Schüssel HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\1.4 bzw. HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\1.5 in der Eigenschaft „JavaHome“ abgelegt. Für das Development Kit analog unter HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Development Kit\1.4 bzw. HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Development Kit\1.5 in der Eigenschaft „JavaHome“. In der Setupbeschreibung wird die Variable mit einem „Property“-Tag Definiert. Das Attribut „Id“ bestimmt den Namen der Variable. Innerhalb des „Property“-Tags können „RegistrySearch“-Tags platziert werden, die verschiedene Stellen der Registry durchsuchen. Wird ein Wert gefunden, so wird die Variable mit dem entsprechenden Wert gesetzt. Die „RegistrySearch“-Tags werden in der angegebenen Reihenfolge abgearbeitet, so dass ein später gefundener Wert einen zuvor gefundenen Wert überschreibt. Das folgende Beispiel findet eine installierte Java 1.4 oder 1.5 Laufzeitumgebung, wobei Version 1.5 der Version 1.4 und das JDK dem JRE vorgezogen wird: <Property Id="JAVA_HOME"> <RegistrySearch Id="rs1" Type="raw" Root="HKLM" Name="JavaHome" Key="SOFTWARE\JavaSoft\Java Runtime Environment\1.4" /> <RegistrySearch Id="rs2" Type="raw" Root="HKLM" Name="JavaHome" Key="SOFTWARE\JavaSoft\Java Development Kit\1.4" /> 39 4 Erstellen von Installationspaketen <RegistrySearch Id="rs3" Type="raw" Root="HKLM" Name="JavaHome" Key="SOFTWARE\JavaSoft\Java Runtime Environment\1.5" /> <RegistrySearch Id="rs4" Type="raw" Root="HKLM" Name="JavaHome" Key="SOFTWARE\JavaSoft\Java Development Kit\1.5" /> </Property> Um einen Standardwert für die Variable festzulegen, muss wie bei der Variable TARGETDIR eine CustomAction definiert werden: <CustomAction Id="SET_JAVA_HOME" Property="JAVA_HOME" Value="[ProgramFilesFolder]" Execute="firstSequence" /> Zusätzlich zur Suche des Pfades der Java Laufzeitumgebung ist es sinnvoll, dem Benutzer diesen Pfad in einem Dialog anzuzeigen, damit der Pfad gegebenenfalls korrigiert werden kann. Um die Anwendung mit einem Startskript zu starten, muss dieser Pfad von dem Startskript ermittelt werden. Ein Zugriff auf die Registry oder eine Konfigurationsdatei ist aus einer BAT-Datei allerdings nicht ohne weiteres möglich. Es bietet sich daher an, den Pfad zur Java Laufzeitumgebung in einer Umgebungsvariable abzuspeichern. Angenommen der Pfad zur JavaLaufzeitumgebung ist in der Umgebungsvariable „JAVA_DemoApp“ gespeichert, könnte ein Startskript folgendermaßen aussehen: @ECHO OFF %JAVA_DemoApp%\bin\java.exe -cp lib\demoapp.jar ↵ installtoolkit.demo.DemoAppMain %* Es ist hier nicht möglich, die Umgebungsvariable „JAVA_HOME“ zu verwenden, da diese nach der Installation der Java Laufzeitumgebung auf Windows Systemen nicht gesetzt ist. Daher wird hier bei der Installation für die Anwendung eine eigene JAVA_HOME-Umgebungsvariable mit dem Namen „JAVA_DemoApp“ definiert. 40 4 Erstellen von Installationspaketen Die Umgebungsvariable kann bei der Installation gesetzt werden, indem eine Komponente erzeugt wird, die einen „Environment“-Tag enthält. Die Konfigurationsdatei wird dem Skript als Parameter übergeben und mittels „%*“ an die Anwendung weitergegeben. Auf Basis des zuvor über die Suche in der Registry ermittelten Pfades zur Java Laufzeitumgebung, die in der Variable JAVA_HOME gespeichert wurde, sorgt der folgende Codeabschnitt dafür, dass die Umgebungsvariable „JAVA_DemoApp“ bei der Installation angelegt wird. Zu beachten ist hierbei, dass der „Environment“-Tag innerhalb eines „Component“-Tags platziert werden muss, da eine Umgebungsvariable für den Windows Installer eine installierbare Komponente darstellt. <Component Id="CF8BADAB9_654C_427E_96B1_36F5718EAAF3" Guid="F127A151-E61E-4393-8FA5-0EDE39581107" DiskId="1" > <Environment Id="Java_Home" Name="JAVA_[ProductName]" Action="create" System="yes" Part="all" Value="[JAVA_HOME]" /> </Component> 41 4 Erstellen von Installationspaketen 4.5 Verknüpfungen im Startmenü Bei der Installation von Programmen ist es üblich, im Startmenü und eventuell auf dem Desktop Verknüpfungen (Shortcuts) zum Starten des Programmes anzulegen, falls es sich hierbei um eine Desktopanwendung handelt. 4.5.1 Windows Unter Windows ist das Anlegen der Verknüpfungen nicht sehr aufwendig, da es hier nur eine einheitliche grafische Benutzeroberfläche gibt. Der Windows Installer enthält hierfür die notwendige Funktionalität. In der Installer-Beschreibung wird eine Verknüpfung erzeugt, indem innerhalb des „File“-Tags ein „Shortcut“-Tag eingefügt wird, dass den angezeigten Namen der Verknüpfung in dem Attribut „LongName“ sowie einen 8.3 Dateinamen im Attribut „Name“ enthält. Das Attribut „Directory verweist auf das Verzeichnis, in dem die Verknüpfung angelegt werden soll. Optional kann noch das Attribut „Icon“ auf ein „Icon“-Tag verweisen, um der Verknüpfung ein Symbol zuzuordnen. <File .....> <Shortcut Id="demo_shortcut1" Directory="DesktopFolder" LongName="Start DemoApp" Name="demo" Icon="demoapp_icon" /> <Shortcut Id="demo_shortcut2" Directory="Start_Menue" LongName="Start DemoApp" Name="demo" Icon="demoapp_icon" /> </File> 42 4 Erstellen von Installationspaketen Damit die Verweise auf die Verzeichnisse innerhalb des Windows Installers auch aufgelöst werden können, ist es notwendig, die Verzeichnisse für den Desktop und das Startmenü zu definieren. So ist es auch möglich, innerhalb des Startmenüs Unterverzeichnisse anzulegen. Anhand der Id-AttributWerte „DesktopFolder“ und „ProgrammMenuFolder“ identifiziert der Windows Installer die Verzeichnisse und ersetzt den Pfad durch die entsprechenden Pfade auf dem lokalen System. Ob der Windows Installer hierfür die Desktop/Startmenü Pfade des installierenden Benutzers oder des Systembenutzers „All Users“14 verwendet wird mit der Variable „ALLUSERS“ gesteuert. Verknüpfungen auf dem Desktop bzw. im Startmenü des Benutzers „All Users“ werden bei allen Benutzern angezeigt. Durch <Property Id="ALLUSERS" Value="1"/> werden die Desktop- bzw. Startmenü- Verzeichnisse des Benutzers „All Users“ verwendet. <Directory Id="DesktopFolder" Name="Desktop" /> <Directory Id="ProgramMenuFolder" Name="PMenu"> <Directory Id="Start_Menue" Name="DemoApp" LongName="DemoApp" /> </Directory> Symbole für die Verknüpfungen werden mit „Icon“-Tags eingebunden. Die Icons werden beim Windows Installer nicht als Datei auf der Festplatte installiert, sondern in das Installer-Paket direkt eingebunden, wie dies auch bei Grafiken für die GUI der Fall ist (siehe Kapitel Eine GUI für den Installer). Das „Icon“-Tag wird daher auch innerhalb des „Fragment“-Tags und nicht innerhalb eines „Directory“-Tags platziert. Der Pfad ist daher relativ zu den Installer-Beschreibungsdateien. <Icon Id="demoapp_icon" src="demoapp.ico"/> Die Abbildungen 13 und 14 zeigen die Verknüpfungen für die Anwendung DemoApp auf dem Desktop und im Startmenü. Abbildung 13: Verknüpfung auf dem Windows Desktop 14 Einträge im Startmenü des Benutzers „All Users“ erscheinen im Startmenü aller Benutzer. 43 4 Erstellen von Installationspaketen Abbildung 14: Verknüpfung im Windows Startmenü 4.5.2 KDE, Gnome und andere Auf Linux-Systemen ist es nicht so leicht wie auf Windows eine Verknüpfung im Startmenü unterzubringen, da es hier keine einheitliche grafische Oberfläche gibt. Im Laufe der Zeit hat es sich gezeigt, dass die beiden vorherrschenden Oberflächen, KDE und GNOME, die Verwaltung der Verknüpfungen ähnlich organisierten, indem Dateien in einem zentralen Verzeichnis gesammelt wurden und jede Datei eine Verknüpfung enthielt. Die Freedesktop Organisation [FreeD], die Standards für Linux und grafische Oberflächen auf Linux entwickelt, hat diese Formate in der Desktop-Entry Spezifikation [FreeD:DE] zusammengeführt. Mit der Desktop-Basedir Spezifikation [FreeD:DB] hat die Freedesktop Organisation ebenfalls die Verzeichnisse, in denen die Verknüpfungsdateien liegen können, spezifiziert. Üblicherweise verwenden die Distributionen das Verzeichnis /usr/share/applications. Mit der Menu Spezifikation [FreeD:M] hat die Freedesktop Organisation die Standards erweitert, um den Aufbau einer einheitlichen Menü-Struktur zu ermöglichen. Hierfür wurde unter anderem das Format der Verknüpfungsdateien erweitert, um die Verknüpfungen in Kategorien einzuordnen. Eine Verknüpfungsdatei hat den Namen <Paketname>.desktop und enthält pro Zeile ein „Schlüssel=Wert“ Paar. In der ersten Zeile steht der Header „[Desktop Entry]“. Die Schlüssel „Name“ und „Comment“ geben einen kurzen Namen, der im Startmenü erscheint, und eine Kurzbeschreibung an, die als Popup erscheint, wenn sich der Mauszeiger über dem Eintrag 44 4 Erstellen von Installationspaketen befindet. Der Schlüssel „Icon“ definiert ein Icon für die Verknüpfung. Fehlt der Schlüssel „Icon“, so wird kein Icon angezeigt. Der Schlüssel „Terminal“ („true“ oder „false“) gibt an, ob die Anwendung in einem Konsolenfenster gestartet werden soll. Mit dem Schlüssel „Type“ wird festgelegt, dass diese Verknüpfung eine Anwendung (Wert: „Application“) aufruft. Der Schlüssel „Categories“ schließlich legt fest, in welchen Kategorien, also in welchen Ordnern des Startmenüs, die Verknüpfung angezeigt wird. Mögliche Werte sind z.B. „Office“ für Office-Anwendungen, „Utility“ für Dienst- oder Hilfsanwendungen oder „Application“ für Anwendungen, die in keine andere Kategorie passen. Es können auch mehrere Kategorien, durch „ ; “ getrennt, angegeben werden. Die möglichen Kategorien sind in [FreeD:M] im Anhang A beschrieben. Auf diese Art ist es möglich, zumindest für die beiden verbreitetsten grafischen Oberflächen unter Linux automatisch Links zu erstellen. Aber auch andere grafische Oberflächen nutzen zunehmend die Freedesktop Standards, um die Menüeinträge zu erzeugen. Xfce [Xfce] ist ein solches Beispiel. Eine Datei demoapp.desktop würde demnach folgendermaßen aussehen: [Desktop Entry] Name=DemoApp Comment=Start DemoApp Application Icon=/usr/share/demoapp/demoapp.xpm Exec=/usr/bin/demoapp Terminal=true Type=Application Categories=Utility Die Abbildungen 15 bis 17 zeigen die so erzeugte Verknüpfung im Startmenü von Gnome, KDE und Xfce. Abbildung 15: Verknüpfung im Xfce Startmenü 45 4 Erstellen von Installationspaketen Abbildung 17: Verknüpfung im KDE Startmenü Abbildung 16: Verknüpfung im GNOME Startmenü 46 4 Erstellen von Installationspaketen 4.6 Update der Anwendung Kritisch ist das Updaten der Anwendung. Während der Windows Installer hier recht komplexe Methoden bereitstellt, bei denen nur einzelne Teile der Anwendung ersetzt werden15, ersetzt der Debian Paketmanger immer die kompletten Pakete. Ein problematischer Punkt sind hierbei Konfigurationsdateien, die möglicherweise vom Benutzer angepasst wurden. Unter Windows werden Konfigurationsdateien meistens nicht vom Installer sondern erst von der Anwendung selbst angelegt und auch über diese bearbeitet. Diese Konfigurationsdateien liegen somit nicht im Zuständigkeitsbereich des Windows Installers und bleiben somit auch über Versionsupdates bzw. Deinstallationen hinaus erhalten. Daher gibt es im Windows Installer auch keine besondere Unterstützung für textbasierte Konfigurationsdateien im Anwendungsverzeichnis, die eventuell vom Benutzer verändert wurden. Allerdings gibt es auch hier durch das .NET Framework [NET] einen Trend zu textbasierten Konfigurationsdateien16. Unter Linux/Unix hingegen sind textbasierte Konfigurationsdateien sehr verbreitet. In den meisten Fällen werden diese Dateien mit einem Texteditor bearbeitet. Der Debian Paketmanager bietet daher eine gesonderte Unterstützung für diese Konfigurationsdateien. In einer zusätzlichen Datei debian/conffiles.ex können alle Dateien, die gesondert geprüft werden sollen, aufgeführt werden. Das Dateiformat ist eine Datei mit vollem Pfad pro Zeile z.B: /etc/demoapp.properties. Bei jeder dieser Dateien wird geprüft, ob diese Datei vom Benutzer verändert wurde. Wurde diese Datei verändert, so wird der Benutzer bei einem Update gefragt, ob die alte Version dieser Datei erhalten bleiben oder die Version aus dem neuen Paket installiert werden soll17. Diese Abfrage erscheint nur dann, wenn die Konfigurationsdatei in dem Paket sich zwischen den Versionen geändert hat. Abbildung 18 zeigt eine solche Abfrage in dem Frontend synaptic. Abbildung 18: synaptic - Ersetzen der Konfigurationsdatei beim Update bestätigen 15 Der Windows Installer kann neben Installer Paketen auch Patches verarbeiten, die nur die entsprechenden Teile der Anwendung ersetzten. 16 Das .NET Framework bietet eine umfangreiche Unterstützung für XML basierte Konfigurationsdateien, die im gleichen Verzeichnis wie die ausführbare Datei befinden und dem gleichen Name mit einer zusätzlichen Endung „.config“ haben. 17 Der Benutzer kann sich auch die Unterschiede zwischen den Dateien als Unified-Diff anzeigen lassen 47 4 Erstellen von Installationspaketen Auch bleiben diese Dateien bei der Deinstallation des Paketes erhalten18. Es ist daher auf Debian Systemen möglich, z.B. einen FTP-Server bei Nichtgebrauch zu deinstallieren. Wenn der FTPServer wieder gebraucht wird, muß lediglich das Paket wieder installiert werden und der FTPServer ist sofort wieder einsatzbereit. Um ein Update der Installationspakete zu ermöglichen, ist es notwendig, dass die Versionsnummer für jedes erzeugte Paket erhöht wird. Soll das Paket bei Build der Anwendung automatisch mit erzeugt werden, muss also bei jedem Build eine neue Versionsnummer generiert werden. Das DEBPaket ist dann bereits updatefähig. Eventuell müssen hier noch Konfigurationsdateien in der Datei debian/conffiles.ex definiert werden. Für das Windows Installer Paket ist bis zur Updatefähigkeit etwas mehr Arbeit notwendig. Zunächst einmal muss dem „Product“-Tag der Installer-Beschreibung das Attribut „UpgradeCode“ hinzugefügt werden, dass für alle Versionen des Produktes gleich bleibt und somit die zusammengehörigen Pakete und Versionen identifiziert. Jetzt müssen die „Id“-Attribute des „Product“-Tags und des „Package“-Tags geändert werden, um zu kennzeichnen, dass es sich um ein anderes Installationspaket handelt. Das Versions-Attribut des „Package“-Tags muss natürlich auch angepasst werden. Um dem Windows Installer mitzuteilen, dass nach älteren Versionen dieser Anwendung gesucht werden soll, wird unterhalb des „Product“-Tags ein „Upgrade“-Tag eingefügt. In das Attribut „Id“ wird der UpgradeCode aus dem „Product“-Tag eingefügt. Innerhalb des „Upgrade“-Tags wird mittels „UpgradeVersion“-Tags definiert, welche Versionen der Anwendung aktualisiert werden können: <Upgrade Id="8356006A-EF32-4651-91FF-2B6B65C78560"> <UpgradeVersion IncludeMinimum="yes" Minimum="0.0.0.0" Property="OLDERFOUND"/> <UpgradeVersion IncludeMinimum="yes" Minimum="1.1.0.0" Property="NEWERFOUND"/> </Upgrade> Der erste „UpgradeVersion“-Tag sucht nach älteren Versionen, der zweite nach neueren Versionen. Werden ältere oder neuere Versionen gefunden, werden die Variablen „OLDERFOUND“ bzw. „NEWERFOUND“ gesetzt. Mittels einer CustomAction-Fehlermeldung kann ein Downgrade verhindert werden. Diese CustomAction erzeugt eine Fehlermeldung, wenn die Variable „NEWERFOUND“ gesetzt wurde: <CustomAction Id="NoDowngrade" Error="A later version of [ProductName] is already installed." /> <InstallExecuteSequence> 18 Der Debian Paketmanager bietet eine zusätzliche Option an, die bei der Deinstallation auch die Konfigurationsdateien entfernt. 48 4 Erstellen von Installationspaketen <Custom Action="NoDowngrade" After="FindRelatedProducts"><![CDATA[NEWERFOUND]]></Custom> </InstallExecuteSequence> Die „InstallExecuteSequence“ muss jetzt noch um die folgenden Eintrage erweitert werden, um die Suche nach anderen Produktversionen durchzuführen („FindRelatedProducts“), ein Update auf die neue Version durchzuführen („MigrateFeatureStates“) und um die alte Version zu deinstallieren („RemoveExistingProducts“): <InstallExecuteSequence> <MigrateFeatureStates/> <FindRelatedProducts/> <RemoveExistingProducts Before="InstallValidate"/> </InstallExecuteSequence> Das Windows Installer Paket ist jetzt updatefähig. Allerdings werden alle Dateien, die von dem Paket der alten Version installiert wurden, bei der Installation der neuen Version entfernt und durch die Version des neuen Paketes ersetzt. Um für Konfigurationsdateien das Verhalten des Debian Paketmanagers nachzuahmen können die Komponenten, die die Konfigurationsdateien enthalten, mit dem zusätzlichen Attribut „Permanent“ (Wert: "yes") als permanent markiert werden, was verhindert, dass diese Dateien bei einer Deinstallation gelöscht werden. Jetzt muss lediglich noch verhindert werden, dass die Konfigurationsdateien durch die neue Version überschrieben werden. Hierzu wird den Komponenten, die die Konfigurationsdateien enthalten, noch ein weiteres Attribut „NeverOverwrite“ (Wert: „yes“) hinzugefügt, das bewirkt, dass diese Datei nicht überschrieben wird, falls sie schon existieren sollte. Ebenso wie Dateien werden auch Registry-Einträge beim Deinstallieren der alten Version entfernt und durch den Installer neu gesetzt. Die Informationen, die erhalten bleiben sollen, müssen zuvor mittels Registry-Suche in eine Variable gelesen werden. In diesem Fall sind das konkret die Einträge für das Installationsverzeichnis und für das vom Benutzer eventuell bei der alten Version geänderte Verzeichnis für die Java Laufzeitumgebung. 49 4 Erstellen von Installationspaketen 4.7 Eine GUI für den Installer Pakete des Debian Installers besitzen keine eigenständige GUI. Die Installation wird vollständig von einem Tool wie apt-get (Kommandozeile) oder synaptic (grafisch) durchgeführt. Abbildung 19 zeigt den Verlauf einer Paketinstallation mit apt-get. Abbildung 19: Installation von demoapp mit apt-get Im Gegensatz dazu definiert ein Windows Installer Paket die GUI des Install-Wizards selber. Die einfachste Variante kann ein Windows Installer Paket sein, dass keine eigene Oberfläche besitzt. Bei der Installation erscheint dann lediglich ein Fenster mit einem Fortschrittsbalken. Eine solche Installation kann unter anderem für Systembibliotheken verwendet werden, die in ein festes Verzeichnis wie C:\WINDOWS\System32\ installiert werden. Abbildung 20 zeigt die Installation eines Windows Installer Paketes, dass keine GUI definiert. Abbildung 20: Windows Installer ohne GUI 50 4 Erstellen von Installationspaketen 4.7.1 Eine Standard GUI Üblich ist allerdings, dass die Installation durch eine Abfolge von Dialogen gesteuert wird, die dem Benutzer unter anderem die Softwarelizenz anzeigen und die Möglichkeit geben, das Installationsverzeichnis auszuwählen. Um eine GUI für den Windows Installer nicht komplett selber erstellen zu müssen, bietet das WiX Toolkit drei vorgefertigte Benutzeroberflächen an, die in den Installer eingebunden werden können: – Minimal: Eine minimale GUI, die lediglich die Lizenzbedingungen anzeigt und danach die Installation startet. – Featuretree: Eine Standard-GUI mit Willkommensseite, Anzeige der Lizenzbedingungen sowie Auswahl der Programmkomponenten und des Installationspfades. – Mondo: Eine erweiterte GUI, die zusätzlich zum Umfang der Featuretree-GUI noch die Auswahl verschiedener Installationsarten (Minimal, Standard und Benutzerdefiniert) erlaubt. Da der hier erzeugte Installer nicht aus verschiedenen Programmkomponenten besteht, macht es keinen Sinn die Mondo-GUI zu verwenden. Da der Benutzer allerdings die Möglichkeit haben soll, den Installationspfad zu ändern, kann auch die Minimal-GUI nicht verwendet werden, da hier der Dialog zur Auswahl des Installationspfades nicht enthält. Die Featuretree-GUI ist daher die am besten geeignete Variante. Durch Einfügen von einer UI-Referenz unterhalb des „Product“-Tags in der Installer-Beschreibung wird die Benutzeroberfläche mit eingebunden: <UIRef Id="WixUI" /> Zusätzlich muss beim Linken die entsprechende GUI-Bibliothek des WiX-Toolkits und eine Sprachdatei mit angegeben werden. Die Auswahl der Bibliothek entscheidet darüber welche der GUIs eingebunden wird (angenommen im Verzeichnis %WIX_PATH% ist das WiX Toolkit zu finden): light -out ../DemoApp.msi Setup.wixobj %WIX_PATH%\lib\wixui_featuretree.wixlib -loc %WIX_PATH%\lib\WixUI_en-us.wxl Die Sprachdatei WixUI_en-us.wxl enthält alle Texte, die die GUI verwendet. Durch Übersetzung dieser Datei ist es möglich, einen Installer in anderen Sprachen zu erstellen. Es ist zu erwarten, dass in absehbarer Zeit auch Sprachdateien in weiteren Sprachen vom WiX-Toolkit bereit gestellt werden. Zudem erwartet der WiX Linker eine Datei License.rtf mit dem Lizenztext, der im Installer angezeigt werden soll sowie einen Ordner Bitmaps, der die benötigten Bitmaps für die Dialoge des Installers enthält. Diese können selber erstellt oder aus dem WiX Toolkit entnommen werden. 51 4 Erstellen von Installationspaketen 4.7.2 Erweiterung der GUI Was der GUI jetzt noch fehlt, ist eine Anzeige des Pfades, der für die Java-Laufzeitumgebung gefunden wurde und die Aufforderung an den Benutzer, diesen Pfad zu prüfen und eventuell zu korrigieren. Das WiX-Tutorial [Wix:Tut] beschreibt die notwendigen Schritte um der GUI weitere Dialoge hinzuzufügen. Zunächst einmal müssen die neuen Dialoge entworfen werden. Neben dem Dialog zur Anzeige des Pfades für die Java-Laufzeitumgebung wird noch ein Dialog für die Auswahl des Verzeichnisses benötigt, der erscheint, wenn der Benutzer auf den Browse-Button klickt. Beide Dialoge werden als WiX-Fragment-Dateien erstellt und können eigenständig bearbeitet werden. Mit dem Tool WiX Edit [WixEdit] existiert ein freier Editor, mit dem die Dialoge grafisch bearbeitet werden können (die „$(loc.XXX)“ Anzeigen sind die Verweise auf die Datei mit den Texten). Abbildung 21 zeigt den Java.Dialog in dem Editor WiX Edit. Abbildung 21: Der Java-Dialog in WiX Edit 52 4 Erstellen von Installationspaketen Als nächstes wird eine Kopie der Datei src\ui\wixui\featuretree\WixUI_FeatureTree.wxs erstellt und angepasst. In dieser Datei werden die globalen Variablen gesetzt, die unter anderem die Abfolge der Dialoge festlegen. Um den Dialog für die Anzeige der Java-Laufzeitumgebung einzubinden, ist es am besten, den Dialog zwischen dem Customize-Dialog (Auswahl der Komponenten und des Installationspfades) und dem VerifyReady-Dialog (letzter Dialog vor Beginn der Installation) zu platzieren. Vom Customize-Dialog (Auswahl der zu installierenden Komponenten) muss also die Variable für den nächsten Dialog auf den Java-Dialog gesetzt werden und der Java-Dialog ruft beim Anklicken des Weiter-Buttons („next“) den VerifyReady-Dialog auf. Entsprechend müssen auch die Variablen für die Zurück-Buttons („back“) gesetzt werden. Standardabfolge der Dialoge der Featuretree-GUI (sofern nicht anders angegeben erscheint der nächste Dialog bei Betätigung des weiter-Buttons)19: nicht installiert bereits installiert Maintenance Dialog Welcome Dialog ändern View License Dialog Browse Dialog browse Customize Dialog reparieren oder entfernen Verify Ready Dialog (Remove oder Repair) Verify Ready Dialog (Install) Abbildung 22: Featuretree-GUI Standardabfolge der Dialoge 19 Hier wurde bewusst auf eine Darstellung als Flussdiagramm verzichtet, um die Darstellung übersichtlicher zu halten. 53 4 Erstellen von Installationspaketen Abfolge der Dialoge mit dem eingefügten Java-Dialog (Ausschnitt von Abbildung 22): Browse Dialog Java Browse Dialog browse browse Customize Dialog Java Dialog Verify Ready Dialog (Install) Abbildung 23: Der eingefügte Java-Dialog Gemeinsam mit dem Sourcecode der WiX-UI Dialoge kann die erweiterte GUI jetzt zu einer WiXBibliothek kompiliert werden. Hierzu wird der Library-Compiler (lit.exe) des WiX-Toolkits verwendet. Die folgenden Aufrufe erstellen die neue GUI-Bibliothek, die anstelle der WixUIBibliothek verwendet werden kann (der Sourcecode von WiX ist unter %WIX_SRC% zu finden): candle wixui_java.wxs JavaDlg.wxs BrowsejavaDlg.wxs ↵ %WIX_SRC%\src\ui\wixui\Common.wxs %WIX_SRC%\src\ui\wixui\CancelDlg.wxs .... lit -out wixui_java.wixlib wixui_java.wixobj JavaDlg.wixobj .... 54 4 Erstellen von Installationspaketen 4.8 Bedingungen beim Windows Installer Der Windows Installer bietet die Möglichkeit, vor der Installation verschiedene Bedingungen zu prüfen. Hierfür werden „Condition“-Tags (innerhalb des „Product“-Tags) verwendet. Das Attribut „Message“ gibt die Fehlermeldung an, die ausgegeben wird, wenn die Bedingung nicht erfüllt ist. Die Bedingung selbst steht als Text innerhalb des Tags. Kapitel 5.3 des WiX Tutorials [Wix:Tut] gibt eine Übersicht über mögliche logische Ausdrücke, die hier verwendet werden können. Hierbei sollte beachtet werden, dass die Ausdrücke nicht die XML-Syntax verletzen. Insbesondere die spitzen Klammern („<“ und „>“) für Vergleiche können zu Problemen führen. Diese Zeichen können entweder durch passende Entitäten ersetzt werden („&lt;“ statt „<“), oder der Ausdruck wird als CDATA-Abschnitt eingefügt. Wenn die Bedingung nicht logisch wahr ist, wird die Installation mit der angegebenen Fehlernachricht abgebrochen. Die folgenden Bedingungen lassen eine Installation nur auf Systemen ab Windows NT und als Benutzer mit Administrationsrechten zu. Hierbei werden die vordefinierten Variablen „Privileged“ und „VersionNT“ verwendet. Die Texte werden wie bei der GUI aus der Sprachdatei übernommen. <Condition Message="$(loc.ErrorNoAdministrator)">Privileged</Condition> <Condition Message="$(loc.ErrorNoWindowsNT)">VersionNT &gt; 400</Condition> 55 5 Automatisierung der Installer-Erstellung als Toolkit 5 Automatisierung der Installer-Erstellung als Toolkit Nachdem im vorherigen Kapitel der Grundstein für die Erzeugung eines Installers für die Anwendung DemoApp gelegt wurde, soll dieser Vorgang nun so weit wie möglich automatisiert werden damit eine solche Installer-Erzeugung auch für andere Anwendungen leicht durchführbar ist. Hierbei soll die Erzeugung soweit wie möglich in den bereits existierenden Build-Prozess integriert werden, um den zusätzlichen Aufwand möglichst gering zu halten. Es bietet sich daher an, das im Java-Umfeld sehr beliebte und verbreitete Build-Werkzeug Apache Ant [Ant] als Basis zu verwenden, und mit eigenen Tasks zu erweitern. Dieses Toolkit wird im Verlauf der Arbeit erstellt. Mit Abschluss der Arbeit auf der Open Source Plattform SourceForge [SF] als Projekt „installtoolkit“ unter den Bedingungen der Lesser Gnu Public License [LGPL] freigegeben. Die URL des Projektes lautet: http://sourceforge.net/projects/install-toolkit. Durch die Bedingungen der LGPL steht das Toolkit mit der Freigabe allen interessierten Personen zur Verfügung. 5.1 Apache Ant Apache Ant wurde als Alternative zum dem verbreiteten Build-Werkzeug make (und diversen Abkömmlingen) entwickelt, um ein Build-Werkzeug bereit zu stellen, dass besonders auf die Bedürfnisse von Java-Applikationen und deren Entwicklung ausgerichtet ist. Ant ist in Java implementiert und damit genau so plattformunabhängig wie Java selbst. Im Gegensatz zu make sind die Build-Dateien von Ant XML-basiert. Ein Ant-Build besteht aus verschiedenen Targets, die wiederum von anderen Targets abhängen können, wobei ein Target meistens für eine bestimmte Aufgabe zuständig ist, wie z.B. Kompilieren der Sourcen oder Packen der Klassen in ein Jar-Archiv. Ant sorgt bei der Ausführung der Targets dafür, dass diese in der richtigen Reihenfolge entsprechend ihrer Abhängigkeiten ausgeführt werden. Ein Target führt verschiedene Aktionen in Form von Tasks aus. Ein Task kann eine einfache Aktion wie das Kopieren einer Datei sein oder auch eine komplexe Aktion wie das Ausführen von JUnit Tests. Durch das Erstellen eigener Tasks kann Ant leicht erweitert werden. 5.1.1 Eigene Ant Tasks erstellen Ein Ant Task wird immer von genau einer Java-Klasse implementiert, die von der generischen Klasse org.apache.ant.Task abgeleitet ist. Diese Klasse muss den Java-Bean Richtlinien [Bean] entsprechen und für jedes Attribut des Tasks entsprechende Setter-Methoden definieren. Wenn die Setter-Methoden einen anderen Parameter-Typ als String besitzen, versucht Ant den Parameter automatisch zu konvertieren. Soll der Task innere Tags enthalten, so sind entsprechende addXXX()Methoden (mit passenden Parametern) oder createXXX()-Methoden (mit passendem Rückgabewert) erforderlich. Zum Ausführen von Aktionen muss schließlich die Methode execute() überschrieben werden. Um Ant die neuen Tasks bekannt zu machen, gibt es den Task „taskdef“. Dieser lädt die Tasks 56 5 Automatisierung der Installer-Erstellung als Toolkit entweder aus einer Properties-Datei im Jar-Archiv oder Name und Klasse werden als Attribut angegeben. Analog gibt es noch den Task „typedef“, mit dem Klassen für innere Tags definiert werden. 5.1.2 Ein einfacher Ant Task Für einen einfachen Ant Task der Form <target name="sometarget"> <mytask parameter=“somevalue“/> </target> wird die folgende Klasse MyTask benötigt (die Darstellung der Klasse Task ist zugunsten der Übersichtlichkeit gekürzt): Abbildung 24: Die Klasse „MyTask“ 57 5 Automatisierung der Installer-Erstellung als Toolkit Damit dieser Task im Build-Skript verwendet werden kann, muss er noch mittels „taskdef“ definiert werden (vorausgesetzt, die kompilierten Klassen befinden sich im Klassenpfad): <taskdef name="mytask" classname="sample.MyTask"/> Alternativ kann die Deklaration der Ant-Tasks auch in einer Properties-Datei im Klassenpfad abgelegt werden. Hier werden die Deklarationen in der Form Name=Klasse abgelegt. Durch Laden der Datei mittels taskdef werden dann alle in der Datei enthaltenen Tasks geladen: <taskdef resource="tasks.properties"/> 5.1.3 Ein Ant Task mit inneren Tags Für einen mit einem inneren Tag „files“ wird eine createFiles()-Methode benötigt. Der innere Tag „files“ ist eine Pfadstruktur, daher muss die createFiles()-Methode ein Objekt vom Typ org.apache.tools.ant.types.Path zürückgeben. Abbildung 25: Die Klasse MyTask2 58 5 Automatisierung der Installer-Erstellung als Toolkit Verwendet wird der Task wie folgt: <taskdef name="myothertask" classname="sample.MyTask2"/> <target name="sometarget"> <myothertask> <files> <fileset dir="src"/> <fileset dir="data"/> </files> </myothertask> </target> 59 5 Automatisierung der Installer-Erstellung als Toolkit 5.1.4 Einen Ant Task innerhalb eines Ant Tasks aufrufen Es besteht auch die Möglichkeit, innerhalb eines Ant Tasks einen anderen Ant Task zu erzeugen und auszuführen. Die Parameter, die sonst als Attribute oder innere Tags definiert werden, können dann direkt über die die setXXX(), addXXX() und createXXX() Methoden festgelegt werden. Dieses Vorgehen ist dann nützlich, wenn ein Task die Funktionalität eines anderen Tasks benötigt. Beispiel: package sample; import org.apache.tools.ant.*; public class MyTask3 extends Task { public void execute() throws BuildException { MyTask t = new MyTask(); mytask.setProject(getProject()); mytask.setParamaeter("someparam"); } } 60 5 Automatisierung der Installer-Erstellung als Toolkit 5.2 Ant Tasks als Wrapper für die verwendeten Tools Um einen komfortablen Zugriff auf die benötigten Tools zu erhalten, ist es sinnvoll, diese Tools jeweils mit einzelnen Tasks zu kapseln. So ist auch der direkte Zugriff auf diese Tools aus einem Build-Skript heraus möglich20. Diese Tasks können dann innerhalb der Generierung verwendet werden. 5.2.1 Tasks für das WiX Toolkit Die Tools des WiX Toolkits werden als Exe-Datei aufgerufen. Eine Möglichkeit wäre hier, den Task von dem bereits bestehenden Exec-Task abzuleiten. Dadurch würden aber auch alle Attribute und innere Tags übernommen, die der Exec-Task bereits anbietet. Durch ähnliche Namen oder Bedeutungen können so allerdings leicht Verwirrungen entstehen. Besser ist es, die Hilfsklassen Execute und CommandLine zu verwenden, mit deren Hilfe der Prozess ausgeführt werden kann. Alle Tasks benötigen eine Attribut „wixdir“, das den Pfad zum WiX Toolkit festlegt. Mit Hilfe dieses Pfades kann der absolute Pfad zu den .exe Dateien ermittelt werden. Dieser wird dann der Execute-Klasse mittels setExecutable() mitgeteilt und entspricht dem Attribut „executable“ des Exec-Tasks. Auch ist es notwendig, für die Tools das Verzeichnis festzusetzen, in dem der Prozess ausgeführt wird, da in diesem Verzeichnis Ausgabedateien geschrieben werden. Die Tasks nehmen dieses Verzeichnis über das Attribut „workdir“ an und übergeben es an die Klasse Execute mit der Funktion setWorkingDirectory(). Parameter, die allen Tools gemeinsam sind sind: -nologo (Herstellerinformationen nicht anzeigen), -wx (Warnungen als Fehler behandeln), -ust (kleine Tabellendefinitionen verwenden), -ss (nur die Eingaben validieren) sowie die Level für Warnungen (-w) und sonstige Ausgaben (-v) jeweils mit einer Zahl zwischen 0 und 3. Diese Parameter können über die Funktion createArg().setValue() der Klasse CommandLine gesetzt werden. Ebenso werden allen Tools eine Menge von Source oder Objektdateien übergeben, die verarbeitet werden sollen. Diese können über eine Pfad-Struktur mit dem Namen „files“ angegeben werden. Die Dateien der Pfad-Struktur werden beim Ausführen des Tools als Argumente an die Kommandozeile angehängt. Die Auswertung der Pfad-Struktur erfolgt mit der Methode this.files.list(), die ein String Array mit den Dateinamen zurückliefert, die dieser Pfad einschließt. Um diese Namen, die relativ zum Basisverzeichnis des Projektes sind, in java.io.File Objekte umzuwandeln, kann die Funktion this.getProject().resolveFile() verwendet werden. Insbesondere für den WiX-Compiler candle.exe ist es wichtig, dass für den Prozess Umgebungsvariablen gesetzt werden können. Ein Ausdruck wie „$(env.VARIABLE)“ im WiXSourcecode wird dann von dem Kompiler durch den Wert der Variable „VARIABLE“ ersetzt. Über die Funktion addEnv() des Tasks können Objekte vom Typ org.apache.tools.ant.types.Environment.Variable als „env“-Tags an den Task übergeben werden, die in einem Objekt von Typ org.apache.tools.ant.types.Environment gesammelt werden. Mit der 20 Diese Tasks werden unter anderem zum Erstellen des Toolkits benötigt. 61 5 Automatisierung der Installer-Erstellung als Toolkit Methode getVariables() wird dieses Objekt in ein String-Array umgewandelt, dass der ExecuteKlasse mittels setEnvironment() übergeben wird. Die „env“-Tags werden dabei genau so wie in dem Execute-Task verwendet. Über die execute()-Methode der Execute-Klasse wird schließlich die eigentliche Ausführung des Prozesses initiiert. Mittels Execute.isFailure() kann der Returnwert geprüft werden ob dieser, abhängig vom Standard des Betriebssystems, einen Erfolg oder Fehlschlag symbolisiert. Die Tasks für die Tools candle.exe, light.exe und lit.exe werden jeweils um zusätzliche Parameter ergänzt. Für light.exe ist desweiteren eine zusätzliche Pfad-Struktur für die Sprachdateien notwendig. 5.2.2 Tasks für die Debian Tools Die Debhelper-Skripte werden wie die WiX-Tools auch als Prozesse ausgeführt. Hier ist es allerdings etwas komplizierter, da die Debhelper-Skripte in einer fakeroot-Umgebung ausgeführt werden müssen, um normalen Benutzern die Möglichkeit zu geben, die Dateirechte anzupassen und auf den Besitzer der Datei zu ändern21. Sobald der fakeroot-Aufruf beendet wurde, sind alle Änderungen an den Dateien, die der Benutzer nicht hätte durchführen dürfen, verloren. Um das zu umgehen kann fakeroot die simulierte Umgebung abspeichern und beim nächsten Aufruf wieder laden. Für die Debhelper-Skripte wird daher ein Ant-Task benötigt, der die Debhelper Skripte in einer fakeroot-Umgebung ausführt. Dieser Task führt zunächst das Kommando fakeroot -s fakeroot.save exit aus, was dafür sorgt, dass die Fakeroot Umgebung initialisiert und in der Datei fakeroot.save gespeichert wird. Die Debhelper-Skripte werden dann nacheinander mittels fakeroot -i fakeroot.save -s fakeroot.save -- <Skriptname> <Parameter> ausgeführt. Um auch die Erstellung von Paketen für für andere Prozessorarchitekturen als die des aktuellen Systems zu ermöglichen, ist zusätzlich noch eine Kapselung des Aufrufs der Debhelper-Skripte mittels „dpkg-architecture“ erforderlich (siehe Kapitel. Bauen des DEB-Paketes). Diese Kapselung ist allerdings nur erforderlich, wenn die Prozessorarchitektur des Paketes nicht „all“ ist. Der Aufruf des Debhelper-Skriptes lautet folglich: fakeroot [...] -- dpkg-architecture -a<Architecture> <Skriptname> <Parameter> 21 Dateien die durch ein DEB-Paket installiert werden gehören normalerweise dem Benutzer „root“. 62 5 Automatisierung der Installer-Erstellung als Toolkit Als Parameter, die allen Debhelper-Skripten gemeinsam sind, werden -Pdebian/tmp (Arbeitsverzeichnis debian/tmp relativ zum Ausführungsverzeichnis) und -v (ausführliche Ausgaben). Beim letzten Debhelper-Skript dh_buildpackage, der das Paket zusammenbaut, wird noch ein zusätzlicher Parameter –destdir=<Verzeichnis> benötigt, der angibt, in welchem Verzeichnis das DEB-Paket abgelegt wird. Zum Ausführen der Kommandos werden wieder die Hilfsklassen CommandLine und Execute verwendet. Um die Abfolge der Debhelper-Skripte flexibel zu halten, werden diese über innere „dh“-Tags mit dem Attribut „name“ angegeben. Lediglich der Aufruf von dh_buildpackage zum Schluß ist festgelegt, da hier der zusätzliche Parameter „destdir“ gesetzt werden muß. Ein weiterer innerer Tag „command“ kann benutzt werden, um zusätzliche Befehle in der fakerootUmgebung auszuführen. Das kann unter anderem dann der Fall sein, wenn Dateiberechtigungen angepasst werden sollen (eine Datei ausführbar machen oder den Besitzer ändern), da der aktuelle Benutzer unter Umständen nicht die notwendigen Berechtigungen für diese Aktionen besitzt. Hierbei muß beachtet werden, dass der Befehl in dem srcdir-Verzeichnis ausgeführt wird. Die zu bearbeitenden Dateien befinden sich unterhalb des Verzeichnisses debian/tmp. Die Architektur des Paketes kann, wenn diese nicht „all“ ist, mit dem Parameter „architecture“ angegeben werden. Ein Aufruf kann dann folgendermaßen aussehen: <target name="debhelper"> <debhelper debug="false" srcdir="target/installer-deb" destdir="target" > <dh name="dh_testdir"/> <dh name="dh_testroot"/> <dh name="dh_installdirs"/> <dh name="dh_installchangelogs"/> <dh name="dh_installdocs"/> <dh name="dh_compress"/> <dh name="dh_fixperms"/> <dh name="dh_installdeb"/> <dh name="dh_gencontrol"/> <dh name="dh_md5sums"/> </debhelper> </target> 63 5 Automatisierung der Installer-Erstellung als Toolkit Um die erzeugten Pakete mittels apt-get oder anderen Frontends zu installieren, ist eine Paketliste notwendig, die im gleichen Verzeichnis liegt wie die Pakete. Das Erzeugen der Paketliste kann mit dem Kommando dpkg-scanpackages ./ /dev/null erzeugt werden. Die Ausgabe wird in eine Datei Packages.gz geschrieben, und mittels gzip [GZip] gepackt, um Platz und Bandbreite zu sparen. Der Befehl dpkg-scanpackages gibt die Paketliste über den Standard-Output Stream aus und kann, wie bei den Debhelper-Skripten, mit den Klassen CommandLine und Excecute ausgeführt werden. Um den Standard-Output nicht auf die Konsole auszugeben, sondern im Programm zu verarbeiten, muss der Task selber das Interface ExecuteStreamHandler implementieren und bei der ExcecuteKlasse mittels setStreamHandler(this) registriert werden. Über die Funktion setProcessOutputStream() wird der Output-Stream des Prozesses von der Execute-Klasse an den Task übergeben und in der Member-Variable „procoutstream“ gespeichert wird. Nachdem der Prozess ausgeführt wurde, aber bevor der Output-Stream gelöscht wird, wird die Funktion stop() aufgerufen. Der folgende Codeabschnitt liest den Output-Stream des Prozesses und und schreibt die Daten in den Stream der Variable „filestream“. Der FileStream wird zuvor als GZipOutputStream erzeugt, und in die Ausgabedatei geleitet wird. public void stop() { try { if (debug) handleOutput( ... ); int available = this.procoutstream.available(); while (available > 0) { if (debug) handleOutput( ... ); byte[] buffer = new byte[available]; int bytes = this.procoutstream.read(buffer); this.fileoutstream.write(buffer,0,bytes); available = this.procoutstream.available(); } if (debug) handleOutput( ... ); 64 5 Automatisierung der Installer-Erstellung als Toolkit this.fileoutstream.finish(); this.fileoutstream.close(); } catch (IOException e) { [ ... ] } } 65 5 Automatisierung der Installer-Erstellung als Toolkit 5.3 Installer-Metainformationen Um für die Informationen, die zum Erstellen der Installer-Pakete benötigt werden, einen Zentralen Speicherort zu definieren, bietet es sich an, diese Informationen in einer XML Datei abzulegen. Lediglich die Versionsnummer soll innerhalb des Ant-Skriptes als Property verwaltet werden, um so die Möglichkeit zu erhalten, dass die Versionsnummer mit jedem Build erhöht wird. Die benötigten Informationen für ein Windows Installer Paket sind: – Paket bzw. Anwendungsname – Ersteller des Paketes bzw. der Anwendung – Kurzbeschreibung (1 Zeile) – Softwarelizenz, die vom Installer angezeigt wird – Konfigurationsdateien – Upgradecode (Kapitel Update der Anwendung) – Desktop und Startmenü Verknüpfungen (Kapitel Verknüpfungen im Startmenü) Für das DEB-Paket sind die benötigten Informationen ähnlich: – Paket bzw. Anwendungsname – Ersteller des Paketes bzw. der Anwendung – email-Adresse des Paketerstellers – Kurzbeschreibung (1 Zeile) – Ausführliche Beschreibung (mehrere Zeilen) – Softwarelizenz (wird immer in der Datei /usr/share/doc/<Anwendungsname>/copyright abgelegt) – Konfigurationsdateien – Sektion und Priorität des Paketes – Depends, Recommends und Suggests Abhängigkeiten. – Verknüpfungen im Startmenü (Kapitel Verknüpfungen im Startmenü) Hierbei muss zwischen den Informationen, die vom konkreten Installer unabhängig sind, und den Informationen, die nur für einen Installer notwendig sind, unterschieden werden. Die vom Installer unabhängigen Informationen, also die Schnittmenge aus den oben angegebenen Punkten sind: Allgemeine Paketinformationen (Paketname und Paket- bzw. Anwendungshersteller), Kurzbeschreibung (eine Zeile), lange Beschreibung sowie der Lizenztext. Diese Informationen werden als Tags innerhalb des Root-Tags „Installer“ untergebracht. 66 5 Automatisierung der Installer-Erstellung als Toolkit <?xml version="1.0" encoding="UTF-8"?> <inst:Installer xmlns:inst="http://installtoolkit.sourceforge.net/InstallerDescription"> <Package Name="DemoApp" Manufacturer="Christian Elberfeld" Email="[email protected]" /> <Description> <Short>Java Application Installer Demo</Short> <Long> This Application demonstrates the automatic generation of Installers for Java Applications. </Long> </Description> <License> Software License for DemoApp DemoApp is distributed under the Terms of the GNU lesser Generall Public License. </License> </inst:Installer> Alle Windows Installer spezifischen Einstellungen werden innerhalb eines „Windows“-Tags untergebracht. Hierzu gehören der Upgradecode (im Attribut „Upgradecode“) sowie die Verknüpfungen für den Desktop und das Startmenü. Die Verknüpfungen werden als „Shortcut“-Tags definiert, jeweils mit den Attributen File (Dateiname relativ zu dem Verzeichnis, in dem die Verzeichnishierarchie aufgebaut wird), Name (Name der Verknüpfung) und optional Icon (Icondatei, der Pfad ist relativ zum Verzeichnis in dem die Installer-Beschreibung erzeugt wird). Die „Shortcut“-Tags werden entweder unterhalb eines „Desktop“-Tags, für DesktopVerknüpfungen, oder unterhalb eines „Startmenue“-Tags für Startmenü-Verknüpfungen, angelegt. Das „Startmenue“-Tag hat zudem noch ein optionales Attribut „Folder“, das einen Unterordner in Startmenü definiert. Auch die geschützten Konfigurationsdateien werden hier deklariert. Die Patterns der „Include“- und „Exclude“-Tags unterhalb des „Configfiles“-Tags werden wie Ant-Patterns in Ant-FileSets verwendet und werden relativ zum dem Verzeichnis ausgewertet, in dem die Verzeichnishierarchie aufgebaut wird. 67 5 Automatisierung der Installer-Erstellung als Toolkit <?xml version="1.0" encoding="UTF-8"?> <inst:Installer xmlns:inst="http://installtoolkit.sourceforge.net/InstallerDescription"> [ ... ] <Windows Upgradecode="8356006A-EF32-4651-91FF-2B6B65C78560"> <Configfiles> <Include>demoapp.properties</Include> </Configfiles> <Desktop> <Shortcut File="demoapp.bat" Name="Start DemoApp" Icon="demoapp.ico" /> </Desktop> <Startmenue Folder="DemoApp"> <Shortcut File="demaoapp.bat" Name="Start DemoappApp" Icon="demoapp.ico" /> </Startmenue> </Windows> </inst:Installer> Ebenso werden die für das DEB-Paket spezifischen Informationen in einem „Deb“-Tag hinterlegt. Hierzu gehören die Sektions- und Prioritätsangaben, jeweils als Attribute des „Deb“-Tags sowie die Depends- Recommends- und Suggestsangaben als eigene Tags innerhalb des „Deb“-Tags. Die Startmenü-Verknüpfungen können als „Startmenue“-Tags mit den Attributen Name, Comment, Command, Terminal („true“ oder „false“), Category und optional Icon angegeben werden. Die Architektur des Zielpaketes, sofern diese nicht „all“ ist, soll nicht in dem Metadaten abgelegt werden. Diese wird dem Task als Parameter übergeben, damit es möglich ist, innerhalb eines Build Pakete für mehrere Architekturen zu bauen (sofern das erforderlich ist). Die Deklaration der geschützten Konfigurationsdateien erfolgt analog zur Deklaration im Abschnitt für Windows Installer Einstellungen. <?xml version="1.0" encoding="UTF-8"?> <inst:Installer xmlns:inst="http://installtoolkit.sourceforge.net/InstallerDescription"> [ ...] <Deb Section="contrib/misc" Priority="optional"> <Depends>bash (>= 3.1), java2-runtime, sun-j2se5.0-jre-binary</Depends> <Recommends>sun-j2re1.5</Recommends> <Suggests></Suggests> 68 5 Automatisierung der Installer-Erstellung als Toolkit <Configfiles> <Include>etc/demoapp.properties</Include> </Configfiles> <Startmenue Name="DemoApp" Comment="Start DemoApp" Command="/usr/bin/demoapp" Terminal="true" Icon="/usr/share/demoapp/demoapp.xpm" Category="Utility" /> </Deb> </inst:Installer> Um die Validierung der XML-Beschreibung dem XML-Parser zu überlassen, kann das Format als XML-Schema formuliert werden. Zusätzlich wird das Erstellen der Beschreibung dadurch vereinfacht, dass ein geeigneter Editor das XML-Schema zur Autovervollständigung benutzen kann. Der Name „http://install-toolkit.sourceforge.net/InstallerDescription“ für den XMLNamespace leitet sich aus der URL der Projekthomepage ab. XML Schema der Installer Beschreibung (Auszug): <?xml version="1.0" encoding="UTF-8"?> <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://install-toolkit.sourceforge.net/InstallerDescription" xmlns:inst="http://install-toolkit.sourceforge.net/InstallerDescription"> <element name="Installer"> <complexType> <sequence minOccurs="1" maxOccurs="1"> <element name="PackageName" type="string" minOccurs="1" maxOccurs="1" /> [...] </complexType> </element> </schema> 69 5 Automatisierung der Installer-Erstellung als Toolkit Zur besseren Übersicht zeigen die Abbildungen 26 bis 28 das XML-Schema als grafische Darstellung. Abbildung 26 zeigt die Gesamtübersicht des XML-Schemas, wobei hier die den Elementen „Windows“ und „Deb“ untergeordneten Elemente ausgeblendet sind. Die Abbildungen 27 und 28 zeigen jeweils nur die Teilausschitte, die in Abbildung 26 ausgeblendet wurden. Die grafische Darstellung wurde mit dem XML-Schema Editor des eclipse Web Tools [WTP] Projektes aus dem Sourcecode des XML-Schemas erzeugt. Für die grafische Darstellung von XML-Schemata gibt es keine feste Darstellungsform wie UML. Daher zunächst eine kurze Übersicht über die Syntax der Darstellung: – XML-Elemente werden als Rechteck dargestellt. In der oberen Zeile steht der Name des Elementes. Die untere Zeile gibt den Typ des Elementes entsprechend XML-Schema an (z.B. „type=string“ bedeutet, dass der Inhalt des Elementes ein Text ist, „type=<anonymous>“ bedeutet, dass das Element leer ist oder ausschließlich andere XML-Elemente enthält). Sofern unterhalb des Rechteckes nicht angegeben ist, wie oft das Element vorkommen kann, erscheint es genau einmal. – Enthält ein XML-Element Attribute, so wird das durch ein „@“ neben dem Namen des Elementes gekennzeichnet. Attribute werden in dieser Darstellungsform nicht einzeln angezeigt. – Untergeordnete Elemente sind durch Linien mit dem übergeordneten Element verbunden (das übergeordnete Element steht links). Anstelle eines untergeordneten Elementes kann auch eine Sequenz von Elementen untergeordnet werden, was durch das Symbol dargestellt wird. Die Reihenfolge der untergeordneten Elemente entspricht dann der Darstellung von oben nach unten. Abbildung 26: Installer Metainformationen – XML-Schema 70 5 Automatisierung der Installer-Erstellung als Toolkit Abbildung 27: Installer Metainformationen – XML-Schema (Windows-Abschnitt) Abbildung 28: Installer Metainformationen – XML-Schema (DEB-Abschnitt) 71 5 Automatisierung der Installer-Erstellung als Toolkit 5.4 Verarbeitung der Installer-Metainformationen in einem Ant-Task Um die Erstellung von Ant-Tasks, die die eigentlichen Installer erstellen, zu erleichtern, wird zunächst eine abstrakte Klasse installtoolkit.InstallerGeneratorTask von der Klasse org.apache.tools.ant.Task abgeleitet. Dieser Task liest in der Funktion execute() zunächst die XMLDatei mit den Installer-Metainformationen ein und speichert die Werte in Member-Variablen der Klasse. Die Struktur der XML-Datei wird bereits vom XML-Parser gegen das XML-Schema aus dem Kapitel Installer-Metainformationen geprüft. Anschießend wird die als abstrakt definierte Funktion build() aufgerufen, die von der jeweils abgeleiteten Klasse implementiert wird, um die eigentliche Installer-Erstellung durchzuführen. Zum Parsen und Auslesen der XML-Datei wird Dom4J [Dom4J] verwendet. Um die Validierung der XML-Datei zu ermöglichen, muß dem Parser der Speicherort des XML Schemas über das Attribut „schema“ mitgeteilt werden. Alternativ kann auch über das Attribut „validate“ die Validierung deaktiviert werden, was allerdings zu Verarbeitungsfehlern führen kann, falls die XML-Datei nicht korrekt ist. 5.5 Erzeugen des Windows Installer Paketes Mit Ausnahme der Definition der zu installierenden Dateien, kann die Installer Beschreibung als „Skelett“ entsprechend der Angaben aus dem Kapitel Erstellen von Installationspaketen erstellt werden. Die veränderlichen Informationen wie Name, Hersteller und Version werden als Umgebungsvariablen ausgelagert, die dem Compiler bei der Erzeugung mit übergeben werden. Die Definition der Dateien bzw. der Verzeichnishierarchie, die installiert werden sollen, wird in eine externe Fragmentdatei ausgelagert, die auf Basis eines Verzeichnisses, das das zukünftige Installationsverzeichnis widerspiegelt, erzeugt wird (siehe Kapitel Die Dateiliste erzeugen ). Diese Templatedatei stellt alle Einstellungen für einen Standardinstaller bereit, kann aber gegebenenfalls angepasst werden. Zum Kompilieren und Linken der Dateien werden innerhalb des Ant-Tasks die Tasks aus dem Kapitel Tasks für das WiX Toolkit innerhalb des Ant-Tasks ausgeführt. Auch die Bitmaps und Icons für die GUI des Installers müssen noch gesammelt werden. Die verwendeten Teile der WiXUI (s. Kapitel Eine GUI für den Installer) erwarten diese als Dateien in einem Unterordner Bitmap mit den Dateinamen bannrbmp.bmp (oberer, meist weißer, Abschnitt der Dialoge), dlgbmp.bmp (Hintergrundbild des Willkommensdialogs), exclamic.ico (gelbes Warndreieck mit Rufzeichen, wird bei Fehlermeldungen verwendet), info.ico (weiße Sprechblase mit Rufzeichen, wird bei Hinweismeldungen angezeigt), New.ico (Symbol für den Button zum Erstellen eines neuen Ordners im Ordnerauswahl-Dialog), Up.ico (Symbol für den Button, der im Ordnerauswahl-Dialog in den nächst höheren Ordner wechselt). Diese werden unter Zuhilfenahme des Copy-Tasks in das passende Verzeichnis kopiert. Hierfür werden entweder eigene Dateien, die über entsprechende Attribute dem Task mitgeteilt wurden, oder die Standarddateien aus dem WiX-Toolkit verwendet. 72 5 Automatisierung der Installer-Erstellung als Toolkit Zudem wird noch der Lizenztext, der vom Installer angezeigt wird und vom Benutzer bestätigt werden muss, benötigt. Dieser muß als RTF-Datei License.rtf vorliegen. (siehe Kapitel Die Datei License.rtf erzeugen). Als Schrift wird standardmäßig „Tahoma“ (Größe 8) verwendet, die auch in den Installer-Dialogen benutzt wird. Eine Änderung dieser Parameter sowie die Verwendung einer eigenen Lizenzdatei ist mittels entsprechender Attribute möglich. Für die eigentliche Kompilation und Bindung der Dateien können jetzt die bereits vorbereiteten Ant-Tasks für CandleTask und LightTask aus dem Kapitel Tasks für das WiX Toolkit verwendet werden. Die IDs für das „Product“-Tag sowie die ID des „Package“-Tags und die GUIDs der „Component“-Tags der Installer-Beschreibung werden dem Compiler candle.exe als Umgebungsvariablen übergeben. Die hierfür notwendigen Globally Unique Identifier (GUIDs) bzw. Universally Unique Identifier (UUIDs)22 können mit der Klasse java.util.UUID über die Funktion randomUUID() erzeugt werden. Auch die restlichen Umgebungsvariablen für candle.exe werden hier gesetzt. 5.5.1 Die Datei License.rtf erzeugen Der Windows Installer benötigt für die Anzeige der Lizenzbedingungen eine Datei im Rich Text Format [RTF:Spec], um diese in den Dialog mit einzubinden. Diese Datei soll aus dem „License“-Tag der Installer-Metadaten erzeugt werden. Das RTF-Dateiformat selbst ist textbasiert, so dass die RTF-Datei direkt erzeugt werden könnte, wozu jedoch recht genaue Kenntnisse des RTF-Formats notwendig sind. Einfacher ist es, wenn man auf die Klasse javax.swing.text.rtf.RTFEditorKit des Swing-Frameworks von Java zurückgreift. Diese Klasse kann den Inhalt eines formatierten oder unformatierten Swing-Textfeldes in eine RTFDatei speichern. Der Inhalt des Swing-Textfeldes wird durch eine Klasse repräsentiert, die das Interface javax.swing.text.Document implementiert. In diesem Fall reicht es daher aus, eine Klasse vom Typ javax.swing.text.DefaultStyledDocument, die Document implementiert, zu erzeugen und mittels RTFEditorKit zu speichern. Mit der Funktion insertText() kann der Text in die Klasse DefaultStyledDocument geschrieben werden. Als zusätzlicher Parameter kann noch eine Instanz der Klasse javax.swing.text.SimpleAttributeSet mit übergeben werden, um Schrift und Größe des Textes festzulegen. Diese werden vorher mit den Funktionen der Klasse javax.swing.text.StyleConstants in das SimpleAttributeSet geschrieben. 22 Universally Unique Identifier (UUID) sind im RFC Nummer 4122 [RFC:4122] definiert. Wichtigste Eigenschaft einer UUID ist, dass jede erzeugte UUID eindeutig ist. Microsoft verwendet hierfür die Bezeichnung Globally Unique Identifier (GUID). Weitere Informationen zur Verwendung von UUIDs/GUIDs im Microsoft Installer und deren Erzeugung bietet [WI:Kerl] auf Seite 102 ff. 73 5 Automatisierung der Installer-Erstellung als Toolkit Die resultierende RTF-Datei aus der obigen Abbildung sieht im Quelltext wie folgt aus (Schriftart: Tahoma, Größe: 8): {\rtf1\ansi {\fonttbl\f0\fnil Monospaced;\f1\fnil Tahoma;} \f1\fs16\par Software License for DemoApp\par \par DemoApp is distributed under the Terms of the GNU lesser Generall Public License.\par \par\fs24\par } 5.5.2 Die Dateiliste erzeugen Die Erzeugung der Fragment-Datei mit der Dateiliste wird in einem eigenen Task FilesFragmentGeneratorTask untergebracht, so dass die Erzeugung auch unabhängig von der Installer-Erzeugung verwendet werden kann. Dieser Task wird bei der Erzeugung des WindowInstallers aufgerufen. Die Fragment-Datei für die Dateiliste ist ähnlich aufgebaut wie die Installer-Beschreibung. Anstelle des Root-Tags „Wix“ steht hier allerdings das Tag „Fragment“. Das Attribut Id des „Fragment“-Tags hat den gleichen Wert wie das Attribut Id des „FragmentRef“-Tags der InstallerBeschreibung, wodurch die Verbindung hergestellt wird. Innerhalb des „Fragment“-Tags gibt es ein „DirectoryRef“-Tag sowie ein „FeatureRef“-Tag, die über das Attribut „Id“ jeweils das entsprechende Verzeichnis bzw. Feature referenzieren. In diesem Fall sind das das Verzeichnis „TARGETDIR“ und das Feature „BASEFEATURE“. Alle innerhalb der „DirectoryRef“-Tags bzw. „FeatureRef“-Tags enthaltenen Elemente werden so behandelt, als würden sie in den referenzierten Tags enthalten sein. Nachdem die Grundstruktur der Fragment-Datei aufgebaut wurde, wird das Verzeichnis, das das Installationsverzeichnis widerspiegelt, rekursiv durchlaufen. Für jedes Verzeichnis wird entsprechend ein „Directory“-Tag erstellt. Für jede Datei wird innerhalb des „Directory“-Tags ein „Component“-Tag und darin ein „File“-Tag erzeugt. Außerdem wird innerhalb des „FeatureRef“-Tags die Komponente mittels eines „ComponentRef“-Tags referenziert. Für die Id-Attribute der „Component“-Tags und „File“-Tags werden sequentielle Nummern verwendet, deren Erzeugung von der Hilfsklasse IdGenerator übernommen wird. Zur Erzeugung der 8.3 Dateinamen, die zwar nicht benötigt werden, aber aus Kompatibilitätsgründen vorhanden sein müssen, wird die Hilfsklasse FilenameGenerator verwendet, die zwei sequentiell hochlaufende Zahlen von jeweils 8 bzw. 3 Ziffern zusammensetzt. Entsprechend dem Kapitel Update der Anwendung werden bei allen Konfigurationsdateien zusätzlich die Attribute "Permanent=yes" und "NeverOverwrite=yes" des umschließenden „Component“-Tags gesetzt. 74 5 Automatisierung der Installer-Erstellung als Toolkit 5.6 Erzeugen des DEB-Paketes Die Erzeugung des DEB-Paketes teilt sich in zwei Teilschritte auf: Erzeugung der Dateien im Verzeichnis debian und Bau des Paketes mit Hilfe der Debhelper-Skripte. Die Dateien im Verzeichnis debian werden entsprechend den Angaben im Kapitel Erstellen der Dateien im Verzeichnis debian erstellt. Falls über die Attribute des Tasks eigene Dateien vom Benutzer angegeben wurden, werden diese in das Verzeichnis kopiert. Für den Aufruf der Debhelper-Skripte, also die eigentliche Erstellung des Paketes, wird der DebhelperTask aus dem Kapitel Tasks für die Debian Tools aufgerufen. Hierbei werden folgende Debhelper-Skripte aufgerufen: – dh_testdir: Prüft, ob das Verzeichnis debian vorhanden ist – dh_testroot: Prüft, ob der Benutzer über root-Rechte verfügt23 – dh_installdirs: Erzeugt benötigte Unterverzeichnisse – dh_installchangelogs: Kopiert die changelog-Datei – dh_installdocs: Kopiert zusätzliche Dokumentationsdateien – dh_compress: Komprimiert einige Installationsdateien (z.B. Manpages) – dh_fixperms: Setzt korrekte Dateiberechtigungen24 – dh_installdeb: Kopiert die Maintainer-Skripte – dh_gencontrol: Erzeugt die control-Datei für das Paket aus debian/control – dh_md5sums: Berechnet Checksummen für die Dateien – dh_buildpackage: Erstellt das DEB-Paket Wenn der Task innere „dh“-Tags enthält, werden diese Debhelper-Skripte zwischen dh_md5sums und dh_buildpackage ausgeführt. Zudem soll die Möglichkeit angeboten werden, eigene Befehle gemeinsam mit den Debhelper-Skripten auszuführen. Die hierfür notwendigen „command“-Tags haben die gleiche Syntax wie beim Debhelper-Task aus dem Kapitel Tasks für die Debian Tools. Das Erzeugen der im Kapitel Verknüpfungen im Startmenü vorgestellten Verknüpfungsdateien kann in einen eigenständigen Ant-Task ausgelagert werden, der bei der Erzeugung des DEBPaketes mit aufgerufen wird. Dem StartmenueLinksTask werden das Ausgabeverzeichnis für die Verknüpfungsdateien sowie der Paketname als Attribut übergeben. Zudem werden die Verknüpfungen als innere Link-Tasks übergeben, deren Attribute mit denen der „Shortcut“-Tags der XML-Datei mit den Installer-Metainformationen entsprechen. Für jeden inneren „Link“-Tag wird eine Verknüpfungsdatei mit dem Namen <Packetname>_<laufende Nummer>.desktop im Ausgabeverzeichnis erzeugt. 23 Bei Verwendung von fakeroot hat der Benutzer in der fakeroot-Umgebung root-Rechte. 24 Alle installierten Dateien werden dem Benutzer root zugewiesen und alle Dateien unterhalb von /usr werden ausführbar gemacht. Zudem wird sichergestellt, dass jeder Benutzer die Dokumentationen lesen kann. 75 5 Automatisierung der Installer-Erstellung als Toolkit 5.7 Erstellung des Toolkits Um das Toolkit selbst zu erstellen, müssen die Ant-Tasks wie eine normale Java-Anwendung in ein Jar-Archiv kompiliert werden. Zudem muß noch die WiX-Bibliothek für die GUI des Installers kompiliert werden. Hierzu muss der Pfad zu dem WiX-Toolkit und zu den WiX-Sourcen bekannt sein, die als Variablen aus der build.properties ausgelesen werden. Sind diese Variablen nicht gesetzt, muss dieser Schritt übersprungen werden. Zum Kompilieren der WiX-Bibliothek werden die Tasks CandleTask und LitTask verwendet. Hierfür werden die Tasks aus dem bei der Kompilation erstellten, Jar-Archiv geladen. Das Toolkit selbst wird anschließend in ein Zip-Archiv gepackt, dass die folgenden Dateien enthält: – installer-toolkit.jar: Das Archiv mit den Ant-Tasks – dom4j.jar: Dom4J, wird von den Ant-Tasks benötigt – UI.wixlib: WiX-Bibliothek mit der GUI für den Installer – SetupTemplate.wxs: Template Datei für WiX Setups – Loc_en-us.wxl: Englische Texte für die GUI und das Setup – InstallerDescription.xsd: XML Schema für die Installer-Beschreibung – InstallerDescriptionsample.xml: Beispiel für eine Installer-Beschreibung 76 6 Erstellung von einfachen Installationspaketen 6 Erstellung von einfachen Installationspaketen Als Beispiel für eine einfache Anwendung soll jetzt noch einmal ein Installer für die Anwendung DemoApp erzeugt werden. Im Gegensatz zu dem Kapitel Erstellen von Installationspaketen wird jetzt das Toolkit aus dem Kapitel Automatisierung der Installer-Erstellung als Toolkit verwendet. 6.1 Installer Metainformationen Die Informationen aus dem Kapitel Erstellen von Installationspaketen lassen sich in einer XMLDatei entsprechend dem Kapitel Installer-Metainformationen zusammenfassen: <?xml version="1.0" encoding="UTF-8"?> <inst:Installer xmlns:inst="http://installtoolkit.sourceforge.net/InstallerDescription"> <PackageName>DemoApp</PackageName> <Manufacturer>Christian Elberfeld</Manufacturer> <Email>[email protected]</Email> <Description> <Short>Java Application Installer Demo</Short> <Long> This Application demonstrates the automatic generation of Installers for Java Applications. </Long> </Description> <License> Software License for DemoApp DemoApp is distributed under the Terms of the GNU lesser Generall Public License. </License> 77 6 Erstellung von einfachen Installationspaketen <WindowsInstaller> <UpgradeCode>8356006A-EF32-4651-91FF-2B6B65C78560</UpgradeCode> <Configfiles> <Include>demoapp.properties</Include> </Configfiles> <Desktop> <Shortcut File="demoapp.bat" Name="Start DemoApp" Icon="demoapp.ico" Workingdir="TARGETDIR" Arguments="[TARGETDIR]\demoapp.properties Desktop" /> </Desktop> <Startmenue Folder="DemoApp"> <Shortcut File="demoapp.bat" Name="Start DemoApp" Icon="demoapp.ico" Workingdir="TARGETDIR" Arguments="[TARGETDIR]\demoapp.properties Desktop" /> <Shortcut File="doc\manual.txt" Name="DemoApp Manual" /> </Startmenue> </WindowsInstaller> <DebPackage> <Section>contrib/misc</Section> <Priority>optional</Priority> <Depends>bash (>= 3.1), java2-runtime, sun-j2re1.5</Depends> <Recommends>sun-j2se5.0-jre-binary</Recommends> <Suggests></Suggests> 78 6 Erstellung von einfachen Installationspaketen <Configfiles> <Include>etc/demoapp.properties</Include> </Configfiles> <Startmenue Name="DemoApp" Comment="Start DemoApp" Command="/usr/bin/demoapp" Terminal="true" Icon="/usr/share/demoapp/demoapp.xpm" Category="Utility" /> </DebPackage> </inst:Installer> 6.2 Erstellen der Anwendung Das eigentliche Kompilieren der Anwendung erfolgt noch so wie im Kapitel Erstellen von Installationspaketen beschrieben. Für die nachfolgende Erzeugung der Installer-Pakete müssen jedoch noch zusätzliche Pfade dem Build-Skript bekannt gemacht werden, die von dem jeweiligen System abhängig sind. Es bietet sich daher an diese Pfade in der Datei build.properties auszulagern: – installer-toolkit.dir: Verzeichnis in dem das Installer Toolkit abgelegt ist. – wix.dir: Verzeichnis in dem das WiX Toolkit abgelegt ist Um eine automatisierte Versionierung der Builds zu erhalten, muss bei jedem Build die Versionsnummer inkrementiert werden. Mit dem buildnumber-Task bietet Ant bereits von Haus aus eine Unterstützung dafür an. Der buildnumber-Task liest eine Nummer aus der Datei build.number und speichert sie in der Variable „build.number“. Anschließend wird die Nummer inkrementiert und in die Datei build.number zurückgeschrieben. Wird diese Nummer an die letzte Stelle der Versionsnummer angehängt, so erhält jeder Build eine eigene Versionsnummer. Durch Löschen der Datei build.number kann die Revision wieder auf 0 zurückgesetzt werden, z.B. weil die Haupt- oder Unterversionsnummer verändert wurden. 79 6 Erstellung von einfachen Installationspaketen Hierbei ist zu beachten, dass der Windows Installer lediglich die ersten 3 Stellen der Versionsnummer auswertet. Damit ein Update als solches erkannt wird, muss sich mindestens eine dieser drei Stellen ändern. Die Revisionsnummer sollte daher an der dritten Stelle der Versionsnummer stehen (z.B. „1.2.80“ für Version 1.2 mit Revision 80). Das Target „init“ erzeugt eine passende Versionsnummer in der Variable „version“: <target name="init"> <buildnumber/> <property name="version" value="1.1.${build.number}"/> <echo>Building Version: ${version}</echo> </target> 6.3 Windows Installer Die Erzeugung des Windows Installers erfolgt in dem Target „installer-win“. Das Target erzeugt zunächst die Verzeichnishierarchie in dem Verzeichnis target/installer-win entsprechend dem Kapitel Erstellen von Installationspaketen. Hierfür werden hauptsächlich verschiedenen CopyTasks verwendet. Anschließend wird durch den Aufruf des Tasks „installer-win“, der durch die Klasse installtoolkit.WindowsInstallerTask implementiert wird, das Windows Installer Paket erzeugt. <target name="installer-win" depends="init"> <mkdir dir="target/installer-win"/> <mkdir dir="target/installer-win/lib"/> <mkdir dir="target/installer-win/doc"/> <mkdir dir="target/build-win"/> <copy todir="target/installer-win" file="demoapp.properties" /> [...] 80 6 Erstellung von einfachen Installationspaketen <mkdir dir="target/build-win"/> <installer-win descriptor="Installer.xml" schema="${installer-toolkit.dir}/InstallerDescription.xsd" destdir="target" workdir="target/build-win" srcdir="target/installer-win" version="${version}" wixdir="${wix.dir}" > <src> <fileset dir="${installer-toolkit.dir}"> <include name="SetupTemplate.wxs"/> </fileset> </src> <lib> <fileset dir="${installer-toolkit.dir}"> <include name="UI.wixlib"/> </fileset> </lib> <localisation> <fileset dir="${wix.dir}/lib"> <include name="WixUI_en-us.wxl"/> </fileset> <fileset dir="${installer-toolkit.dir}"> <include name="Loc_en-us.wxl"/> </fileset> </localisation> </installer-win> </target> 81 6 Erstellung von einfachen Installationspaketen 6.4 DEB-Paket Ebenso wie bei der Erzeugung des Windows Installers ist auch die Erzeugung des DEB-Paketes in zwei Targets aufgeteilt. Das Target „installer-deb“ erstellt auch hier zunächst die Verzeichnishierarchie in dem Verzeichnis target/installer-deb. Anschließend wird der Task „installer-deb“ ausgeführt, der durch die Klasse installtoolkit.DebianPackageTask implementiert wird. Dieser Task führt die eigentliche Erstellung des DEB-Paketes durch. Ein nachfolgender Aufruf des Tasks „packages“ erstellt eine Paketliste der DEB-Pakete im Verzeichnis target, so dass dieses Verzeichnis als Paketquelle von apt-get oder synaptic verwendet werden kann. <target name="installer-deb" depends="init"> <delete dir="target/installer-deb"/> <mkdir dir="target/installer-deb"/> <copy todir="target/installer-deb/usr/share/demoapp"> <fileset dir="target/build"/> </copy> [ ... ] <installer-deb descriptor="Installer.xml" schema="${installer-toolkit.dir}/InstallerDescription.xsd" destdir="target" workdir="target/installer-deb" version="${version}" /> <packages workdir="target" /> </target> 82 7 Erstellung von komplexen Installationspaketen 7 Erstellung von komplexen Installationspaketen Mit dem Toolkit Installer für einfache Anwendungen wie die Beispielanwendung „DemoApp“ zu erstellen, kann bereits für einen Teil der real existierenden Anwendungen ausreichen25. Allerdings sind viele real existierende Anwendungen um ein vielfaches komplexer als diese Beispielanwendung. Eine solche Anwendung benötigt auch einen Installer, der an die jeweiligen Anforderungen angepasst ist. Als Beispiel wird hier der JBoss Application Server [JB] betrachtet werden. Der erzeugte Installer soll nicht nur den Application Server auf die Festplatte kopieren, was auch durch Entpacken des ZIP-Archives möglich wäre, sondern den Server dabei auch in das System integrieren, so dass dieser als Systemdienst gestartet werden kann. Zudem soll der Server seine Logmeldungen, zusätzlich zu den Standard-Logdateien, an das Log-System des Betriebssystems weitergeben. Auf Linux/Unix Systemen ist das üblicherweises der Syslog-Daemon, dessen Netzwerkprotokoll im [RFC:3164] dokumentiert ist. Auf Windows hingegen ist seit Windows NT das Eventlog das Standard-Logsystem. Dieses Kapitel zeigt anhand dieser Anforderungen, wie die von dem Toolkit erzeugten Installer an die jeweiligen Anforderungen angepasst bzw. erweitert werden können. 7.1 Der JBoss Application Server Der JBoss Application Server [JB] wird von der JBoss Inc. [JBI] entwickelt. JBoss selbst ist unter der GNU Lesser General Public License [LGPL] als Open Source Software lizensiert. Als kommerzielles Unternehmen verdient JBoss Inc. durch Supportverträge und Schulungsangebote sowie Zertifizierungen rund um den JBoss Application Server. Der JBoss Application Server ist unter anderem dadurch bekannt geworden, dass er im Juli 2004 als erstes Open Source Produkt die J2EE-Zertifizierung von Sun Microsystems [SUN] für Java Enterprise Application Server erhalten hat. In der Standardversion wird der JBoss Application Server als Zip-Archiv ausgeliefert, das lediglich auf dem lokalen Rechner entpackt werden muss. Der JBoss Application Server ist dann bereits in einer Standardkonfiguration einsatzbereit. 25 Als Beispiel kann hier die Java-Entwicklungsumgebung eclipse [eclipse] genannt werden. Hier werden lediglich die Dateien der Anwendung in ein Verzeichnis kopiert. 83 7 Erstellung von komplexen Installationspaketen Die Verzeichnisstruktur des JBoss unterteilt sich in folgende Verzeichnisse, wie in Abbildung 29: – Startdateien Im Verzeichnis bin liegen die Batch- bzw Shell-Skripte sowie die run.jar und shutdown.jar. Diese Dateien werden in jedem Fall benötigt, um JBoss zu starten. Alle anderen Komponenten können alternativ auch mit dem Netboot-Feature26 von JBoss über das Netzwerk von einem zentralen Server geladen werden. – Basisbibliotheken Im Verzeichnis lib befinden sich die Java Bibliotheken, die benötigt werden, um den Server zu starten. – Clientbibliotheken Im Verzeichnis client befinden sich die Bibliotheken, die eine Clientanwendung benötigt, um mit dem JBoss Server zu kommunizieren. – Dokumentation und Beispiele Das Verzeichnis doc enthält Dokumentation und Beispiele für den JBoss Server. – Serverkonfigurationen Im Verzeichnis server gibt es für jede Serverkonfiguration ein Verzeichnis, dessen Name den Namen der Serverkonfiguration angibt. Die standard-Serverkonfiguration trägt den Namen "default". Eine Serverkonfiguration ist in die folgenden Verzeichnisse unterteilt: – Konfiguration Das Verzeichnis conf enthält die Basiskonfigurationsdateien für die Serverkonfiguration. Hier werden die Basisservices, das Logging und die Sicherheitskonfigurationen erstellt. – Bibliotheken Das Verzeichnis lib enthält die Java Bibliotheken, die beim Start der Serverkonfiguration geladen werden. – Anwendungen und Module Das Verzeichnis deploy enthält die Anwendungen, die von der Serverkonfiguration gestartet werden. Auch viele Komponenten des JBoss Server wie z.B. der Webcontainer oder das JMS Messaging sind hier abgelegt. Dieses Verzeichnis wird permanent überwacht, so dass Anwendungen durch Hineinkopieren bzw. Löschen auch ohne einen Neustart des Servers hinzugefügt bzw. entfernt werden können. 26 Das Netboot-Feature des JBoss erlaubt es nahezu die gesamte JBoss Installation auf einem zentralen WebDAVServer abzulegen und von dort zu laden. Weitere Informationen Hierzu bietet unter anderem [JB:Rupp] im Kapitel 5.1.2. 84 7 Erstellung von komplexen Installationspaketen Abbildung 29: JBoss Verzeichnisstruktur 7.2 Modifikationen an der Verzeichnisstruktur Die (De-)Aktivierung von verschiedenen Serverkomponenten und Anwendungen wird durch das Vorhandensein der XML-Dateien bzw. EAR-, WAR-, SAR- und RAR-Archive27 im deployVerzeichnis des Servers gesteuert. Lediglich die Basiskomponenten werden aus der zentralen Konfigurationsdatei im conf-Verzeichnisses des Servers geladen. Die Dateien im deployVerzeichnis des Servers stellen allerdings für den Installer ein Problem dar, da diese nicht nur durch Existenz bzw. Abwesenheit die entsprechende Programmkomponente aktivieren bzw. deaktivieren, sondern in einigen Fällen auch an das entsprechende System angepasst werden müssen (z.B. Datenbankverbindungen). Da diese Dateien eventuell angepasst werden, müsste der Installer sie als Konfigurationsdateien betrachten, dann ist allerdings ein Entfernen der Komponenten durch Deinstallieren nicht möglich. Für den zu installierenden JBoss Server wird eine neue Serverkonfiguratuion „current“ angelegt, die beim Starten des Servers geladen wird. Diese enthält lediglich die Verzeichnisse config und lib. Der Benutzer kann dann seine eigene 27 Anstelle der Archive können auch Verzeichnisse verwendet werden. 85 7 Erstellung von komplexen Installationspaketen Serverkonfiguration anpassen, indem er die Anwendungsmodule aus dem deploy-Verzeichnis der Konfigurationen „all“ oder „default“ in die Konfiguration „current“ kopiert und gegebenenfalls anpasst. Um Speicherplatz bei der Installation zu sparen, übernimmt die Konfiguration „current“ das lib-Verzeichnis der Konfiguration „all“ welches sämtliche Bibliotheken enthält und entfernt dafür das lib-Verzeichnis der Konfigurationen „all“ und „default“. 7.3 Log4J Anpassungen Der JBoss benutzt zur Verwaltung von Log-Meldungen die Log4J Bibliothek der Apache Software Foundation [Log4J]. Zur Weitergabe der Logmeldungen an das Log-System des Betriebssystems wird die Konfigurationsdatei conf/log4j.xml des Servers für die entsprechende Zielplattform angepasst.. Die Weitergabe von Logmeldungen an den Syslog-Daemon auf Linux/Unix Systemen ist für Java Programme recht unkompliziert, da die Logmeldungen über UPD an den Syslog-Daemon übertragen werden. Das Protokoll zur Übertragung der Logmeldungen ist in [RFC:3164] festgelegt. Für die Weitergabe von Logmeldungen an den Syslog-Daemon bringt Log4J bereits einen eigenen Appender mit, der mit dem folgenden Abschnitt konfiguriert werden kann. Da die Logging-Facility „jboss“ dem Syslog-Daemon nicht bekannt ist, sofern diese nicht in der Syslog Konfigurationsdatei konfiguriert wurde, werden die Logmeldungen der Facility „user“ zugeordnet und in der Logdatei /var/log/user.log abgelegt. Alle Logmeldungen mit einem Loglevel von „warn“ oder höher werden unabhängig von der Facility zusätzlich in den Logdateien /var/log/syslog und /var/log/messages abgelegt28. <appender name="SYSLOG" class="org.apache.log4j.net.SyslogAppender"> <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/> <param name="Facility" value="jboss"/> <param name="FacilityPrinting" value="true"/> <param name="SyslogHost" value="localhost"/> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="[%d{ABSOLUTE},%c{1}] %m%n"/> </layout> </appender> 28 Diese Einstellungen gelten für die Linux Distribution Debian und können bei anderen Distributionen davon abweichen. 86 7 Erstellung von komplexen Installationspaketen Bei der Übergabe von Logmeldungen an das Eventlog von Windows ist es nicht so leicht wie beim Syslog-Daemon. Hier erfolgt die Übergabe über Funktionen der Win32-API, die über das Java Native Interface (JNI) aufgerufen werden können. Auch hierfür bietet Log4J einen fertigen Appender. Die hierfür zusätzlich benötigte DLL ist in dem ZIP-Archiv von Log4J 1.2.8 im Verzeichnis /src/java/org/apache/log4j/nt/NTEventLogAppender.dll enthalten29. Damit die Logmeldungen im Eventlog korrekt angezeigt werden, muß beachtet werden, dass die Datei NTEventLogAppender.dll in das Verzeichnis C:\WINDOWS\System32\ installiert wird. Die Abbildungen 30 und 31 zeigen die Anzeige von Log4J-Logmeldungen im Eventlog: Abbildung 30: Log4J Meldung im EventLog (NTEventLogAppender.DLL befindet sich nicht im Systemverzeichnis) 29 Bei späteren Log4J Versionen ist lediglich der C-Sourcecode enthalten. 87 7 Erstellung von komplexen Installationspaketen Abbildung 31: Log4J Meldung im EventLog (NTEventLogAppender.DLL befindet sich im Systemverzeichnis) Wie beim Syslog-Appender erfolgt die Konfiguration des EventLogAppenders mit einem kurzen Abschnitt in der Konfigurationsdatei. Da das Eventlog eine feste Größe hat, ist es ratsam, nur Fehlermeldungen an das Eventlog zu übergeben, da, falls das Eventlog voll ist, nachfolgende Logmeldungen verloren gehen. <appender name="EVENTLOG" class="org.apache.log4j.nt.NTEventLogAppender"> <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/> <param name="Threshold" value="ERROR"/> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x) %m%n"/> </layout> </appender> 88 7 Erstellung von komplexen Installationspaketen 7.4 JBoss als Systemservice Auf Linux/Unix Systemen würde an sich ein geeignetes Init-Skript ausreichen, um den JBoss Server als Systemdienst zu starten. Auf Windows hingegen muss ein Systemdienst zwingend eine ausführbare Datei sein, die spezielle, durch die Win32-API definierte, Callback-Funktionen unterstützt. Eine einfach einzusetzende und doch mit großem Funktionsumfang ausgestattete Lösung bietet hier der JavaServiceWrapper [JSW]. Der JavaServiceWrapper besteht aus einer auf der jeweiligen Plattform ausführbaren Datei, dem Wrapper, der die Java VM startet und überwacht. Unter Windows kann der Wrapper dann als Systemdienst registriert oder in einer Konsole ausgeführt werden. Über eine Konfigurationsdatei wird der Wrapper an die eigenen Bedürfnisse angepasst. Der Wrapper bietet über das reine Starten und Stoppen der Anwendung hinaus noch weitere Funktionen an, durch die der Einsatz des Wrappers auch auf Linux/Unix Systemen interessant ist. Unter anderem überwacht der Wrapper die gestartete Java VM und startet diese neu, falls diese aufgrund eines Fehlers abstürzen sollte, was besonders bei Serveranwendungen ein praktisches Feature sein kann. Für Serveranwendungen, die die Java Management Extensions (JMX) unterstützen, bietet der Wrapper eine JMX-MBean an, über die der Server gestoppt oder neu gestartet werden kann. Um den laufenden JBoss Server von anderen Prozessen unterscheiden zu können, wird die ausführbare Datei wrapper(.exe) in jboss(.exe) umbenannt. Der laufende JBoss Server ist dann in der Prozessliste von anderen Java Programmen unterscheidbar. Die Abbildungen 32 und 33 zeigen die Anzeige des JBoss Prozesses auf Windows und Linux Systemen, wenn dieser über den Wrapper gestartet wurde: Abbildung 32: Der gestartete JBoss Server (pstreeAnsicht auf Linux) 89 7 Erstellung von komplexen Installationspaketen Abbildung 33: Der gestartete JBoss Server (Sysinternals Process Explorer auf Windows) 7.4.1 Konfiguration des JavaServiceWrappers Die Konfiguration des JavaServiceWrappers erfolgt über eine Properties-Datei, die verschiedene Einstellungen enthält. Hierbei kann auf Umgebungsvariablen zurückgegriffen werden. Wichtige Einstellungen der Konfigurationsdateien für den JBoss Server sind: – wrapper.java.command: Pfad zur ausführbaren Java-Datei. Unter Zuhilfenahme der Umgebungsvariable des Installers kann unter Windows „%JAVA_JBoss%\bin\java.exe“ verwendet werden. Auf Linux Systemen kann entweder „java“ oder der volle Pfad verwendet werden. – wrapper.java.command: Zu startende Java-Klasse. Diese Klasse muss das Interface WrapperListener implementieren. Für Anwendungen wie JBoss, bei denen das nicht der Fall ist, kann die Hilfsklasse WrapperSimpleApp verwendet werden. – wrapper.java.classpath.n und wrapper.java.library.path.n: Pfade zu den Java-Bibliotheken und zu nativen Bibliotheken, die von der VM geladen werden. Für den JBoss sind das die JAR-Archive wrapper.jar und run.jar aus dem bin-Verzeichnis der JBoss 90 7 Erstellung von komplexen Installationspaketen Installation sowie tools.jar aus dem Java SDK30. – wrapper.java.additional.n: Startoptionen für die Java VM. Für den JBoss sollte die option „-server“ gesetzt werden. – wrapper.java.initmemory und wrapper.java.maxmemory: Initiale und maximale Größe des Heap-Speichers der Java VM in MB. Der JBoss benötigt in der „default“-Konfiguration mindestens 64 MB, um zu starten. Der maximale Speicher sollte an das aktuelle System und die auf dem JBoss laufenden Anwendungen angepasst werden. – wrapper.app.parameter.n: Parameter, die an die zu startende Klasse übergeben werden. Bei Verwendung der Hilfsklasse WrapperSimpleApp ist der erste Parameter die Klasse der zu startenden Anwendung (org.jboss.Main beim JBoss). Für den JBoss muss zusätzlich noch „-c current“ gesetzt werden, um die zu startende Serverkonfiguration auszuwählen. – wrapper.console.loglevel und wrapper.syslog.loglevel: Welche Logmeldungen sollen auf der Konsole ausgegeben werden (wenn der JBoss in der Konsole gestartet wurde) bzw. welche Logmeldungen sollen in das Logsystem des Betriebssystems (Syslog oder Eventlog) geschrieben werden. Für das Logsystem des Betriebssystems bietet sich „STATUS“ an, was alle Fehlermeldungen sowie Statusänderungen (Start, Stop und Neustart der VM) beinhaltet. Für die Konsole ist „INFO“ passend, da dann zusätzlich alle Ausgaben der VM auf die Konsole durchgereicht werden und Logmeldungen so direkt mitverfolgt werden können. – wrapper.single_invocation: Wird dieser Parameter auf „TRUE“ gesetzt kann immer nur eine Instanz des JBoss auf dem System laufen (betrifft nur Windows Systeme, auf Linux wird das durch das Init-Skript geprüft). Zusätzlich muss wrapper.ntservice.name auf den Namen des Windows Dienstes gesetzt werden. 7.4.2 Startskripte für den JavaServiceWrapper Auf Windows Systemen wird der Java Service Wrapper über die Verwaltung der Systemdienste gestartet. Um den JBoss in der Konsole zu starten, wird allerdings noch ein Startskript benötigt. Die Datei run.bat enthält lediglich die Zeile (Unter der Voraussetzung dass in der Umgebungsvariable %JBOSS_HOME% das Installationsverzeichnis des JBoss abgelegt ist.): %JBOSS_HOME%\bin\jboss.exe -c jboss.conf Auf Linux/Unix Systemen wird zum Starten und Stoppen des JBoss ein Startskript verwendet, dass im Verzeichnis /etc/init.d/ abgelegt wird. Eine Vorlage für ein solches Startskript ist in dem Binärpaket des Java Service Wrappers enthalten. In diesem Skript müssen lediglich die Installationspfade der Anwendung angepasst werden. Über dieses Skript kann der JBoss sowohl als Systemdienst gestartet bzw. gestoppt werden sowie in der Konsole als Prozess ausgeführt werden. 30 Der integrierte Tomcat Webserver benötigt die tools.jar um JSP-Seiten zu kompilieren. 91 7 Erstellung von komplexen Installationspaketen 7.5 Versionierung der Installer-Pakete Ein kleines Problem stellt die Versionierung des JBoss Servers da. Damit der Windows Installer ein Update auch als ein solches erkennt, muss sich mindestens die dritte Zahl (beim Format „Major.Minor.Revision“, die Revisionsnummer) der Versionsnummer ändern. Zusätzlich zur dreistelligen Versionsnummer des JBoss Servers gibt es aber noch weitere Abstufungen. So gibt es z.B eine 4.0.3RC1, 4.0.3RC2, 4.0.3 und eventuell auch eine 4.0.3SP1. Um eine für den Windows Installer auswertbare Versionsnummer zu erzeugen, wird an die Versionsnummer zusätzlich eine Buildnummer angehängt. Die erste Stelle der Versionsnummer fällt dafür weg und fließt in den Paketnamen ein, so dass das Paket für den JBoss 4.0.4RC1 den Namen „JBoss4“ und die Version „0.4.1“ trägt. Für die DEB-Pakete, bei denen diese Einschränkung der Versionsnummer nicht gilt, wird die Buildnummer als zusätzliche Stelle an die Versionsnummer angehängt, so dass die Versionsnummer in diesem Fall „4.0.4.1-RC1“ lautet. 7.6 Metainformationen der Installer-Pakete Die Beschreibung des JBoss Application Servers innerhalb des Installationspaketes soll kurz gehalten werden und verweist auf die Homepage des JBoss. Analog dazu wird auch die Lizenzvereinbarung kurz gehalten, und verweist auf die Lizenzen der einzelnen Programmkomponenten, die im Installationsverzeichnis abgelegt werden. Als Konfigurationsdateien kommen sowohl die Konfigurationsdatei des Wrappers bin/jboss.conf sowie alle Dateien in dem conf-Verzeichnis der Serverkonfiguration „current“ (server/current/conf/**) in Frage. Dateien im deploy-Verzeichnis der Serverkonfiguration stehen nicht unter der Kontrolle des Installers und sind daher auch keine Konfigurationsdateien. Für Windows-Systeme wird im Startmenü ein Link angelegt, der das Starten des JBoss in der Konsole ermöglicht. Zudem wird dem JBoss das Windows-Tool Tail for Win32 [Tail32] mitgegeben, dass das Betrachten der Logdateien im laufenden Betrieb ermöglicht. Auch hierfür werden 2 Links im Startmenü platziert, die das Betrachten der Logdateien server.log und boot.log ermöglichen. Für das DEB-Paket erfolgt die Einordnung in die Sektion „contrib/net“. „contrib“, da das Paket von der Java-Laufzeitumgebung abhängt, die selber entsprechend dem Debian Gesellschaftsvertrag [DSC] nicht frei ist, und „net“, da dieses die Sektion für Daemonen und Netzwerkanwendungen ist. Die Architektur wird in den Metainformationen leer gelassen und beim Bauen des Paketes übergeben, dass das Paket für verschiedene Architekturen erstellt wird. Das ist notwendig, da der JavaServiceWrapper als plattformabhängige Komponente in dem Paket enthalten ist. Als erforderliche Abhängigkeiten benötigt das DEB-Paket die Pakete „java2-runtime“ (eine beliebige, zu Java2 kompatible Laufzeitumgebung für den JBoss) sowie die Pakete „bash“ und „gnulib“, die von dem Init-Skript benötigt werden. 92 7 Erstellung von komplexen Installationspaketen 7.7 Vorbereitung des JBoss Bevor die Installationspakete für den JBoss erstellt werden können, muss in einem Verzeichnis die Verzeichnisstruktur des JBoss so aufgebaut werden, wie dieser später installiert werden soll. Die Verzeichnisstruktur des JBoss bleibt dabei größtenteils so erhalten wie im Kapitel Der JBoss Application Server beschrieben. Die Dateien des JavaServiceWrappers aus dem Kapitel JBoss als Systemservice werden in das Verzeichnis bin des JBoss kopiert. Neben der Datei jboss(.exe) sind dass die Dateien wrapper.jar sowie wrapper.dll bzw. libwrapper.so und die Konfigurationsdatei jboss.conf. Für eine Installation auf Windows wird das Startskript run.bat durch ein angepasstes Startskript ersetzt, dass den Java Service Wrapper zum Starten des JBoss benutzt. Unterhalb des Verzeichnisses server wird mit dem Verzeichnis current eine neue Serverkonfiguration erstellt, die von dem installierten JBoss geladen wird. Diese Serverkonfiguration enthält die Verzeichnisse conf und lib, die aus der Serverkonfiguration „all“ kopiert werden. Um die Größe des Installationspaketes zu reduzieren, werden diese Verzeichnisse aus den Serverkonfigurationen „all“ und „default“ entfernt. Die Datei log4j.xml im Verzeichnis conf wird hierbei durch eine Konfigurationsdatei ersetzt, die an das Betriebssystem angepasst wurde wie im Kapitel Log4J Anpassungen beschrieben. In dem Verzeichnis deploy der Serverkonfiguration „current“ wird die Datei wrapper-server.xml mit dem folgendem Inhalt angelegt: <?xml version="1.0" encoding="UTF-8"?> <server> <classpath archives="wrapper.jar" codebase="../../bin"/> <mbean code="org.tanukisoftware.wrapper.jmx.WrapperManager" name="JavaServiceWrapper:service=WrapperManager" /> </server> Diese Datei lädt die JMX-Komponente des JavaServiceWrappers in den JBoss und ermöglicht dadurch die Kontrolle des JavaServiceWappers über die Java Management Extensions (JMX) und somit über die Web-Console des JBoss oder eine externe Verwaltungskonsole wie die MC4J Management Konsole [MC4J]. 93 7 Erstellung von komplexen Installationspaketen 7.8 Serverkonfiguration „current“ des JBoss Die Serverkonfiguration „current“ des JBoss, die im Kapitel Vorbereitung des JBoss aufgebaut wurde, enthält im Verzeichnis deploy mit Ausnahme der Datei wrapper-serveice.xml keine weiteren Dateien und somit auch keine Anwendungen, die der JBoss beim Starten lädt. Da der JBoss Server allerdings alle nicht zwingend notwendigen Serverfunktionen ebenfalls als Anwendungen aus dem deploy-Verzeichnis lädt, sollten die Serverfunktionen31 der „default“-Konfiguration nach der Installation auch in der „current“-Konfiguration enthalten sein. Problematisch ist hierbei allerdings, dass die Dateien im deploy-Verzeichnis vom Benutzer möglicherweise verändert wurden, um die Serverfunktionen zu konfigurieren32. Es ist allerdings auch nicht möglich, die Dateien im deployVerzeichnis als Konfigurationsdateien entsprechend dem Kapitel Update der Anwendung zu behandeln, da diese Dateien bei einem Update neu angelegt werden, wenn sie nicht existieren. Das Entfernen einer Serverfunktionalität, die nicht benötigt wird, erfolgt allerdings durch Löschen der Dateien im deploy-Verzeichnis. Auch kann es bei einem Update vorkommen, dass sich die Namen der Dateien im deploy-Verzeichnis ändern. Nach einem Update wären dann eventuell einzelne Serverfunktionen doppelt vorhanden. Eine Möglichkeit, diese Probleme zu umgehen, ist hier die Dateien im default-Verzeichnis nicht über das Installationspaket zu installieren, sondern nach einer Erstinstallation, wenn noch kein JBoss installiert war, aus der „default“-Konfiguration zu kopieren. Diese Dateien stehen dann nicht mehr in unter der Verantwortung des Installationspaketes und der Benutzer kann diese Dateien nach Belieben verändern oder auch löschen. Bei einem Update werden diese Dateien durch das Installationspaket nicht verändert. Das genaue Vorgehen hierfür ist von der jeweiligen Installationstechnologie abhängig und wird in den Kapiteln Bau des Windows Installer Paketes und Bau der DEB-Pakete beschrieben. 31 Nicht zwingend erforderliche Serverfunktionen sind, je nach Einsatzzweck, unter anderem der integrierte Webserver oder die JMS-Funktionalität. 32 z.B. der integrierte Tomcat-Webserver wird über die Datei jbossweb-tomcat55.sar/server.xml konfiguriert. 94 7 Erstellung von komplexen Installationspaketen 7.9 Bau des Windows Installer Paketes Für das Windows Installer Paket wird die Vorlage der Setup-Datei aus dem Toolkit geringfügig angepasst. Das Installationsverzeichnis wird als zusätzliche Umgebungsvariable „JBOSS_HOME“ angelegt, die unter anderem in der Wrapper-Konfigurationsdatei benutzt wird. Die Datei NTEventLogAppender.dll muss separat konfiguriert werden, da sie in das Verzeichnis C:\WINDOWS\System32\ installiert wird. Auch die Datei jboss.exe muss separat definiert werden, da hier zusätzliche Informationen zur Registrierung als Systemservice in die Setup-Datei mit eingefügt werden müssen. Der dafür notwendige „ServiceInstall“-Tag muss innerhalb des „File“-Tags platziert werden. Da diese Dateien nicht durch die automatische Generierung der Setup-Datei eingebunden werden, dürfen sie auch nicht in dem Verzeichnis mit den übrigen Dateien liegen, sondern werden in das Verzeichnis mit der Setup-Datei kopiert. Um die Serverkonfiguration „current“ zu initialisieren, wie im Kapitel Serverkonfiguration „current“ des JBoss beschrieben, wird eine „CustomAction“ benötigt, die in die Setup-Datei eingefügt werden muss. Ein „CustomAction“-Tag und ein „Property“-Tag werden benötigt um die Aktion zu definieren33: <CustomAction Id="INIT_DEPLOY" Execute="commit" Return="check" Property="XCOPY" ExeCommand="/Q /S /E /V /C /Y [TARGETDIR]\server\default\*.* [TARGETDIR]\server\current\" /> <Property Id="XCOPY" Value="xcopy.exe"/> Diese Aktion wird in die „InstallExecuteSequence“ eingebunden und nur ausgeführt, wenn es sich um eine Erstinstallation handelt (Bedingung: „ProductState = -1“). Ausgeführt wird diese Aktion kurz vor Beenden der Installation, nachdem die Dateien auf die Festplatte kopiert wurden (Before=“InstallFinalize“). <InstallExecuteSequence> [...] <Custom Action="INIT_DEPLOY" Before="InstallFinalize">ProductState = -1</Custom> </InstallExecuteSequence> Die Abbildungen 34 bis 37 zeigen den Installer-Wizard, sowie das erzeugte Installationsverzeichnis und die Verknüpfungen im Startmenü und auf dem Desktop: 33 Der Windows Installer erfordert die Angabe der ausführbaren Datei über eine Property. 95 7 Erstellung von komplexen Installationspaketen Abbildung 34: Installation des JBoss auf Windows Abbildung 35: Der installierte JBoss im Windows-Explorer 96 7 Erstellung von komplexen Installationspaketen Abbildung 36: Der installierte JBoss im Startmenü Abbildung 37: Der installierte JBoss in der Computerverwaltung 97 7 Erstellung von komplexen Installationspaketen 7.10 Bau der DEB-Pakete Der JBoss Server ist so konzipiert, dass er komplett innerhalb des Installationsverzeichnisses operiert, was zur Folge hat, dass dort sowohl ausführbare Dateien als auch Bibliotheken, Konfigurationsdateien, Logdateien und Daten der integrierten Datenbank untergebracht sind. Diese Struktur passt eigentlich nicht zu der unter Linux/Unix üblichen Verzeichnisstruktur, die eine Trennung von Konfigurationsdateien (/etc), ausführbaren Dateien (/usr/bin) und Daten bzw. Logdateien (/var) vorsieht. Aufgrund der enthaltenen Daten und Logdateien ist es am sinnvollsten, den JBoss unterhalb von /var/jboss zu installieren. Um den JBoss als Systemdienst zu starten, wird ein Init-Skript benötigt. Dieses kann der Distribution das JavaServiceWrappers entnommen werden. Lediglich die Pfade zu der ausführbaren Wrapper-Datei und der Konfigurationsdatei müssen angepasst werden. Das Init-Skript wird unter dem Namen „init.d“ im debian-Verzeichnis abgelegt. Durch zusätzliches Aufrufen des DebhelperSkriptes dh_installinit wird dieses Skript nach der Installation als /etc/init.d/jboss installiert. Zudem modifiziert das Debhelper-Skript auch die Maintainer-Skripte debian/postinst und debian/prerm, um den JBoss Server automatisch beim (De-)Installieren zu starten und stoppen. Hierbei muss beachtet werden, dass das Debhelper-Skript dh_installdeb nach dh_installinit noch einmal ausgeführt werden muss, damit die modifizierten Skripte debian/postinst und debian/prerm auch in in das DEB-Paket mit übernommen werden. Um die Serverkonfiguration „current“ zu initialisieren, wie im Kapitel Serverkonfiguration „current“ des JBoss beschrieben, wird das Skript debian/postinst (siehe Kapitel Maintainer-Skripte) verwendet, das nach der erfolgreichen Installation ausgeführt wird. Hierbei handelt es sich um ein Shell-Skript, dass beliebige Befehle enthalten kann. Wichtig ist die Zeile „#DEBHELPER#“, da hier zusätzliche Befehle eingefügt werden, die durch die Debhelper-Skripte erzeugt werden. Um sicherzustellen, dass nur bei einer Erstinstallation die Serverinstallation initialisiert wird, erfolgt die Initialisierung nur, wenn die Datei /var/jboss/server/server-initialized nicht existiert. Nach erfolgter Initialisierung wird diese Datei mit dem Befehl touch angelegt. 98 7 Erstellung von komplexen Installationspaketen #! /bin/sh set -e # Initialize JBoss with the default configuration, # but only if this is the first install if [ -e "/var/jboss/server/server-initialized" ]; then echo "Initializing JBoss default configuration ..."; echo "JBoss configuration already initialized"; echo "To reinitialize [...]"; else cp --force --recursive --preserve=mode,ownership,timestamps /var/jboss/server/default/* /var/jboss/server/current/ ; touch /var/jboss/server/server-initialized; echo "JBoss configuration initialized"; fi # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0; Zudem wird noch das Skript debian/postrm angelegt, um beim vollständigen Entfernen34 des Paketes auch die Datei /var/jboss/server/server-initialized und das deploy-Verzeichnis zu entfernen. Beim vollständigen Entfernen des Paketes wird dem Skript der Parameter „purge“ übergeben, der über den case-Block abgefragt wird. Anschließend entfernt das Skript bei jedem Deinstallieren und Updaten35 des Paketes die Verzeichnisse tmp und work der Serverkonfiguration, die die temporären Dateien des JBoss enthält. Das Entfernen der Verzeichnisse ist unkritisch, da der JBoss bei einem Update durch die Modifikationen an den Skripten debian/postinst und debian/prerm durch das Debhelper-Skript dh_installinit vor einem Update beendet und anschließend neu gestartet wird. 34 Der Debian Package Manager unterscheidet zwischen dem Entfernen des Paketes, bei dem die Konfigurationsdateien auf dem System verbleiben, und dem vollständigen Entfernen, dass auch die Konfigurationsdateien löscht. 35 Bei einem Update wird die alte Version des Paketes deinstalliert, bevor die neue Version installiert wird. Die Konfigurationsdateien bleiben dabei enthalten. 99 7 Erstellung von komplexen Installationspaketen #! /bin/sh set -e case "$1" in purge) # remove the file /var/jboss/server/server-initialized # this target is called when package is removed and purged (apt-get --purge remove jboss4) echo "removing /var/jboss/server/server-initialized"; echo "JBoss wil be reinitialized on next install"; rm --force /var/jboss/server/server-initialized; rm --force --recursive /var/jboss/server/current/deploy; ;; esac echo "Removing temprary JBoss files"; rm --force --recursive /var/jboss/server/current/tmp; rm --force --recursive /var/jboss/server/current/work; # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0; Zusätzlich muss noch das Kommando „chmod u+x debian/tmp/var/jboss/bin/jboss“ beim Erstellen des Paketes durch den Ant-Task des Toolkits ausgeführt werden, um den Wrapper ausführbar zu machen. Diese Aktion ist bei ausführbaren Dateien, die nicht in /usr/bin platziert werden, notwendig, da das Debhelper-Skript, dh_fixperms diese Dateien standardmäßig nicht ausführbar macht36. Da das Paket durch die Integration des JavaServiceWrappers plattformabhängige Komponenten enthält, ist es notwendig den Parameter „architecture“ des Tasks zu setzten. Der Wert für den Parameter wird hier aus der Datei build.properties entnommen. Auf eine Erstellung des Paketes für mehrere Architekturen wird hier verzichtet, um das Beispiel nicht unnötig aufzublähen (Durch Verwendung verschiedener build.properties Dateien bzw. Setzen der build.properties-Variablen von der Kommandozeile ist das Erzeugen der Pakete für mehrere Architekturen bereits möglich). Die Abbildungen 38 und 39 zeigen die Installation des Paketes mittels apt-get sowie das erzeugte Installationsverzeichnis: 36 Dateien, die in /usr/bin platziert werden, werden von dh_fixperms standardmäßig ausführbar gemacht. 100 7 Erstellung von komplexen Installationspaketen Abbildung 38: Installation des JBoss mit apt-get Abbildung 39: Der installierte JBoss im Konqueror 101 8 Zusammenfassung und Ausblick 8 Zusammenfassung und Ausblick Der Verlauf dieser Arbeit hat gezeigt, dass eine Zusammenführung verschiedener Installationstechnologien auf einen einheitlichen Nenner keine einfache Aufgabe ist. Insbesondere die Zusammenführung zweier konzeptionell sehr unterschiedlicher Technologien wie dem Windows Installer und dem Debian Package Manager war nicht frei von Problemen und Kompromissen. Insbesondere die Verwaltung von Konfigurationsdateien, die der Debian Package Manager sehr gut gelöst hat, kann mit dem Windows Installer nicht in diesem Maße umgesetzt werden. Dennoch zeigt diese Arbeit, dass eine solche Zusammenführung auf einen gemeinsamen Nenner durchaus möglich ist. Das im Verlauf dieser Arbeit entwickelte Toolkit ermöglicht es, die Erzeugung von Installer-Paketen in dem Build-Prozess mit einzubinden, so dass bei jedem Build ein Installationspaket mit erzeugt werden kann. Diese Installationspakete können unter anderem in Integrationstests mit eingebunden werden. Falls zudem noch ein System zur kontinuierlichen Integration37 (Continuous Integration) wie z.B. CruiseControl [CC] eingesetzt wird, ergibt sich so die Möglichkeit, täglich neue Testversionen zur Verfügung zu stellen. Das im Verlauf dieser Arbeit entwickelte Toolkit ist hierfür lediglich ein Ansatz, der für den Einsatz in realen Umgebungen noch ausgebaut werden muss. Die Unterstützung von zwei verschiedenen Installationstechnologien sicher noch nicht ausreichend, wenn eine Anwendung auf vielen Plattformen installiert werden soll. Eine zusätzliche Unterstützung des RPM-Formates [RPM] würde dazu beitragen, einen großen Teil der verbreiteten Linux Distributionen zu unterstützen. Eine Erweiterung des Toolkits um die Unterstützung des RPM-Formates sollte aufgrund der Ähnlichkeiten zwischen dem DEB- und dem RPM-Format mit nicht allzu großem Aufwand möglich sein. Auch die Unterstützung weiterer Installationstechnologien und Paketformate ist hier durchaus denkbar. Auch eine Einbindung in das Build-Tool Maven [MVN], dass von der Apache Software Foundation aktiv entwickelt und genutzt wird, wäre im Zuge einer Weiterentwicklung durchaus sinnvoll, da hier, ähnlich wie bei dem Toolkit, der gesamte Build-Prozess über beschreibende Metadaten gesteuert wird. Um die Weiterentwicklung des Toolkits auch durch andere interessierte Personen als den Autor zu ermöglichen, wird das Toolkit zusammen mit dem Beispielen aus dieser Arbeit als Projekt auf der Open Source Plattform SourceForge [SF] unter den Bedingungen der Lesser GNU Public License [LGPL] veröffentlicht. Über diese Plattform wird auch die Kommunikation mit anderen Entwicklern sowie die weitere Entwicklung laufen. Verfügbar ist die Projektseite unter der URL: http://sourceforge.net/projects/install-toolkit. 37 Die kontinuierliche Integration (Continuous Integration) ist ein Verfahren, das in direktem Zusammenhang mit Extreme Programming steht. Herbei erstellt ein Serverprozess in einem festen Zeitintervall (z.B. täglich) einen Build des aktuellen Entwicklungsstandes und testet diesen. Continuous Integration wird von Martin Fowler in [CI] näher beschrieben. 102 9 Abbildungsverzeichnis 9 Abbildungsverzeichnis Abbildung 1: Ein typischer Install-Wizard.........................................................................................11 Abbildung 2: Ansicht einer MSI-Datei mit ORCA............................................................................ 13 Abbildung 3: Windows Installer - Zustandsdiagramm.......................................................................14 Abbildung 4: Ansicht des Installer Paketes im Explorer....................................................................21 Abbildung 5: Dateiinformationen des Installer Paketes..................................................................... 22 Abbildung 6: OpenOffice.org Installer - Auswahl von Programmkomponenten.............................. 24 Abbildung 7: Windows Installer - Features und Komponenten......................................................... 25 Abbildung 8: synaptic - demoapp im nicht installierten Zustand.......................................................34 Abbildung 9: synaptic - Eigenschaften (allgemein) von demoapp.....................................................35 Abbildung 10: synaptic - Eigenschaften (Abhängigkeiten) von demoapp.........................................35 Abbildung 11: synaptic - Eigenschaften (Beschreibung) von demoapp............................................ 36 Abbildung 12: synaptic - demoapp im installierten Zustand (Update verfügbar)..............................36 Abbildung 13: Verknüpfung auf dem Windows Desktop.................................................................. 43 Abbildung 14: Verknüpfung im Windows Startmenü........................................................................44 Abbildung 15: Verknüpfung im Xfce Startmenü............................................................................... 45 Abbildung 16: Verknüpfung im GNOME Startmenü........................................................................ 46 Abbildung 17: Verknüpfung im KDE Startmenü...............................................................................46 Abbildung 18: synaptic - Ersetzen der Konfigurationsdatei beim Update bestätigen........................47 Abbildung 19: Installation von demoapp mit apt-get.........................................................................50 Abbildung 20: Windows Installer ohne GUI......................................................................................50 Abbildung 21: Der Java-Dialog in WiX Edit..................................................................................... 52 Abbildung 22: Featuretree-GUI Standardabfolge der Dialoge...........................................................53 Abbildung 23: Der eingefügte Java-Dialog........................................................................................54 Abbildung 24: Die Klasse „MyTask“.................................................................................................57 Abbildung 25: Die Klasse MyTask2.................................................................................................. 58 Abbildung 26: Installer Metainformationen – XML-Schema............................................................ 70 Abbildung 27: Installer Metainformationen – XML-Schema (Windows-Abschnitt)........................ 71 Abbildung 28: Installer Metainformationen – XML-Schema (DEB-Abschnitt)................................71 Abbildung 29: JBoss Verzeichnisstruktur.......................................................................................... 85 Abbildung 30: Log4J Meldung im EventLog (NTEventLogAppender.DLL befindet sich nicht im Systemverzeichnis).............................................................................................................................87 Abbildung 31: Log4J Meldung im EventLog (NTEventLogAppender.DLL befindet sich im Systemverzeichnis).............................................................................................................................88 Abbildung 32: Der gestartete JBoss Server (pstree-Ansicht auf Linux)............................................ 89 Abbildung 33: Der gestartete JBoss Server (Sysinternals Process Explorer auf Windows) ............. 90 Abbildung 34: Installation des JBoss auf Windows...........................................................................96 Abbildung 35: Der installierte JBoss im Windows-Explorer.............................................................96 Abbildung 36: Der installierte JBoss im Startmenü........................................................................... 97 Abbildung 37: Der installierte JBoss in der Computerverwaltung.....................................................97 Abbildung 38: Installation des JBoss mit apt-get.............................................................................101 Abbildung 39: Der installierte JBoss im Konqueror........................................................................ 101 103 10 Literaturverzeichnis 10 Literaturverzeichnis [Ant] Apache Ant Homepage http://ant.apache.org [AP] Autopackage Homepage http://www.autopackage.org/index.html [BASH] BASH Homepage http://www.gnu.org/software/bash/bash.html [BD] ERPOSS3 - Erprobung des Einsatzes von Open Source Software in Behörden http://www.bsi.bund.de/produkte/erposs3/index.htm [Bean] Java Beans Specification http://java.sun.com/products/javabeans/docs/spec.html [BSI] bundesministerium für Sicherheit in der Informationstechnik http://www.bsi.bund.de/index.htm [CC] CruiseControl Homepage http://cruisecontrol.sourceforge.net [CI] Continuous Integration http://www.martinfowler.com/articles/continuousIntegration.html [Debian] Debian http://www.debian.org [Dom4J] Dom4J Homepage http://www.dom4j.org [DP] Debian Policy-Handbuch http://www.debian.org/doc/debian-policy/ [DSC] Debian Gesellschaftsvertrag http://www.debian.org/social_contract [DU] Debian Unofficial Homepage http://www.debian-unofficial.org [eclipse] eclipse Homepage http://www.eclipse.org [FHS] Filesystem Hierarchy Standard http://www.pathname.com/fhs/ [FreeD] Freedesktop.Org Homepage www.freedesktop.org [FreeD:DB] Freedesktop.Org Desktop Basedir Specification http://www.freedesktop.org/wiki/Standards_2fbasedir_2dspec [FreeD:DE] Freedesktop.Org Desktop-Entry Specification http://standards.freedesktop.org/desktop-entry-spec/latest/ [FreeD:M] Freedesktop.Org Menu Specification http://www.freedesktop.org/wiki/Standards_2fmenu_2dspec [Froot] fakeroot Homepage http://joostje.op.het.net/fakeroot/index.html [Gartn] Gartner Homepage http://www.gartner.com/ [GGen] GuidGen http://www.guidgen.com/ [GZip] GZip Homepage http://www.gzip.org/ [HN1] Microsoft-Betriebssysteme dominieren weiter http://www.heise.de/newsticker/meldung/40917 [HN2] Studie: Windows-Server beim Umsatz vorne http://www.heise.de/newsticker/meldung/66568 [HN3] IDC: Marktanteil von Linux-Servern steigt in Europa auf 16 Prozent http://www.heise.de/newsticker/meldung/52568 [IA] Install Anywhere Homepage http://www.macrovision.com/products/flexnet_installshield/installanywhere/index.shtml [IDC] IDC Homepage http://www.idc.com/ [IS] InstallShield Homepage http://www.macrovision.com/products/flexnet_installshield/index.shtml [JB] JBoss Homepage http://www.jboss.org [JB:Rupp] JBoss, Heiko W. Rupp dpunkt.verlag ISBN 3-89864-318-2 [JBI] JBoss Inc. Homepage http://www.jboss.com [JSW] JavaServiceWrapper Homepage http://wrapper.tanukisoftware.org [klik] klik Homepage http://klik.atekon.de/ [Knoppix] Knoppix Homepage http://www.knopper.net/knoppix/ 104 10 Literaturverzeichnis [Kubuntu] Kubuntu Homepage http://www.kubuntu.org/ [LGPL] GNU Lesser General Public License http://www.gnu.org/licenses/lgpl.html [Lintian] Lintian Homepage http://lintian.debian.org [LM:A] Distributionsunabhängige Pakete mit Autopackage: Eines für alle,Robert Staudinger Linux Magazin 02/2006 [LM:K] Softwaredistribution mit Klik: ... und es hat Klik gemacht,Tim Schürmann Linux Magazin 02/2006 [Log4J] Log4J Homepage http://logging.apache.org/log4j/docs/ [M23] m32 Homepage http://m23.sourceforge.net/ [MC4J] MC4J Homepage http://mc4j.org [MD] Mandriva Homepage http://www.mandriva.com/ [MVN] Apache Maven Homepage http://maven.apache.org/ [NET] Microsoft.NET Framework Homepage http://msdn.microsoft.com/netframework/ [Netcr] Strong growth for Debian http://news.netcraft.com/archives/2005/12/05/strong_growth_for_debian.html [Novell] Novell Homepage http://www.novell.com [NSIS] NSIS Homepage http://nsis.sourceforge.net [OO] OpenOffice Homepage http://www.openoffice.org [OSuse] OpenSuse Linux Homepage http://www.opensuse.org [RFC:3164] The BSD syslog Protocol http://www.ietf.org/rfc/rfc3164.txt [RFC:4122] RFC 4122: A Universally Unique IDentifier (UUID) URN Namespace http://www.ietf.org/rfc/rfc4122.txt [RFC:822] RFC 822: Standard For The Format of ARPA Internet Messages http://www.ietf.org/rfc/rfc822.txt [RH] RedHat Homepage http://www.redhat.com [RPM] RedHat Package Manager Homepage http://www.rpm.org/ [RpmG] RPM Guide, Eric Foster-Johnson Whiley Publishing Inc. ISBN 0-7645-4965-0 [RTF:Spec] Rich Text Format (RTF) Specification, Version 1.6 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnrtfspec/html/rtfspec.asp [Sapt] Synaptic Homepage http://www.nongnu.org/synaptic/ [SF] SourceForge Homepage http://www.sourceforge.net [SUN] Sun Microsystems Homepage http://www.sun.com [Tail32] Tail for Win32 Homepage http://tailforwin32.sourceforge.net/ [Ubuntu] Ubuntu Homepage http://www.ubuntu.com/ [WAmp] Winamp Homepage http://www.winamp.com [WI:Kerl] Windows Installer 3.1, Andreas Kerl Microsoft Press 3.1 ISBN 3-86063-547-6 [WI:Knecht] Windows Installer, Stephanie Knecht-Thurmann, Thomas Knecht Addison-Wesley ISBN 3-8273-2307-X [WIENUX] WIENUX: Linux Distribution der Stadt Wien http://www.wien.gv.at/ma14/wienux.html [WISE] WISE Homepage http://www.wise.com/ [WIX] Windows Instaler XML Toolkit http://wix.sourceforge.net/ [Wix:Tut] WiX Tutorial http://www.tramontana.co.hu/wix/ [WixEdit] WixEdit Homepage http://wixedit.sourceforge.net/ [WTP] eclipse Web Tools Project http://www.eclipse.org/webtools/ [Xfce] Xfce Desktop Environment Homepage http://www.xfce.org/ 105