From 33613a85afc4b1481367fbe92a17ee59c240250b Mon Sep 17 00:00:00 2001
From: Sven Eisenhauer
+
+Die Ausführungen in diesem Abschnitt können beim ersten
+Lesen übersprungen werden. Sie setzen ein grundsätzliches
+Verständnis für Applets voraus und verwenden Beispielcode
+aus den Abschnitten 38.3 und 46.3.3.
+Aus systematischen Gründen soll das Thema jedoch an dieser Stelle
+behandelt werden.
+Applets werden ab Kapitel 39
+erklärt. Sie waren es, die mit der Möglichkeit, eigenständige
+Programme mit grafischer Oberfläche in Webseiten einzubinden,
+einen großen Teil der anfänglichen Begeisterung für
+Java auslösten. Später erkannte man noch einen zweiten,
+strategischen Vorteil: diese Programme mußten nicht installiert
+werden, sondern wurden einfach aufgerufen und waren immer up-to-date.
+Das brachte »gute alte Zeiten« in Erinnerung, bei denen
+die Anwender an einfachen Terminals saßen, die - wenn sie wirklich
+einmal defekt waren - ohne großen Aufwand ausgetauscht werden
+konnten.
+
+
+Schnell war die Idee geboren, dies mit aktueller (Java-)Technologie
+nachzuahmen. Warum nicht alle benötigten Programme als Applets
+implementieren, die bei Bedarf von einem zentralen Server geladen
+werden? Man hatte nämlich erkannt, dass in den Unternehmen ein
+Großteil der durch Computerarbeitsplätze verursachten Kosten
+gar nicht bei deren Kauf entstand, sondern erst danach. Etwa durch
+Updates, Reparaturen und Wartungen; aber auch durch Probleme, die
+durch nicht verfügbare, fehlerhafte oder inkonsistente Programmversionen
+entstand. Die aus dieser Idee entstandenen Java Workstations
+konnten sich allerdings nicht durchsetzen. Trotz vielversprechender
+Anfänge wurden die durch langsame Netzwerkverbindungen oder unzulängliche
+Java-Implementierungen in den Browsern verursachten Probleme nicht
+gelöst. Die Java-Stations verschwanden ebenso schnell von der
+Bildfläche, wie sie zuvor aufgetaucht waren.
+
+
+Während der Entwicklung des JDK 1.3 brachte SUN eine Technologie
+auf den Markt, mit der die Vorteile von Applets und Applikationen
+kombiniert werden sollten. Sie wird als Java Web Start (kurz
+WebStart) bezeichnet und ist seit dem
+JDK 1.4 fester Bestandteil jedes JDKs und JREs. Java Web Start bietet
+die Möglichkeit, Applikationen über einen Web-Server
+automatisch zu laden und zu aktualisieren, ohne dass dazu eine lokale
+Installation oder das manuelle Einspielen eines Softwareupdates erforderlich
+wäre. Sie kombiniert so die Installationsfreiheit von Applets
+mit der Geschwindigkeit und Flexibilität von Java-Applikationen.
+Wir wollen uns einmal ansehen, wie das Ganze funktioniert:
+
+
+Die hier skizzierte Vorgehensweise beschreibt die Nutzungsmöglichkeiten
+von Java Web Start nur in Ansätzen. Tatsächlich bietet diese
+Technologie weit mehr Möglichkeiten, als hier erläutert
+werden könnte. So ist es beispielsweise möglich, die Anwendung
+in separate Teile zu zerlegen, die erst bei Bedarf geladen werden.
+Teile von Anwendungen lassen sich versionieren und werden nur dann
+aktualisiert, wenn eine neuere Version zur Verfügung steht. Man
+kann Applikationen auch signieren, um ihnen den Zugriff auf den kompletten
+Arbeitsplatz zu ermöglichen. Ohne Signatur laufen sie - ähnlich
+wie Applets - lediglich in einer »Sandbox« ab, in der sie
+nur beschränkte Zugriffsmöglichkeiten auf lokale Ressourcen
+haben. Weitere Informationen dazu werden in Abschnitt 13.5.3
+gegeben.
+
+
+Ein Großteil dieser Möglichkeiten wird im Java Network
+Launching Protocol beschrieben, das
+über die Download-Seite der WebStart-Homepage heruntergeladen
+werden kann. Es findet sich wie alle anderen WebStart-Ressourcen und
+-Dokumentationen auf http://java.sun.com/products/javawebstart/index.html.
+Wir wollen uns in diesem Abschnitt die Aufgabe stellen, das Beispielprogramm
+JTree 3 aus Listing 38.13
+in eine WebStart-Applikation zu verwandeln. Der Übersichtlichkeit
+halber erstellen wir dazu ein Unterverzeichnis wstest,
+in dem wir alle benötigten Dateien sammeln. Auf der DVD zum Buch
+befindet sich dieses unterhalb der Beispieldateien, also direkt im
+Verzeichnis examples. Da es auf der DVD
+bereits mit allen benötigten Dateien gefüllt ist, sind die
+nachfolgend beschriebenen Schritte (bei Verwendung dieses Verzeichnisses)
+redundant. Zum Lernen sollten sie aber dennoch nachvollzogen werden.
+
+
+Zunächst kopieren wir die Dateien Listing3813.java
+und WindowClosingAdapter.java in das
+Verzeichnis und kompilieren sie:
+
+
+Nach dem Kompilieren befinden sich die .class-Dateien
+Listing3813.class und WindowClosingAdapter.class
+in diesem Verzeichnis. Sie werden nun in ein jar-Archiv wstest.jar
+verpackt:
+
+
+Der nächste Schritt besteht darin, die Deskriptordatei zu unserem
+WebStart-Projekt anzulegen. Hierbei handelt es sich um eine XML-Datei
+mit der Erweiterung .jnlp,
+in der alle Informationen untergebracht sind, die der WebStart-Anwendungsmanager
+für das Laden, Ausführen und Darstellen der Applikation
+benötigt. Sie heißt in unserem Beispiel wstest.jnlp
+und hat folgenden Inhalt:
+
+
+
+
+
+
+ Titel
+ Inhalt
+ Suchen
+ Index
+ DOC
+ Handbuch der Java-Programmierung, 5. Auflage
+
+ <<
+ <
+ >
+ >>
+ API
+ Kapitel 13 - Strukturierung von Java-Programmen
+
+
+
+
+
+13.5 Java Web Start
+
+
+
+
+
+
+
+
+13.5.1 Einleitung und Funktionsweise
+
+
+
+
+
+
+
+![]()
+
+
+
+![]()
+
+
+
+
+
+ Hinweis
+
+
+
+
+
+
+
+
+![]()
+
+![]()
+
+
+
+![]()
+
+
+
+
+
+ JDK1.1-6.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+![]()
+
+
+
+![]()
+
+
+
+
+
+ Hinweis
+
+
13.5.2 Erstellen einer WebStart-Applikation
+
+
+
+
+Erzeugen der jar-Dateien
+
+
+javac *.java
+
+
+
+
+jar cvf wstest.jar Listing3813.class WindowClosingAdapter.class
+
+
+
+
+
+
+Anlegen der Deskriptordatei
+
+
+
+
+Listing 13.10: Eine WebStart-Deskriptordatei
+
+
+
+
+
+001 <?xml version="1.0" encoding="utf-8"?>
+002
+003 <!-- JNLP File fuer HJP3 WebStart Demo-Applikation -->
+004 <jnlp codebase="http://localhost:7777/" href="wstest.jnlp">
+005
+006 <information>
+007 <title>HJP3 WebStart Demo Application</title>
+008 <vendor>Guido Krueger</vendor>
+009 <homepage href="http://www.javabuch.de"/>
+010 <description>HJP3 WebStart Demo Application</description>
+011 <icon href="wstest.gif"/>
+012 <offline-allowed/>
+013 </information>
+014
+015 <information locale="de">
+016 <description>HJP3 WebStart Demo-Applikation</description>
+017 <offline-allowed/>
+018 </information>
+019
+020 <security>
+021 <!-- <all-permissions/> -->
+022 </security>
+023
+024 <resources>
+025 <j2se version="1.3+"/>
+026 <jar href="wstest.jar"/>
+027 </resources>
+028
+029 <application-desc main-class="Listing3813"/>
+030
+031 </jnlp>
+
+
+Die Datei besteht aus dem jnlp-Element +und vier Deskriptoren. Das jnlp-Element +enthält die Attribute codebase +und href. In codebase +wird das Basisverzeichnis für alle relativen URLs angegeben, +href ist die Lokation der jnlp-Datei +selbst. localhost:7777 bedeutet, +dass auf dem eigenen Rechner ein Web-Server auf TCP-Port 7777 läuft. +Wir werden später noch zeigen, wie der in Abschnitt 46.3.3 +vorgestellte ExperimentalWebServer +für diesen Zweck verwendet werden kann. Alle URLs innerhalb der +Datei können entweder absolut oder relativ zur codebase +angegeben werden. + +
+Die vier Deskriptoren haben folgende Bedeutung: +
+Das information-Element kann +ein optionales locale-Argument +haben und mehrfach vorhanden sein. So lassen sich Angaben machen, +die nur für eine bestimmte Sprachversion gelten. In unserem Beispiel +gibt es ein zweites information-Element, +in dem die description in deutscher +Sprache angegeben wird. Als mögliche Werte für das locale-Argument +können die in Abschnitt 17.4 +erläuterten Sprachen-/Länderstrings der Locale-Klasse +verwendet werden. +
+
![]() |
+![]() |
+
+
+ +Anmerkung: das offline-allowed-Element +wird hier nur deshalb dupliziert, weil es auf Grund eines Bugs in +der zum JDK 1.4 gehörenden WebStart-Version 1.0.1 nicht vererbt +wurde. Laut BugParade sollte dieser Fehler ab WebStart 1.2 behoben +sein. |
+
+
|
+![]() |
+
+Zunächst benötigen wir für unsere Beispielapplikation
+einen Web-Server. Der Einfachheit halber wollen wir dazu den in Abschnitt 46.3.3
+vorgestellten ExperimentalWebServer
+verwenden. Wir kopieren dazu die Datei ExperimentalWebServer.java
+aus dem Verzeichnis examples
+ebenfalls in unser Beispielverzeichnis und übersetzen sie:
+
+
+javac ExperimentalWebServer.java
+
+
+
+
![]() |
+
+
+ +Soll ein anderer Web-Server verwendet werden, ist es wichtig, den +Mime-Typ für jnlp-Dateien korrekt zu konfigurieren. Der Server +muss eine Datei mit der Erweiterung .jnlp +stets mit dem Mime-Typ application/x-java-jnlp-file +an den Client übertragen. Andernfalls könnte es sein, dass +der WebStart-Applikationsmanager nicht korrekt aufgerufen wird. In +unserem ExperimentalWebServer +ist dieser Typ bereits vorkonfiguriert, zusätzliche Anpassungen +sind daher nicht nötig. |
+
+
|
+![]() |
+
+Wir wollen nun noch eine einfache HTML-Datei wstest.html +zum Starten der WebStart-Applikation erstellen. Sie enthält im +wesentlichen einen Link auf die jnlp-Datei: + + +
+
+
++001 <html> +002 +003 <head> +004 <title>HJP3 WebStart Demo Application</title> +005 </head> +006 +007 <body> +008 +009 <h2>HJP3 WebStart Demo Application</h2> +010 +011 <a href="wstest.jnlp">Anwendung laden/starten</a> +012 +013 </body> +014 +015 </html>+ + |
+
+Zusätzlich müssen wir die in der jnlp-Datei angegebene Icon-Datei
+wstest.gif in unser Beispielverzeichnis
+kopieren. Anschließend können wir den Web-Server starten:
+
+
+java ExperimentalWebServer 7777
+
+
+
+
+
+
+
+Zum erstmaligen Starten der Anwendung wird die Webseite mit dem Link +auf die jnlp-Datei aufgerufen: +
+ +
+Abbildung 13.3: Die Startdatei der WebStart-Anwendung im Browser
+ ++Wird nun der Link »Anwendung laden/starten« angeklickt, +lädt der Browser die jnlp-Datei und ruft als zugehörige +Applikation den WebStart-Applikationsmanager auf. Dieser liest die +Datei ein und lädt alle darin beschriebenen Ressourcen. Anschließend +wird die Applikation gestartet, und wir sehen das in Abbildung 38.10 +gezeigte Programm. + +
+Beim Herunterladen hat der WebStart-Applikationsmanager alle Dateien +der Anwendung in seinen lokalen Cache kopiert. Die HTML-Datei wird +nun zum Starten nicht mehr unbedingt benötigt. Stattdessen kann +der WebStart-Applikationsmanager direkt aufgerufen werden. Nach einem +Klick auf den Menüpunkt »Ansicht.Heruntergeladene Anwendungen« +stellt er sich wie folgt dar: +
+ +
+Abbildung 13.4: Der WebStart-Applikationsmanager
+ ++Durch Drücken des »Starten«-Buttons wird unsere Anwendung +gestartet. Die internen Abläufe unterscheiden sich dabei nicht +von denen beim Starten über den Link im Browser. Zunächst +wird stets die jnlp-Datei geladen und alle darin beschriebenen Ressourcen +überprüft bzw. aktualisiert. Sind alle Dateien verfügbar, +wird die Anwendung gestartet. Taucht ein Problem auf, bricht WebStart +den Startvorgang ab und gibt eine Fehlermeldung aus. Wir wollen hier +nicht weiter auf Details eingehen; der WebStart-Applikationsmanager +ist einfach aufgebaut, und seine Funktionen sind weitgehend selbsterklärend. + +
+Wird eine WebStart-Anwendung das zweite Mal gestartet, fragt der Anwendungsmanager, +ob die Anwendung auf dem Desktop bzw. im Startmenü verankert +werden soll. Stimmt der Anwender zu, kann sie anschließend auch +auf diesem Weg gestartet werden. +
+
![]() |
+
+
+ +Nachdem die Anwendung im lokalen Cache gespeichert wurde, kann sie +auch offline betrieben werden, d.h. ohne den auf Port 7777 laufenden +Webserver. Sie kann dann zwar nicht mehr über den Link im Browser +gestartet werden, aber die drei anderen Wege stehen ihr noch offen. +Stellt WebStart beim Aufruf einer Applikation fest, dass die in der +jnlp-Datei genannten Ressourcen nicht erreichbar sind, verwendet er +die lokalen Kopien und startet die Anwendung aus dem Cache. Das ist +allerdings nur möglich, wenn in der jnlp-Datei das Element offline-allowed +gesetzt wurde. War das nicht der Fall, kann die Anwendung nicht offline +gestartet werden. |
+
+
|
+![]() |
+
+Eingangs wurde schon erwähnt, dass unsignierte WebStart-Applikationen +nur eingeschränkten Zugriff auf lokale Systemressourcen haben. +Zwar ist - anders als bei Applets - der Aufruf von System.exit +erlaubt. Dennoch gibt es einige Einschränkungen: +
+Damit unsignierte WebStart-Anwendungen dennoch ein gewisses Maß +an praxisrelevanter Funktionalität anbieten können, stellt +die WebStart-Laufzeitumgebung einige Services +zur Verfügung, über die Anwendungen in kontrollierter Weise +auf Systemressourcen zugreifen können: +
+
![]() |
+![]() |
+
+
+ +All diese Services sind insofern als relativ sicher anzusehen, als +sie dem Programm entweder nur sehr beschränkten Zugriff auf Systemressourcen +erlauben (z.B. ClipboardService, +PersistenceService) +oder der Anwender per GUI-Dialog ihrer Benutzung zustimmen muss und +somit selbst entscheiden kann, welche konkreten Ressourcen verwendet +werden (z.B. FileOpenService, +FileSaveService, +PrintService). + + +Dennoch sollten unsignierte WebStart-Applikationen aus potentiell +unsicheren Quellen mit der nötigen Vorsicht verwendet werden. +Einerseits ist nicht auszuschließen, dass man als Anwender im +Eifer des Gefechts einmal unbeabsichtigt einer Service-Nutzung zustimmt, +die später Schaden anrichtet. Andererseits sind Denial-of-Service-Attacken +nicht auszuschließen. Hierbei verwendet eine bösartige +Anwendung eine Ressource in so hohem Maße, dass sie für +den ordnungsgemäßen Betrieb anderer Anwendungen nicht mehr +ausreichend zur Verfügung steht. Beispiele sind etwa Programme, +die 100 Prozent CPU-Last verursachen oder solche, die das Dateisystem +durch Erzeugen riesiger Dateien zum Überlauf bringen. Gegen derartige +Programme bieten auch die Service-Einschränkungen der WebStart-Applikationen +keinen Schutz. |
+
+
|
+![]() |
+
+In diesem Abschnitt wollen wir uns ein einfaches Beispiel für +die Verwendung des jnlp-APIs ansehen. Ein Programm soll dem Anwender +einen DateiÖffnen-Dialog präsentieren und den Inhalt der +darin ausgewählten Datei auf der Konsole ausgeben (sie läßt +sich im WebStart-Applikationsmanager im Dialog »Datei.Einstellungen.Erweitert« +sichtbar machen). Auf die übrigen Services wollen wir nicht weiter +eingehen, denn ihre Anwendung ähnelt der hier beschriebenen. +Weitere Details zu den Services sind in der jnlp-API-Dokumentation +zu finden. + +
+Soll ein WebStart-Programm auf einen jnlp-Service zugreifen, muss +dieser zunächst mit Hilfe der Klasse ServiceManager +aus dem Paket javax.jnlp +angefordert werden: +
+
+
++public static java.lang.Object lookup(java.lang.String name) + throws UnavailableServiceException ++ + |
++javax.jnlp.ServiceManager | +
+Die Methode lookup +erwartet einen String +mit dem Servicenamen als Argument. Dies muss ein qualifizierter Klassenname +sein, etwa »javax.jnlp.FileOpenService« oder »javax.jnlp.PrintService«. +Kann der Service nicht zur Verfügung gestellt werden (die meisten +Services sind optional und müssen nicht von allen WebStart-Clients +implementiert werden), wird eine Ausnahme des Typs UnavailableServiceException +ausgelöst. Andernfalls wird der Rückgabewert auf den gewünschten +Typ konvertiert und kann dann verwendet werden. +
+
![]() |
+
+
+ +Alle Klassen aus dem jnlp-API befinden sich im Paket javax.jnlp. +Dieses ist - auch in der Version 1.4 - nicht Bestandteil des JDKs, +sondern muss separat heruntergeladen werden. Es ist wie alle anderen +WebStart-Ressourcen im Download-Bereich von http://java.sun.com/products/javawebstart/index.html +zu finden. Benötigt wird meist lediglich die Datei jnlp.jar, +die zum Kompilieren in den Klassenpfad einzubinden ist. Zur Laufzeit +muss sie nicht explizit angegeben werden, sondern wird vom WebStart-Applikationsmanager +zur Verfügung gestellt. |
+
+
|
+![]() |
+
+Die nun folgenden Schritte sind Service-spezifisch. Der FileOpenService +stellt beispielsweise folgende Methode zur Verfügung, um einen +DateiÖffnen-Dialog zu erzeugen: +
+
+
++public FileContents openFileDialog( + java.lang.String pathHint, + java.lang.String[] extensions +) + throws java.io.IOException ++ + |
++javax.jnlp.FileOpenService | +
+Das erste Argument pathhint +ist ein Vorgabewert der Anwendung für das Verzeichnis, aus dem +die Datei geladen werden soll. Das zweite Argument enthält eine +Liste von Datei-Erweiterungen, die standardmäßig angezeigt +werden. Der Rückgabewert ist entweder null, +falls der Dialog abgebrochen wurde, oder er enthält ein FileContents-Objekt +für die vom Anwender ausgewählte Datei. Dieses kann verwendet +werden, um Informationen über die Datei abzufragen sowie um Eingabe- +oder Ausgabestreams zum Lesen und Schreiben der Datei zu beschaffen. + +
+Wichtige Methoden der Klasse FileContents +sind: +
+
+
++public java.lang.String getName() + throws java.io.IOException + +public long getLength() + throws java.io.IOException + +public boolean canRead() + throws java.io.IOException + +public boolean canWrite() + throws java.io.IOException + +public InputStream getInputStream() + throws java.io.IOException + +public OutputStream getOutputStream(boolean overwrite) + throws java.io.IOException ++ + |
++javax.jnlp.FileContents | +
+getName +liefert den Namen der Datei, und mit getLength +kann ihre Länge bestimmt werden. Mit canRead +und canWrite +kann festgestellt werden, ob Lese- bzw. Schreibzugriffe erlaubt sind. +getInputStream +beschafft einen InputStream, +mit dem die Datei gelesen werden kann, und getOutputStream +stellt einen OutputStream +zum Schreiben der Datei zur Verfügung. Das Argument overwrite +gibt dabei an, ob der bestehende Inhalt überschrieben oder die +neuen Daten an das Ende der bestehenden Datei angehängt werden +sollen. + +
+Nach diesen Vorbemerkungen können wir uns nun das Beispielprogramm +ansehen: + + +
+
+
+
+001 /* WebStartTest2.java */
+002
+003 import java.io.*;
+004 import javax.jnlp.*;
+005
+006 public class WebStartTest2
+007 {
+008 public static void main(String[] args)
+009 {
+010 try {
+011 //FileOpenService anfordern
+012 FileOpenService fos = (FileOpenService)ServiceManager.lookup(
+013 "javax.jnlp.FileOpenService"
+014 );
+015 //DateiÖffnen-Dialog aufrufen
+016 FileContents fc = fos.openFileDialog(null, null);
+017 if (fc == null) {
+018 System.err.println("openFileDialog fehlgeschlagen");
+019 } else {
+020 //Dateiinhalt auf der Konsole ausgeben
+021 InputStream is = fc.getInputStream();
+022 int c;
+023 while ((c = is.read()) != -1) {
+024 System.out.print((char)c);
+025 }
+026 is.close();
+027 }
+028 } catch (UnavailableServiceException e) {
+029 System.err.println("***" + e + "***");
+030 } catch (IOException e) {
+031 System.err.println("***" + e + "***");
+032 }
+033 //10 Sekunden warten, dann Programm beenden
+034 try {
+035 Thread.sleep(10000);
+036 } catch (InterruptedException e) {
+037 }
+038 System.exit(0);
+039 }
+040 }
+
+ |
++WebStartTest2.java | +
+Das Programm kann wie im vorigen Abschnitt gezeigt übersetzt, +in eine WebStart-Applikation verpackt und ausgeführt werden. +Wenn die Konsole im WebStart-Applikationsmanager aktiviert wurde, +kann mit dem Programm jede beliebige Datei gelesen werden - vorausgesetzt, +der Anwender stimmt im DateiÖffnen-Dialog zu. +
| Titel + | Inhalt + | Suchen + | Index + | DOC + | Handbuch der Java-Programmierung, 5. Auflage, Addison +Wesley, Version 5.0.1 + |
| << + | < + | > + | >> + | API + | © 1998, 2007 Guido Krüger & Thomas +Stark, http://www.javabuch.de + |