Rich Client Entwicklung mit Java

Werbung
Rich Client Entwicklung mit Java
Kai Aras
Medieninformatik - SS 09
1
1. Rich-Client Entwicklung mit Java........................................................ 4
2. Was ist ein Rich-Client ?.............................................................................. 4
3. Was ist eine Rich-Client-Platform ?............................................................. 4
4. Wiso eine Rich-Client-Platform ?................................................................. 4
5. Netbeans Platform..................................................................................6
6. Geschichte der Netbeans Platform.............................................................. 6
7. Netbeans Platform Architektur Alles ist ein Modul........................................ 6
8. Netbeans Classloader System......................................................................... 7
9. Beispiel Netbeans IDE......................................................................................8
10.Grundliegende Konzepte............................................................................. 9
11. Strenge Modularisierung.................................................................................. 9
12. Loose Coupling................................................................................................ 9
13. Lazy Loading.................................................................................................. 10
14. Deklarative Beschreibung (System Filesystem)............................................. 10
15.Auszug aus Modulen und APIs.................................................................. 11
16. File Systems API............................................................................................ 11
17. Data Systems API........................................................................................... 11
18. Lookup API..................................................................................................... 11
19. Nodes API .....................................................................................................
12
20. Explorer API.................................................................................................... 13
21. Visual Library API........................................................................................... 13
2
22.Anpassung und Deployment...................................................................... 15
23. Netbeans Module (NBM)................................................................................ 15
24. Zip Distribution............................................................................................... 15
25. Mac OSX Application......................................................................................15
26. Java WebStart (JNLP).................................................................................... 15
27.Quellen................................................................................................. 17
3
Rich-Client Entwicklung mit Java
Was ist ein Rich-Client ?
Der Begriff Rich Client stammt aus der Client-Server Architektur und beschreibt eine
Anwendung bei der die eigentliche Datenverarbeitung lokal, also vom client, anstatt vom
entfernten Server ausgeführt wird.
In der Regel besitzt ein Rich-Client eine grafische Benutzeroberfläche (GUI) und bietet die
Möglichkeit, neue Funktionalitäten in Form vom Modulen oder Plugins einzubinden.
Grundsätzlich besitzt ein Rich-Client die folgenden Eigenschaften:
a.
b.
c.
d.
e.
f.
Flexible und modulare Architektur
kann leicht an den Benutzer angepasst werden
ist Platformunabhänig
unterstützt sowohl Online- wie auch Offline-Arbeiten
bietet Möglichkeiten zum einfachen Deployment
bietet Möglichkeiten den Client zu Aktualisieren
Was ist eine Rich-Client-Platform ?
Eine Rich Client- Platform ist ein Framework sowie eine Laufzeitumgebung zur Entwicklung von
Rich-Client Anwendungen.
Da sich viele grundsätzlichen Funktionalitäten und Komponenten, wie Menus, Toolbars,
Splash-Screen, Konfigurations-Verwaltung oder Hilfe-System in beinahe allen DesktopAnwendungen wiederfinden, stellt eine Rich-Client-Platform ein Framework dar, mit hilfe
dessen genau diese generischen Aufgaben einer Desktop-Anwendung schnell, einfach und
stabil umgesetzt werden können, und dem Entwickler so mehr zeit für die eigentliche
Anwendungslogik bleibt.
Aufgrund der modularen Architektur einer Rich-Client-Platform, erfolgt die Entwicklung einer
Anwendung auf Basis einer Rich-Client-Platform in einzelnen Modulen.
Ein Modul kapselt eine bestimmte Funktionalität und definiert seine öffentlichen Schnittstellen,
sowie eventuelle Abhänigkeiten zu anderen Modulen und stellt so einen unabhänigen,
erweiterbaren Bestandteil der modularen Architektur der Platform dar.
Wiso eine Rich-Client-Platform ?
Die Verwendung einer Rich-Client-Platform zur Entwicklung von Desktop-Anwendungen bringt
enorme Vorteile mit sich. Nachfolgende Auflistung gibt einen kurzen Überblick über die 4
überzeugendsten Argumente die für die Verwendung einer Rich-Client-Platform sprechen.
•
kürzere Entwicklungszeit
Durch die vielzahl an zur verfügung gestellen APIs können nebensächliche
Funktionalitäten weitaus schneller umgesetzt und ausserdem auch wiederverwendet
werden.
•
Konsistente Benutzeroberfläche
Die Bewertung von Software unter dem Aspekt der Usability spielt einer immer größere
Rolle, so stellen Rich-Client-Platformen in der Regel Frameworks zur
Oberflächengestaltung bereit, welche diesen Aspekt bereits berücksichtigen.
•
Software Updates
Der von grund auf modulare Aufbau einer Rich-Client-Platform erleichtert das
umsetzten, bzw Durchführen von Software Updates ungemein. Durch die strenge
Modularisierung können Neuerungen Modulweise unabhängig von unterschiedlichen
Teams entwickelt und andererseits auch unabhängig von einander ausgeliefert werden.
•
Platformunabhänigkeit
Rich-Client-Platformen basieren auf gut durchdachten Standarts und
wiederverwendbaren Komponenten, so ist beispielsweise eine Anwendung die auf einer
java-basierten Rich-Client-Platform basiert automatisch auf einer vielzahl von Systemen
lauffähig. Voraussetzung ist natürlich eine vorhandene Java- Virtual Machine, bzw Java
Runtime Environment.
5
Netbeans Platform
Geschichte der Netbeans Platform
Anfangs noch ohne RCP-Platform und unter dem an Delphi angelehnten Namen Xelfi, erblickte
Netbeans 1997 in Tschechien das Licht der Welt.
Eine Gruppe Studenten hatte sich damals zur Aufgabe gemacht die erste komplett in Java
geschriebene Entwicklungsumgebung zu erschaffen.
Das daraus entstandene und später komerzialisierte Produkt Netbeans Developer X2 wurde
schließlich ende der 90er Jahre von den Java machern selbst, Sun Microsystems übernommen
und kaum ein halbes Jahr später schließlich auch "open sourced". Hier beginnt die eigentliche Geschichte der Netbeans Platform,
nach der Übernahme von Sun und Veröffentlichung der Quellen wurde die Netbeans Runtime
rasch als Basis zum Bau beliebiger Desktopanwendungen, fern ab von IDE-Anwendungen
gebraucht.
Daraufhin wurde in den folgenden Jahren, seitens Sun, viel Zeit in die entwicklung der
Netbeans Platform gesteckt.
Netbeans Platform Architektur
Alles ist ein Modul
Im Kontext der Netbeans-Platform ist alles ein Modul, d.h. das Prinzip der Modularisierung wird
bis in den Kern der Platform selbst, dem Runtime Container, angewandt. So besteht nämlich
dieser ebenfalls aus einzelnen Modulen, die zusammen die minimalste Form einer Rich-ClientAnwendung bilden.
1. Bootstrap
initales Modul, erzeugt einen Boot-Classloader welcher das Startup Modul lädt und ausführt.
2. Startup
initalisiert Module System und File System
3. Module System API
verwaltet installierte Module und deren Abhänigkeiten
4. File System API
stellt ein platformunabhäniges virtuelles Dateisystem zur verfügung.
5. Utilities API
stellt diverse Basisfunktionalitäten u.a das Lookup für Intermodul-Kommunikation bereit.
6
Netbeans Classloader System
Voraussetzung für die modulare Architektur und damit auch der Kapselung in Module ist das
Netbeans Classloader System.
Das System arbeitet mit drei unterschiedlichen Classloadern, dem:
o
o
o
Original Classloader
Module Classloader
System Classloader
wobei der Original Classloader beim Start der Anwendung vom zughörigen Application
Launcher erzeugt wird, und zunächst sämtliche Klassen und Resources vom original
CLASSPATH lädt.
Module- und System Classloader sind im gegensatz zum Original Classloader multiparent
Classloader, können also mehrere Parent-Classloader besitzen.
Findet der Original Classloader anhand seiner Manifest-Information ein Modul, erzeugt er dafür
eine Instanz des Module Classloaders,
dieser wiederum lädt dann die eigentlichen Klassen des Moduls.
Ein Modul Classloader besitzt neben dem Original Classloader sämtliche Classloader der
Module zu denen eine Abhänigkeit besteht als Parent.
7
Der System Classloader besitzt als Parent die Classloader aller bekannten Module, lädt
allerdings keine Resourcen selbstständig, stattdessen kann er verwendet werden um
Resourcen aus unbekannten Modulen zu laden.
Beispiel Netbeans IDE
Referenzbeispiel für eine Rich-Client Anwendung auf Basis der Netbeans Platform ist sicherlich
die weitverbreitete Entwicklungumgebung Netbeans IDE. Generell kann man sagen, die
Netbeans IDE setzt sich zusammen aus der Netbeans Platform und einem Satz von BasisModulen die grundsätzliche IDE Funktionalitäten zur verfügung stellen.
Darauf aufbauend existieren Module oder Module-Suites, welche die Netbeans IDE um
konkrete Sprach-Umgebungen wie Java, C/C++, SOA oder Python erweitern. Siehe
nachfolgende Grafik.
Aufgrund dieser Modularen Architektur ist es möglich verschiedene "schlankere" Distributionen
der Entwicklungsumgebung wie Java- oder Python-only anzubieten.
8
Grundliegende Konzepte
Nachfolgend möchte ich einige der zentralen Konzepte der Netbeans Platform vorstellen.
Strenge Modularisierung
Damit große und vorallem komplexe Anwendungen auch über die Zeit wart- und erweiterbar
bleiben bietet sich das Konzept der Modularisierung an. Wie bereits erwähnt, lässt sich die
Netbeans Platform durch das Kapseln von Funktionen in Modulen erweitern, dies bringt einige
Vorteile mit sich.
Loose Coupling
Basierend auf der Modularen Architektur der Netbeans Platform existiert das so genannte
Lookup (mehr hier zu in Kapittel ...)
Eine der Hauptaufgaben des Lookups ist das Suchen und Finden von Services, das Lookup
fungiert also als dynamischer Service Locator und ermöglicht so die Trennung von Service
Interface und Service Provider. Durch diese Trennung kann ein ModulA Funktionalität aus einem
ModulB nutzen, ohne dessen Implementation zu kennen, oder anders gesagt, es entsteht eine
lose Kopplung zwischen diesen Modulen.
Um dies zu verdeutlichen möchte ich hierzu ein kleines Beispiel aufführen.
Wir nehmen an wir bauen einen Text-Editor und wollen dem Benutzer den Export in
verschiedene Dateiformate ermöglichen.
Um die Vorteile des Lookups nutzen zu können und somit Service Interface und Service
Provider unabhänhig von einander bleiben, definieren wir 3 Module:
1. Modul A: export.spi (Service Provider Interface)
2. Modul B: exportDOC (Service Provider Implementation)
exportPDF
exportRTF
exportTXT
3. Modul C: editor (unser Text-Editor)
Um die export Funktionalität nun in ModulC, also unserem Editor nutzen zu können, definieren
wir eine Abhänigkeit von ModulC zu ModulA, also vom Editor zum Service Provider Interface.
Damit unsere Service Provider Implementierungen das zugehörige Service Provider Interface
auch implementieren können, müssen wir zusätzlich eine Abhänigkeit von ModulB nach
9
ModulA definieren.
Durch diese Trennung ist es jetzt möglich vom Editor aus, sämtliche Service Provider
Implementierungen aus ModulB zu verwenden, ohne dass eine Abhänigkeit zu diesem Modul
besteht, sie sind also entkoppelt.
Lazy Loading
Lazy Loading ist ein Design Pattern, das immer dann eingesetzt wird wenn es von Vorteil ist
eine Anwendung nicht bereits beim Anwendungsstart komplett zu initialisieren.
Stattdessen werden bestimmte Objekte erst denn initialisiert, wenn sie tatsächlich gebraucht
werden.
Es existiert auch ein gegenteiliges Pattern, genannt Eager Loading.
So würde ein Filebrowser nach dem Lazy Pattern den Inhalt eines Ordners erst dann
initialisieren, wenn der User diesen sehen möchte, wärend bei der Verwendung des Eager
Patterns sofort das komplette vom Browser erfasste Dateisystem initialisiert werden würde.
Die Vor- bzw Nachteile dieser Design Patterns liegen auf der Hand, und sollten je nach
Anwendungsfall nicht unbeachtet gelassen werden. So würde ein Filebrowser nach dem EagerPattern einen erheblichen speicher-bedarf zur folge haben, wärend dies bei der Verwendung
des Lazy-Patterns kein Problem darstellen würde, wäre stattdessen bei Ordnern mit vielen
Kind-Elementen mit eventuellen wartezeiten zu rechnen.
Deklarative Beschreibung (System Filesystem)
Damit Anwendungen auf Basis der Netbeans Platform möglichst flexibel und erweiterbar
bleiben, muss die Möglichkeit bestehen Änderungen oder Erweiterungen nicht nur über
Änderungen am Code selbst einzubringen.
Hierzu besteht die Möglichkeit, Fenster, Menus, Aktionen, Toolbars usw. durch blose
deklarative Beschreibungen in einer Art Konfigurationsdatei einzubinden.
Konkret benutzt man dazu das System Filesystem.
Das System Filesystem ist ein virtuelles XML-Filesystem und besteht aus vielen einzelnen
Layer-Files.
Jedes Modul, dass deklarativ etwas zur Anwendung beitragen will, enthält ein solches LayerFile, im allgemeinen bezeichnet als XML-Layer und konkret benannt als layer.xml.
Beim start der Anwendungen werden sämmtliche XML-Layer zu einem XML-Filesystem
gemerged, und bilden so das System-Filesystem.
10
Auszug aus Modulen und APIs
Im folgenden Abschnitt möchte ich einge der zentralen APIs ,der Netbeans Platform vorstellen.
File Systems API
Die Netbeans File Systems API bietet transparenten Zugriff auf Daten aller Art, bzw aus
Dateisystemen aller art. So können mit ihrer Hilfe lokale Dateien, genau so wie entfernte
Dateien oder Elemente in einem XML-Baum verwaltet werden.
Dabei wird der Zugriff auf Daten nochmals abstrahiert und durch ein einheitliches Interface
dargestellt.
Die Klasse FileObject ist eine abstrakte Wrapper-Klasse und erweitert die standart JDK-FileKlasse um diverse Funktionen, ihre Implementation wird vom jeweiligen Filesystem
bereitgestellt.
Data Systems API
Die DataSystems API, bildet eine logische Schicht, aufbauhend auf der FileSystems API.
Zentrales Element ist hier die abstrakte Klasse DataObject.
Wärend einem FileObject relativ egal ist, mit welchen DateiTypen es arbeitet stellt ein
DataObject einen Wrapper auf ein FileObject eines bestimmten Typs dar.
Verwendung findet dies z.B. bei der Einbindung eines neuen, oder speziellen Dateitypen
anhand von Metainformationen oder Dateierweiterung in eine Platform-Anwendung.
Lookup API
Das Lookup Konzept findet fast überall innerhalb der Netbeans Platform verwendung und ist
dementsprechend eines der wichtigstens Werkzeuge beim Umgang mit der Netbeans Platform.
Vereinfacht, kann man das Lookup mit einer Map vergleichen, die als Key - Klassen, also
Class-Objekte und als zugehörige Werte deren Instanzen beinhaltet.
Sinn und Zweck dieses Konzeptes ist die Entkopplung von Komponenten, oder anders gesagt,
das ermöglichen von Intermodulkommunikation ohne feste Abhänigkeiten definieren zu
müssen.
Die Verwendung dieses Konzepts bringt sehr viele Vorteile mit sich, so ergibts sich aus der
definitions des Lookups implizit auch seine Typsicherheit, denn da als Key hier Class-Objekte
11
anstatt Strings verwendet werden, ist der Typ der zurückgegebenen Instanz bereits festgelegt,
Fehler wie ClassCastExceptions können daher nicht auftreten und auf manuelle Typchecks im
Code, kann verzichtet werden.
Ausserdem bietet sich das Lookup zum finden von Service Providern an und ermöglicht
gleichermaßen Konzepte wie Lazy Loading oder oder das bereits erwähnte Loose Coupling.
Nodes API
Die Nodes API stellt einen graphischen
Präsentations Layer dar, so hat ein Node die
Aufgabe Daten, Aktionen, Eigenenschaften oder
andere Funktionalitäten an der Benutzeroberfläche
zur Verfügung zu stellen.
Um dies zu verdeutlichen stellt man sich am besten
einen Dateibrowser vor, jeder Ordner und jede Datei
stellen einen Node dar, dabei muss ein Node aber
nicht zwangsläufig ein Datenobjekt repräsentieren,
so könnte z.b eine Verknüpfung durch ein
ProxyNode dargestellt werden.
Standartmäßig stellt jeder Node bereits eine Vielzahl
von Funktionen zur verfügung, so besitzen Nodes
von haus aus u.a. bereits ein Icon, ein ContextMenu,
einen html-kompatiblen DisplayName, Properties
und viele mehr, ausserdem kann ein Node wiederum
eine Menge von ChildNodes beinhalten, wodurch
hierarchische Baumstrukturen ermöglicht werden,
wie beispielsweise in jedem Datei-Browser zu finden
sind. Die Nodes API ist ein sehr mächtiges Werkzeug und
kann im übrigen wie sämmtliche anderen Platform
Libraries auch "standalone", also ausserhalb der
Netbeans Platform verwendet werden.
12
Explorer API
Die Explorer API ist eng verwandt mit der Nodes API, ihre Aufgabe ist die Verwaltung und
Darstellung von Nodes.
Hierzu stellt die Explorer API diverse graphische Komponenten, sogenannte Explorer Views
bereit, mit hilfe derer verschiedene Ansichten auf einen Baum von Nodes erstellt werden
können.
Die verwaltung einer Explorer View und eines Node-Sets übernimmt die Klasse
ExplorerManager. Eine Instanz dieses Managers muss von der Parent-Komponente des
ExplorerViews zur verfügung gestellt werden, hierzu implementiert diese in der Regel das
Interface ExplorerManager.Provider, welches die Methode getExplorerManager(), die den
ExplorerManager zurück gibt, spezifiziert.
Dieses Vorgehen hat zur folge, dass ExplorerManager und ExplorerView in keinster Weiste
miteinander gekoppelt werden müssen, stattdessen sucht die ExplorerView selbstständig in
der Hierarchie seiner Parent-Komponenten nach einem geigneten ExplorerManager.
Verwendung findet dies beim Überwachen von Selektionen von Nodes in einer ExplorerView. Durch den Manager können selektierte Nodes inkl. deren Lookup automatisch in einem
eigenen Lookup zur verfügung gestellt werden und so für externe Klassen oder Module
zugänglich gemacht werden.
Visual Library API
Die Visual Library ist eine generische Bibliothek zur Visualisierung von Strukturen, wobei das
Haupteinsatzgebiert sicherlich die Visualisierung von Graphen in Form von graphischen
Modelierungs-Editoren, wie dem Netbeans- eigenen Visual Mobile- oder UML Editor ist.
Ähnlich wie bei Swing werden auch hier sämmtliche Komponenten baumartig aufgebaut und
verwaltet.
Die zentrale Klasse beim Umgang mit der Visual Library is die Basisklasse Widget.
Neben der Widget-Klasse spielt auch die Klasse Scene und ihre Subklassen eine große Rolle.
Die Klasse Scene selbst ist ebenfalls Subklasse von Widget und stellt den Root-Container einer
mit Hilfe der Visual Libarary erstellten Anwendung dar.
Die Subklasse ObjectScene von Scene, stellt eine Relation zwischen View, in Form von Widgets,
und einem zugehörigen Datenmodell vom Typ Object her.
Weiter existieren die generisch, abstrakten Subklassen GraphScene und GraphPinScene, die
auf ein Graphenmodell mit Knoten und Kanten bzw Knoten, Kanten und Pins abbilden, sowie
deren Implementierungen vom Typ String - GraphScene.StringGraph und
GraphPinScene.StringGraph.
Widgets können ähnlich wie bei Swing mit hilfe von Layouts und durch das hinzufügen von
13
Kind-Elementen, welche wiederum selbst Subklasse von Widget sind, gestaltet werden. Hierzu
existieren eine Reihe von Basis-Widgets, wie Label- oder ImageWidget, es ist jedoch auch
möglich ein Widget mit Hilfe der Java2D API selbst zu zeichnen.
Ausserdem können Widgets Aktionen Aufnehmen, auch hier bietet die Library bereits eine
Auswahl an Aktionen für Hover-,Edit-,Move- oder Connect-Events. Zum Erzeugen von Layouts und Aktionen existieren Factories, die bereits erzeugte Aktionsoder Layout-Klassen cachen und so wiederverwenden.
14
Anpassung und Deployment
Zur Anpassung und Auslieferung einer Netbeans Platform Anwendung werden mehrere
Möglichkeiten angeboten.
Netbeans Module (NBM)
Die Distribution als Netbeans Module, also als Erweiterung für eine bestehende NetbeansPlatform Anwendung, bietet sich an, wenn bereits eine Netbeans-Platform Anwendung
besteht, bzw verwendet wird.
Dabei kann es sich sowohl um eine Eigenentwicklung als auch um die bekannte Netbeans IDE
handeln.
Zip Distribution
Die Distribution in Form einer Zip-Distribution wird in der Regel dann verwendet, wenn bisher
kein Netbeans-Platform Anwendung benutzt wurde, bzw vorhanden war.
Hierbei wird eine komplette, lauffähige Anwendung generiert und anschließend als Zip Archiv
zur verfügung gestellt.
Eine solches Archiv lässt sich leicht verschicken, oder zum Download anbieten, ausserdem
beinhaltet es einen Application Launcher im .exe Format für Windows basierte Systeme, sowie
ein Shellscript .sh für Linux basierte Systeme.
Mac OSX Application
Auch der Mac-Nutzer kommt nicht zu kurz, ein eigenes Build-Target zur erstellung einer Mac
OSX Anwendung in Form eines .app Launchers kann ebenfalls, gesondert zu Windows/Linux
Distribution erstellt werden.
Java WebStart (JNLP)
Besonders attraktiv ist auch das Deployment via Java Webstart unter zuhilfename des Java
Network Launching Protocols (JNLP).
Hierbei erzeugt das Build-System ein so genanntes Web-Archive (.war), welches anschließend
auf einem Application Server mit Web-Container (bsp. Tomcat oder GlassFish) deployed
werden kann.
Der end-Benutzer kann die Anwendung dann aus seinem Web-Browser starten, wobei diese
15
dann vom Java Webstart Subsystem heruntergeladen und ausgeführt wird.
Ein wesentlicher Vorteil dieser Variante ist auch die ständig gebene aktualität der Software, so
wird die Anwendung beim wiederholten start nur dann erneut auf den lokalen Client heruntergeladen, wenn eine neuere Version zur verfügung steht, anderenfalls wird die lokal-gecachte
Kopie gestartet, und die Downloadzeit entfällt.
16
Quellen
[NBJDoc09a] http://bits.netbeans.org/dev/javadoc/org-openide-modules/org/openide/
modules/doc-files/classpath.html
[NBWiki07a] http://wiki.netbeans.org/DevFaqLookup
[NBWiki09a] http://wiki.netbeans.org/NetBeansDeveloperFAQ#sectionNetBeansDeveloperFAQ-Lookup
[NBWiki09b] http://wiki.netbeans.org/NetBeansDeveloperFAQ#sectionNetBeansDeveloperFAQ-FilesAndDataObjects
[NBWiki09c] http://wiki.netbeans.org/NetBeansDeveloperFAQ#sectionNetBeansDeveloperFAQ-NodesAndExplorer
[NBGraph09a] http://graph.netbeans.org/documentation.html
[Wiki09a] http://en.wikipedia.org/wiki/Lazy_loading
[Boe08] Heiko Böck, Netbeans Platform 6, Galileo Press 2008
[WG09] Geertjan Walenga's Blog - http://blogs.sun.com/geertjan/entry/
how_to_deploy_netbeans_platform
[NBxx] http://www.netbeans.org/about/history.html
17
Herunterladen