Modulare Anwendungen und die Lookup API - NetBeans

draindecorumSoftware and s/w Development

Aug 15, 2012 (5 years and 2 months ago)

658 views



Modulare Anwendungen und die Lookup API
Geertjan Wielenga
NetBeans Team
Deutschsprachige Überarbeitung, Aljoscha Rittner
NetBeans Dream Team
Certified Engineer Course
Die Notwendigkeit modularer Anwendungen
Certified Engineer Course
Die Notwendigkeit modularer Anwendungen
Certified Engineer Course
Die Notwendigkeit modularer Anwendungen
Certified Engineer Course
Die Notwendigkeit modularer Anwendungen

Anwendungen werden immer komplexer

Sie werden aus Einzelstücken zusammen
gesetzt
>
Frameworks, 3
rd
Party Bibliotheken, Legacy
Bibliotheken

Entwicklung durch verteilte Teams

Komponenten mit umfangreichen
Abhängigkeiten


Gesunde” Architektur erwartet:
>
Wissen über Abhängigkeiten und
>
Die Verwaltung der Abhängigkeiten
Certified Engineer Course
Die Entropie von Software

Version 1.0 ist sauber entwickelt...
Certified Engineer Course
Die Entropie von Software

Version 1.1... einige zweckmäßige
Erweiterungen und Hacks...
...wir werden das in 2.0 schon wieder
richten.
Certified Engineer Course
Die Entropie von Software

Version 2.0...nun ja...aber...es läuft!
Certified Engineer Course
Die Entropie von Software

Version 3.0... Hilfe! Jeder reparierte
Fehler erzeugt zwei weitere!
Certified Engineer Course
Die Entropie von Software

Version 4.0 ist sauber designed. Eine
komplette Neuentwicklung. Zwar ein Jahr
zu spät, aber es läuft...
Certified Engineer Course
Die Entropie von Software

Version 4.1... Das erinnert mich doch an
etwas?....
Certified Engineer Course
Die Entropie von Software

Fortsetzung folgt....
Certified Engineer Course
Modulare Anwendungen

Wissen um ihre Komponenten zur Laufzeit

Dürfen Komponenten während der
Laufzeit hinzufügen, entfernen und neu
laden

Müssen Abhängigkeiten zwischen
Komponenten erkennen

Bieten API Vereinbarungen zwischen
Komponenten

Laufen in einem
Runtime Container
Certified Engineer Course
Was macht ein Runtime Container?

Lebenszyklus der Anwendung
>
Startet und beendet die Anwendung
>
(De)installiert Module

Modul Verwaltung

Classloading und Modulisolation

Service Registry & Zugriffs API
Certified Engineer Course
Was ist der NetBeans Runtime Container?
Certified Engineer Course
Demo 1: NetBeans Runtime Container
Certified Engineer Course
Der NetBeans Runtime Container

Fünf NetBeans Platform Module
Nur diese 5 zusammen: compile & run,
mehr wird nicht benötigt.

Ausschließlich
diese Module werden von
allen NetBeans Platform Anwendungen
benötigt.

NetBeans Platform Anwendungen müssen
nicht (Rich) Client Applikationen sein

Es sind auch modulare Server
Anwendungen denkbar
>
z.B. mit dem CronJob Plugin zeitgesteuerte
Dienste ansteuern
Certified Engineer Course
Was ist ein NetBeans Module?

Nur ein JAR File – keine Magie
>
Es besitzt spezielle Manifest-Einträge für das
NetBeans Modul-System, die in den
Project Properties für Module Projekte
bearbeitet werden können.

Verteilt in einem NBM File
>
Grundsätzlich ein signiertes JAR File
>
Enthält Metadaten über das Modul
>
Darf 3
rd
Party JARs enthalten, oder alles
andere Notwendige für das Modul zur
Installation
Certified Engineer Course
Demo 2: Ein NetBeans Modul erstellen
Certified Engineer Course
Demo 3: Verteilen eines NetBeans Moduls
Certified Engineer Course
NetBeans Modul Manifest
Manifest­Version: 1.0
Ant­Version: Apache Ant 1.7.1
Created­By: 1.5.0_14­b03 (Sun Microsystems Inc.)
OpenIDE­Module­Public­Packages: ­
OpenIDE­Module­Module­Dependencies
: org.jdesktop.layout/1 > 1.7, org.n
 
etbeans.api.java/1 > 1.18, org.netbeans.api.java.classpath/1 > 1.0
OpenIDE­Module­Java­Dependencies
: Java > 1.5
OpenIDE­Module­Build­Version: 200907230101
OpenIDE­Module­Specification­Version
: 2.16.2.5.1.1
OpenIDE­Module
: org.netbeans.modules.java.editor/1
OpenIDE­Module­Implementation­Version: 5
OpenIDE­Module­Localizing­Bundle: 
org/netbeans/modules/java/editor/Bundle.properties
Certified Engineer Course
NetBeans Module Manifest
OpenIDE­Module­Layer: 
org/netbeans/modules/java/editor/resources/layer.xml
OpenIDE­Module­Requires: org.openide.modules.ModuleFormat1
OpenIDE­Module­Install
:
  
org/netbeans/modules/java/editor/JavaEditorModule.class
AutoUpdate­Show­In­Client: false
Certified Engineer Course
Runtime Container Aufgaben

Sicherstellen, dass Abhängigkeiten
aufgelöst sind
>
Auch mit der Notwendigkeit von
vorgegebenen Versionen

Verhindern von ungültigen
Abhängigkeiten
>
Falsche Version, falsches Betriebsystem (→
Token)

Erlauben von gültigen Abhängigkeiten


Booten” von Komponenten während der
Laufzeit
Certified Engineer Course
Modul Abhängigkeiten erzwingen
Certified Engineer Course
Demo 4: Abhängigkeits Verwaltung
Certified Engineer Course
Verwende vorhandene Runtime Container

Ruhe in Frieden
, Home-made Frameworks
1995-2009
1995-2009
Home-made
Home-made
Framework
Framework
Certified Engineer Course
Modul Abhängigkeiten
Certified Engineer Course
Trennung der Implementation von der API

Die API kann in einem Modul deklariert
werden, die Implementation in einem
anderen Modul

Module verwenden die API nur, wenn die
Abhängigkeit dazu deklariert wurde
Certified Engineer Course
Modulare Bibliotheken
Certified Engineer Course
Abhängigkeiten ermitteln
?

Wie findet die SpellChecker API sein
Implementation?
Certified Engineer Course
Abhängigkeiten ermitteln
?
Wie findet die SpellChecker API sein
Implementation?

Oder generell, wie ermöglicht es NetBeans
den Modulen sich in der Applikation zu
finden?
Certified Engineer Course
Der Java Extension Mechanismus (nahezu)

Im JDK seit 1.3

Einfach mit JDK 6's
ServiceLoader.load()

Deklarative
Registrierung

Text Datei(en) in
META-INF/services
>
Name ist Interface
>
Inhalt ist FQN der
Implementation
Certified Engineer Course
Demo 5: ServiceLoader, die Java-Lösung

Das Interface
public interface TextFilter {
    String process(String s);
}

Die Implementation
public class UpperCaseFilter implements TextFilter{
    public String process(String s) {
       return s.toUpperCase();
    }
}
Certified Engineer Course
Demo 5: ServiceLoader, die Java-Lösung

Registrierung der Implementation
>
Textdatei in METAINF/services

Load the Interface
String s = textArea.getText();
ServiceLoader<TextFilter> filters =
 
ServiceLoader.load(TextFilter.class);
for (
TextFilter textFilter
 : 
filters
) {
    if (
filters
 != null) {
        s = 
textFilter.process(s)
;
    }
}
textArea.setText(s);
Certified Engineer Course
Demo 6: Lookup/Dependency Verwaltung
String s = textArea.getText();
Collection<? extends TextFilter> filters = 
Lookup.getDefault().lookupAll(TextFilter.class);
for (TextFilter textFilter : filters) {
    
if (!filters.isEmpty()) {
        
s = textFilter.process(s);
    
}
}
textArea.setText(s);
Certified Engineer Course
Die NetBeans Registrierung

Vereinfachte Registrierung durch
Annotationen
>
Keine selbstgeschriebene Plain-Text-Dateien
mit Tippfehlern
>
Registrierungsinformation direkt an der
annotierten Klasse
>
Refactoring funktioniert
>
Trotzdem Deklarativ, weil zur Compilezeit die
Annotationen ausgewertet werden.
Certified Engineer Course
Die NetBeans Registrierung

Registrierung und Implementation in einer Klasse
import org.netbeans.spi.
TextFilter
;
import org.openide.util.lookup.
ServiceProvider
;
@
ServiceProvider
 (service=
TextFilter
.class)
public class UpperCaseFilter implements 
TextFilter
{
    public String process(String s) {
       return s.toUpperCase();
    }
}
Certified Engineer Course
Lookup – Die NetBeans Lösung

Eine
kleine von NetBeans unabhängige Bibliothek
>
Teil des NetBeans org-openide-util.jar
>
org.openide.util.Lookup

Arbeitet mit jeder Java Version (im Gegensatz zum
ServiceLoader)

Ein Lookup ist dynamisch
>
Listener für Änderungen

Lookups können beliebig instantiiert werden
>
Erzeuge eines und nutze es

Lookups können kombiniert werden
>
ProxyLookup vereinigt Lookups und reicht Event-
Nachrichten durch.
Certified Engineer Course
Ein Lookup ist ein „Aquarium“ für Objekte

Ein „Biotop“ in dem Objekte rein und raus
„schwimmen“

Man erkennt, welche „Arten“ von Objekte
hinzukommen oder verschwinden

Mit einem Befehl bekommt man alle Objekte
einer „Art“ als Collection
Bazz.class
Bazz.class
Foo.class
Foo.class
Bar.class
Bar.class
Lookup
Certified Engineer Course
Nun... Was ist so besonderes daran?
?
Was wäre, wenn Objekte
Lookups besäßen?
Was wäre, wenn Lookups
verkettet werden könnten?
Certified Engineer Course
Objekte, die selbst Lookups besitzen!

TopComponent

Node

DataObject
Certified Engineer Course
Demo 7: TopComponent Lookup
Certified Engineer Course
Demo: TopComponent Lookup
SaveAction
Editor
Gib mir ein SaveCookie
s
s ==
null
?
Ja
Deaktiviere die
Action
Nein
Aktiviere die Action
Bei Aufruf: s.save()
interface
SaveCookie {

void
save();
}
Certified Engineer Course
Demo 8: TopComponent Lookup
private InstanceContent content;
...
...
...        
content = new InstanceContent();
associateLookup(new AbstractLookup(content));
...
...
content.add(s);
Certified Engineer Course
Demo 8: TopComponent Lookup
private Lookup.Result result;
...
...        
result = 
Utilities.actionsGlobalContext().lookupResult(String.class);
  
result.addLookupListener(new LookupListener() {
  @Override
    
public void resultChanged(LookupEvent e) {                
    textArea2.setText(result.allInstances().toString());
    
}
  
});
Certified Engineer Course
Zusammenfassung

Das Lookup wird an jeder Ecke der NetBeans
APIs genutzt

Es wird verwendet für
>
Die deklarative Registrierung von Global Services
>

Instantiation on Demand“ – Reduziert Startzeit
>
Trennung von API und Implementation

Ein Modul bietet eine API

Ein anderes Modul stellt die Implementation
>
Kontextsensitivität, z.B., Action-Aktivierung

Es ist nahezu die wichtigste API auf der
NetBeans Platform
Certified Engineer Course
Die Notwendigkeit modularer Anwendungen
Certified Engineer Course
Die Konzepte im Überblick

Anwendungsentropie

Modularität

Abhängigkeits Verwaltung

Runtime Container

NetBeans Modul

NBM Datei

API vs. Implementation

META-INF/services

ServiceLoader vs. Lookup

Listener für Lookups

Kontextsensitivität mit Lookups
Certified Engineer Course
Fragen & Antworten
http://openide.netbeans.org/lookup/
http://openide.netbeans.org/tutorial/api-design.html
http://bits.netbeans.org/dev/javadoc/org-openide-modules/overview-summary.html