Gliederung 1. Software-Komponenten: Grundlegende Begriffe 2. Systematischer Entwicklungsprozess für Komponenten-Software mit UML 3. Java-Komponenten-Technologien 3.1 JavaBeans-Technologie 3.2 Web-Komponenten mit Java 3.3 Enterprise JavaBeans-Technologie 4. Komponentenspezifikation 5. Komponententechnologien im Vergleich 5.1 Microsoft COM/DCOM/COM+ 5.2 CORBA Component Model 5.3 Vergleich der Komponentenstandards 6. Zusammenfassung und Ausblick Technische Universität Dresden Prof. Hußmann Softwarekomponenten Kapitel 3 Java-Komponenten-Technologien 3.0 3.1 Komponententechnologien und Softwarearchitektur JavaBeans-Technologie Technische Universität Dresden Prof. Hußmann Seite 1 Softwarekomponenten Ergebnis des methodischen Entwurfs (1) • Systematischer Entwurf der Schnitttstellen durch Interaktionsanalyse und Verfeinerung. ICustomerMgt <<interface type>> ICustomerMgt getCustomerMatching(in custD: CustomerDetails, out cus: CustId): Integer createCustomer(in custD: CustomerDetails, out cus: CustId): Boolean getCustomerDetails(in cus: CustId): CustomerDetails notifyCustomer(in cus: CustId, in msg: String) <<data type>> CustomerDetails * <<info type>> Customer id: CustId address: Address email: String Technische Universität Dresden ... name: String postCode[0..1]: String street[0..1]: String email: String Prof. Hußmann Softwarekomponenten Ergebnis des methodischen Entwurfs (2) <<interface type>> IHotelMgt getHotelDetails(in match: String): HotelDetails[ ] getRoomInfo(in res: reservationDetails, out availability: Boolean, out price: Currency) makeReservation(in res: ReservationDetails, in cus: CustId, out resRef: String): Boolean getReservation(in resRef: String, out rd: ReservationDetails, out cus: CustId): Boolean beginStay(in resRef: String, out roomNumber: String): Boolean • Anwendungsspezifische, nicht allgemeine Schnittstellen – separate Entscheidung "buy or build" für Komponentenimplementierung • "You should seek to design for today. Don't try to anticipate future requirements by building in extra capacity and making your interfaces more general than they need to be for the known requirements. You'll invariably be wrong. [...] When new requirements appear, support can be provided by adding on new interfaces [...]" Cheesman/Daniels (S. 119) YAGNI-Prinzip Technische Universität Dresden Prof. Hußmann Seite 2 Softwarekomponenten Realisierung durch JavaBeans ? • JavaBeans: – – – – Eigenschaften, Ereignisse, Methoden Anpassung von generischen Komponenten Visuelle Komposition keine direkte Unterstützung von persistenten Daten und Verteilung • Anforderungen z.B. für Hotel-Buchungssystem: – Realisierung vordefinierter Schnittstellen – Anwendungsspezifische Komponenten – Bedarf nach generischer Infrastruktur: » Persistenz von Daten » Verteilung (Server-Komponenten) » Mehrbenutzerbetrieb: Transaktionsunterstützung » Aktivierung/Deaktivierung von Server-Komponenten Technische Universität Dresden Schlechte Eignung ! Prof. Hußmann Softwarekomponenten Architektur mit JavaBeans + CORBA Client Server <<JavaBean>> Reservation System Skel eton Stub CORBA GUI <<JavaBean>> CustomerMgr <<JavaBean>> HotelMgr Persistenz: Serialisierung ? <<JavaBean>> BillingSystem Transaktion etc.: CORBAservices ? ... Meist ebenfalls aus JavaBeans aufgebaut • Detaillierte Fallstudie siehe: Gruhn/Thiel Kapitel 5 Technische Universität Dresden Prof. Hußmann Seite 3 Softwarekomponenten Java 2 Enterprise Edition (J2EE) • Sammlung von Standard-Schnittstellen (APIs) • Kernbestandteile: – Enterprise JavaBeans (EJB) » Server component model – Java Server Pages (JSP) and Servlets » Dynamische Erzeugung von Webseiten Abschnitt 3.3 Abschnitt 3.2 • Unterstützende Bestandteile: – – – – – – Java Data Base Connectivity (JDBC) Java Transaction Service (JTS) Java Transaction API (JTA) Java Messaging Service (JMS) Java Naming and Directory Interface (JNDI) Remote Method Invocation (RMI) Abschnitt 3.1 • JavaBeans: Bestandteil der grundlegenden Java-Infrastruktur Technische Universität Dresden Prof. Hußmann Softwarekomponenten Architektur mit Enterprise JavaBeans Client Application Server Stub <<EJBSession>> Reservation System Skel eton RMI <<EJBSession>> CustomerMgr <<EJBSession>> HotelMgr <<EJBSession>> BillingSystem Technische Universität Dresden GUI Web Service JSP/ Stub Servlets Spezifische Unterstützung für: (Datenbank-)Persistenz, Transaktionen, Sicherheit, Nachrichtenaustausch Prof. Hußmann Seite 4 Web Client Browser Verwendet JavaBeans Softwarekomponenten Kapitel 3 Java-Komponenten-Technologien 3.0 3.1 3.2 3.3 Komponententechnologien und Softwarearchitektur JavaBeans-Technologie Web-Komponenten mit Java Enterprise JavaBeans-Technologie Technische Universität Dresden Prof. Hußmann Softwarekomponenten JavaBeans • JavaBeans realisieren am deutlichsten die "Lego-Metapher" von Bausteinen • JavaBeans eignen sich für: – Gestaltung von Benutzungsoberflächen – Bausteine bei Gestaltung von dynamischen Web-Seiten Komponenten Provisioning (Bereitstellung) Assembly (Montage) jetzt... Kapitel 1 und Übungen 1+2 Technische Universität Dresden Prof. Hußmann Seite 5 Softwarekomponenten Quellcode der Bean " Counter " (1) public class Counter implements java.io.Serializable { private private private private int count; int startValue; int incrValue; boolean enabled; /** Creates new Counter */ public Counter() { startValue = 0; incrValue = 1; reset(); enabled = true; } public int getCurrent () { return count; } ... Technische Universität Dresden Prof. Hußmann Softwarekomponenten Quellcode der Bean " Counter " (2) ... public int getStartValue () { return startValue; } public void setStartValue (int value) { startValue = value; } // ... analog für incrValue, enabled public void reset () { count = startValue; } public void count () { if (enabled) { count += incrValue; } } } Technische Universität Dresden Prof. Hußmann Seite 6 Softwarekomponenten Was macht eine Klasse zur JavaBean? • Argumentloser öffentlicher Konstruktor – Zur Instanziierung in Entwicklungswerkzeugen • Keine öffentlichen Variablen (Empfehlung) – Zugriff auf Variable nur über Methoden • Unterstützung von Introspektion – Namenskonventionen für Methoden – Stellt Information für Komponenteninspektoren bereit • Unterstützung von Serialisierung oder Externalisierung – Zum Ablegen und Einlesen in Entwicklungsumgebung – Zur Speicherung privater Datenwerte der Bean • Visuelle Beans müssen von java.awt.Component erben – Es gibt keine Oberklasse aller JavaBeans und keine Markierungsschnittstelle für JavaBeans ! Technische Universität Dresden Prof. Hußmann Softwarekomponenten "Counter" in Entwicklungsumgebung (Forte) "Show editable properties" Technische Universität Dresden Prof. Hußmann Seite 7 Softwarekomponenten Namenskonventionen ("Java Bean Patterns") (1) • Eigenschaft P vom Typ T: public T getP() public void setP(T value) Auslesen des Wertes ("getter") Setzen des Wertes ("setter") • Eigenschaft P vom Typ boolean: Gleichwertig zu getP() public boolean isP() • Indizierte Eigenschaft P vom Typ T[]: public public public public T[] getP() void setP(T[] value) T getP(int index) void setP(int index, T Auslesen aller Werte Setzen aller Werte Auslesen eines Einzelwerts value) Setzen eines Einzelwerts • Methode M: Keine besonderen Konventionen public ... M(...) Technische Universität Dresden Prof. Hußmann Softwarekomponenten Werkzeugunterstützung (Beispiel Forte) (1) Automatische Erkennung von "Bean Patterns": Lesen Schreiben Lesen/Schreiben n Indizierte Eigenschaft Technische Universität Dresden Prof. Hußmann Seite 8 Softwarekomponenten Werkzeugunterstützung (Beispiel Forte) (2) Codeerzeugung für neue "Bean Patterns" Technische Universität Dresden Prof. Hußmann Softwarekomponenten Namenskonventionen ("Java Bean Patterns") (2) • Ereignis E: EEvent Ereignisklasse EListener Aufrufschnittstelle ("callback") public void addEListener(EListener l) Empfänger registrieren public void removeEListener(EListener l) Empfänger entfernen – "Multicast"- und "Unicast"-Ereignisse: » Multicast: beliebig viele Empfänger (Normalfall) » Unicast: maximal ein Empfänger (Spezialfall) public void addEListener(EListener l) throws TooManyListenersException Technische Universität Dresden Prof. Hußmann Seite 9 Softwarekomponenten Beispiel: Realisierung "Start"-Knopf Counter setEnabled() <<calls>> ??? <<instanceOf>> registriert actionPerformed (e: ActionEvent) JButton addActionEventListener(l: ActionEventListener) <<interface>> ActionEventListener "Unterstützt Ereignis ActionEvent" Technische Universität Dresden actionPerformed(e: ActionEvent) Prof. Hußmann Softwarekomponenten Beispiel: "ActionEvent" in "Counter" (1) • Idee: Beim Zählen soll ein Ereignis ausgelöst werden. • Erste Möglichkeit für Zählereignis: Verwenden des vordefinierten java.awt.ActionEvent: public synchronized void if (actionListenerList actionListenerList = } actionListenerList.add } addActionListener (ActionListener l) { == null ) { new java.util.ArrayList (); (l); public synchronized void removeActionListener(ActionListener l) { if (actionListenerList != null ) { actionListenerList.remove (l); } } Technische Universität Dresden Prof. Hußmann Seite 10 Softwarekomponenten Beispiel: "ActionEvent" in "Counter" (2) Methode zum Auslösen des Ereignisses (aufgerufen z.B. in count()): private void fireActionListenerActionPerformed (ActionEvent event) { ArrayList list; synchronized (this) { if (actionListenerList == null) return; list = (ArrayList)actionListenerList.clone (); } for (int i = 0; i < list.size (); i++) { ((ActionListener)list.get (i)).actionPerformed (event); } } Gesamter Code für Ereignisverwaltung im Beispiel automatisch generiert ! Technische Universität Dresden Prof. Hußmann Softwarekomponenten Selbstdefinierte Ereignisse • Anwendungsspezifische Ereignisart: – verschieden von den vordefinierten Ereignissen – freie Definition von übertragener Information und Schnittstelle • Schritte: – – – – Neue Ereignisklasse XYEvent als Unterklasse von java.util.EventObject Neue Schnittstelle XYEventListener Ereignisklasse in das gleiche Package wie die Bean-Klasse Weitere Schritte wie bei AWT-Ereignissen: » Methoden zu Registrierung und Deregistrierung » Realisierung konkreter Implementierungen von XYEventListener" (häufig als "anonymous inner class") » Verbindung Quelle-Ziel durch Registrierung • Beispiel: – Selbstdefiniertes Ereignis CountEvent beim Zählen (Zweite Möglichkeit für Zählereignis) Technische Universität Dresden Prof. Hußmann Seite 11 Softwarekomponenten Gebundene Eigenschaften (Bound Properties) • Häufigste Ereignisart in benutzerdefinierten Beans: – Änderung des Werts einer Eigenschaft – z.B. Änderung der Eigenschaft "current" in Counter-Bean • Idee: – (Multicast-)Ereignisart PropertyChangeEvent (in java.beans definiert) » Unterklasse von java.util.EventObject – Nur je eine Methode für Registrierung und Deregistrierung je Bean – Information über Details durch Inhalt des Ereignisses • Vorteil: – Standardimplementierung für Registrierung » PropertyChangeSupport • Nachteil: – Keine statische Information, welche Eigenschaft sich geändert hat – Keine statische Information, welche Eigenschaften gebunden sind Technische Universität Dresden Prof. Hußmann Softwarekomponenten java.beans.* class PropertyChangeEvent extends java.util.EventObject {... Object getSource(); //geerbt String getPropertyName(); Object getOldValue(); Object getNewValue(); } interface PropertyChangeListener { public void propertyChange (PropertyChangeEvent e); } class PropertyChangeSupport { synchronized void addPropertyChangeListener(...); synchronized void removePropertyChangeListener(...); void firePropertyChange (String propname, Object old, Object new); } Technische Universität Dresden Prof. Hußmann Seite 12 Softwarekomponenten Gebundene Eigenschaft "current" in Counter import java.beans.*; public class Counter implements java.io.Serializable { private int count; ... private PropertyChangeSupport propertySupport; public Counter() { propertySupport = new PropertyChangeSupport ( this ); ...} public void count () { if (enabled) { int old = count; count += incrValue; propertySupport.firePropertyChange ("current",old, count); } } Automatisch generierbar mit Ausnahme der Aufrufe von firePropertyChange (und nötiger Parameter) public void addPropertyChangeListener (PropertyChangeListener listener) { propertySupport.addPropertyChangeListener (listener); }... (Dritte Möglichkeit für Zählereignis) } Technische Universität Dresden Prof. Hußmann Softwarekomponenten Eingeschränkte Eigenschaften (Constrained Properties) • Änderung einer Eigenschaft bedürfen oft spezieller Überprüfung – z.B. Plausibilitätsprüfung einer Benutzereingabe – Eingabe: Swing-Bean – Prüfung: Fachliche Bean • Idee: – Empfänger eines PropertyChangeEvent können "widersprechen" (Veto). – Im Falle eines Widerpruchs nimmt der Sender die Änderung zurück. – Schnittstelle VetoableChangeListener: void vetoableChange(PropertyChangeEvent e) throws PropertyVetoException – Vordefinierte Registrierung/Deregistrierung: VetoableChangeSupprt • Verantwortung des Senders: Korrekte Rücknahme – z.B. ändernde Anweisungen erst nach fireVetoableChange() Technische Universität Dresden Prof. Hußmann Seite 13 Softwarekomponenten Reflektion und Introspektion • Reflektion: – die Möglichkeit, zur Laufzeit Informationen über die Felder (Variablen), Konstruktoren und Methoden einer Klasse zu erhalten – fest eingebaut in die Sprache Java (java.lang, java.lang.reflect) » z.B. in Object: Class getClass(); //prüfen!!!! in Class: Constructor[] getConstructors(); Field[] getDeclaredFields(); Method[] getDeclaredMethods(); • Introspektion: – die Möglichkeit, zur Laufzeit Informationen über die Eigenschaften, auslösbaren Ereignisse und Methoden einer JavaBean zu erhalten – Vorwiegend genutzt durch Entwicklungsumgebungen – spezifisch für JavaBeans – Vom Entwickler anpaßbar über Bereitstellung spezieller Klassen Technische Universität Dresden Prof. Hußmann Softwarekomponenten BeanInfo-Klassen • java.beans.BeanInfo: – Schnittstelle für Introspektion – Statische Methode in java.beans.Introspector: static BeanInfo getBeanInfo(Class beanClass); – Sucht zuerst (für Bean namens XYZ) nach Klasse XYZBeanInfo – Falls XYZBeanInfo nicht vorhanden: Standard-Mechanismus (Reflektion) • Beispielhafte Methoden in java.beans.BeanInfo: BeanDescriptor getBeanDescriptor(); Image getIcon(); PropertyDescriptor[] getPropertyDescriptors(); EventSetDescriptor[] getEventSetDescriptor(); MethodDescriptor[] getMethodDescriptors(); • Beispielhafte Methoden in java.beans.PropertyDescriptor: Class getPropertyType(); Method getReadMethod(); ... Technische Universität Dresden Prof. Hußmann Seite 14 Softwarekomponenten BeanInfo-Editor in Entwicklungsumgebung Bild wird noch eingefügt... Beispiel: Forte Technische Universität Dresden Prof. Hußmann Softwarekomponenten JAR: Verpackungsform von JavaBeans (1) • JAR (Java Archive) Datei: – enthält Sammlung von Dateien in Verzeichnis-Struktur – komprimiert nach ZIP-Standard – wird erzeugt und gelesen mit dem Werkzeug jar (angelehnt an Unix tar) jar tvf xyz.jar Inhaltsverzeichnis – erste Datei im Archiv: Manifest » Beschreibungen der anderen Dateien » evtl. digitale Signaturen • JAR-Archive für JavaBeans: – class-Dateien der Bean-Klasse(n) » mehrere Beans in einer JAR-Datei möglich – class-Dateien von Hilfsklassen » z.B. Ereignisklassen, BeanInfo-Klassen, Property-Editoren, Customizer – Text- und HTML-Dateien zur Dokumentation – Bilder, Audioclips, Videoclips Technische Universität Dresden Prof. Hußmann Seite 15 Softwarekomponenten JAR: Verpackungsform von JavaBeans (2) • Beispiel: Manifest-Eintrag für Counter-Bean (Datei Counter.mft) Name: counter/Counter.class Java-Bean: true • JAR-Kommando zum Erzeugen eines JavaBean-Archivs für CounterBean: jar cfm Counter.jar Counter.mft *.class (c=create, x=extract, t=tabulate, f=filename, m=manifest) – Wenn Manifest nicht angegeben, erzeugt "jar" automatisch ein Manifest – Entwicklungsumgebungen: » Beans in/aus JAR im/exportieren » Installation von Beans in Paletten etc. » Umfangreiche Werkzeuge, z.B. in Forte for Java Technische Universität Dresden Prof. Hußmann Softwarekomponenten Persistenz von JavaBeans • Notwendigkeit von Persistenz: – Instanzenorientiertes Vorgehen – Speicherung individueller Werte von Eigenschaften einer Instanz • Serialisierung: – Repräsentation des aktuellen Zustands eines Objekts als Zeichenreihe • Deserialisierung: – Rekonstruktion eines Objekts aus einer Zeichenreihe • Im allgemeinen sollten JavaBeans serialierbar sein ! • Manche Variablenwerte müssen nicht gespeichert werden: – Thread-Objekte ("myThread") – Zeitabhängige Werte (z.B. Uhrzeit, Datum, lokale Zähler) » als "transient" deklarieren Technische Universität Dresden Prof. Hußmann Seite 16 Softwarekomponenten Property Editors, Customizers • Der Entwickler einer JavaBean kann spezielle Klassen mitliefern, mit denen in der Entwicklungsumgebung die Werte einer JavaBean bequem eingestellt werden können. • Für einzelne Eigenschaften: – z.B. für Counter.incrValue: Angebot von vordefinierten Stufen – Interface PropertyEditor, Default-Implementierung PropertyEditorSupport » Darstellung von Werten in Textfeldern (getAsText(), setAsText()) » Darstellung in Auswahl-Listen für zulässige Werte (getTags()) » "Custom Property Editor" (setValue(), paintValue(), ...) • Für mehrere Eigenschaften: – z.B. für Counter.{startValue, incrValue}: Graphische Darstellung – Customizer » im wesentlichen eigenständiges Programm, das Objekt einstellt » Reaktion auf PropertyChange wesentlich • Festlegung der zu verwendenden Editoren: BeanInfo-Klasse Technische Universität Dresden Prof. Hußmann Seite 17 Softwarekomponenten