Netzprogrammierung: CORBA Robert Tolksdorf und Peter Löhr Überblick 1. 2. 3. 4. 5. 6. Konzepte Einfache Fernaufrufe Der CORBA-Namensdienst Interface Definition Language (IDL) Java/IDL-Sprachanbindung Der Umgang mit CORBA Robert Tolksdorf und Peter Löhr 2 Konzepte Robert Tolksdorf und Peter Löhr OMG und CORBA • Java RMI ist sprachgebundene Plattform von Sun • .NET ist sprachunabhängige Plattform von Microsoft • CORBA (Common Object Request Broker Architecture) ist ebenfalls eine Plattform für verteilte Anwendungen, aber • sprachunabhängig • herstellerunabhängig • Industriestandard für heterogene verteilte Anwendungen • spezifiziert von der Object Management Group (OMG) • „… an open membership, not-for-profit consortium that produces and maintains computer industry specifications for interoperable enterprise applications.” • Mitglieder sind „alle bekannten” IT-Firmen • Weitere OMG-Standards neben CORBA: UML, MDA, ... Robert Tolksdorf und Peter Löhr 4 Object Request Broker • CORBA-Objekte • sind fernaufrufbar, • haben eine typisierte Schnittstelle, • können in unterschiedlichen Programmiersprachen implementiert sein. • Das Fernaufrufsystem heißt Object Request Broker (ORB) • Weitere Dienste unterstützen • das Auffinden benannter Objekte (Naming) • das Auffinden von Naming Objekten mit bestimmten Eigenschaften (Trading) Trading • u.a. Robert Tolksdorf und Peter Löhr Client Object Stub Skeleton Object Request Broker 5 Heterogene Middleware • ORBs, die von unterschiedlichen Herstellern stammen, können zusammenarbeiten, Client Object Stub Skeleton Object Request Broker IIOP Object Request Broker • ... sofern sie sich an die Spezifikation des Internet Inter-ORB Protocol (IIOP) halten. Robert Tolksdorf und Peter Löhr 6 Elemente von CORBA • Interface Definition Language (IDL) für typisierte Schnittstellen: • vergleichbar mit Java-Teilsprache für Schnittstellen • Abbildungen zwischen den Typsystemen von Programmiersprachen und von IDL • Fernaufruf-Unterstützung in der jeweiligen Programmiersprache • vergleichbar mit java.rmi • Implementierung eines ORB benutzt Transportdienst TCP • Spezielle Objekte: • CORBA Services: Verteilt angebotene niedere Dienste (z.B. Naming Service, Trading Service, Collection Service, Time Service, Externalization Service, Concurrency Service etc.) • Common Facilities: Nützliche anwendungsbezogene Dienste, die aber nicht als notwendige Dienste angeboten werden müssen. Heutiger Stand: Internationalization, Print Facility, Mobile Agent Facility, ... Robert Tolksdorf und Peter Löhr 7 CORBA-Produkte • CORBA-Bestandteile sind einzeln erhältlich und können von verschiedenen Herstellern bezogen werden: • • • • ORBs IDL-Anbindungen Services Facilities • Empohlener freier ORB für Java - hier am Institut entwickelt: JacORB www.jacorb.org Client Stub Naming Trading Time Object Request Broker … (Facilities) Robert Tolksdorf und Peter Löhr 8 CORBA-Objekte • Eine mit IDL beschriebene Schnittstelle • • • • • ... ... ... ... ... kann verschiedene Implementierungen … in verschiedenen Programmiersprachen haben … aus denen sich verschiedene Exemplare ergeben … die über CORBA-Objektverweise zugänglich sind … und über den ORB fernaufgerufen werden können. Robert Tolksdorf und Peter Löhr 9 Überblick / Glossar • Object Management Group (OMG) entwickelt Standards • Object Management Architecture (OMA) ist Standard für • • • • • • • • verteilte Objektsysteme Object Request Broker (ORB) ist das Fernaufrufsystem in der OMA, also die eigentliche Middleware Common Object Request Broker Architecture (CORBA) ist Spezifikation von ORBs Internet Inter-ORB Protocol (IIOP) ist Protokoll zwischen ORBs Stub ist Vertreter für fernaufrufbares Objekt Skeleton ist Treiber für fernaufrufbares Objekt Portable Object Adapter (POA) ist Standard-Adapter (Zur Erinnerung - Adapter: 04-Fernaufrufe, S. 16/17) Interface Definition Language (IDL) als Sprache zur Beschreibung von Schnittstellen in OMA IDL-Übersetzer erzeugt Stub und Skeleton in der jeweiligen Programmiersprache Robert Tolksdorf und Peter Löhr 10 Einfache Fernaufrufe Robert Tolksdorf und Peter Löhr Das Standard-Beispiel: Counter • Zähler-Objekt als CORBA-Dienst anbieten • Was ist zu tun? • • • • • Schnittstelle definieren mit IDL Klasse des Objekts implementieren in Sprache X Objekt bereitstellen und registrieren Klienten implementieren in Sprache Y Benutzung des Objekts durch Klienten • Hier zunächst: Sprache X = Sprache Y = Java • CORBA wird - wenngleich nicht vollständig - durch die folgenden Java-Bibliotheken unterstützt • org.omg.CORBA • org.omg.CORBA. ... • org.omg. ... Robert Tolksdorf und Peter Löhr 12 Schnittstellendefinition in IDL module counter { Verbundtyp // number of inc executions interface Counter { readonly attribute long value; Schnittstelle void inc(in long value); void addTo(inout long clientValue); Namensraum struct Info { long value; long counted; }; Signatur Info getInfo(); }; }; Robert Tolksdorf und Peter Löhr 13 Erzeugung von Stubs etc. • $ idlj –fall counter.idl • (statt -fall auch nur -server oder -client) Der IDL/Java-Übersetzer erzeugt aus der Schnittstellendatei counter.idl diverse Klassen/Schnittstellen in einem Paket counter, gespeichert in Dateien counter/*.java . Für den Typ Info: • Klasse Info • Klasse InfoHelper für De/serialisierung von Info-Objekten • Hilfsklasse InfoHolder für Info-Werte als out/inout Parameter • Für die Schnittstelle Counter: • Schnittstelle CounterOperations mit den Methoden inc, addTo, ... • Schnittstelle Counter extends CounterOperations, org.omg.CORBA.Object, ... • Klasse CounterHelper für De/serialisierung von Counter-Objekten • Abstrakte Klasse CounterPOA = Skeleton-Code • Klasse _CounterStub = Stub-Code, implementiert Counter • $ javac counter/*.java Robert Tolksdorf und Peter Löhr 14 Implementierung von Servants Die Schnittstelle Counter wird als Unterklasse von CounterPOA implementiert: public class CounterImpl extends CounterPOA { ... } // „inheritance model“ (as opposed to „tie model“) Ein Objekt einer solchen Klasse ist fernaufrufbar und wird in CORBA als Servant bezeichnet. Zur Information: public abstract class CounterPOA extends org.omg.PortableServer.Servant implements counter.CounterOperations, org.omg.CORBA.portable.InvokeHandler { .. } (Es ist instruktiv, sich diesen Code anzusehen!) Robert Tolksdorf und Peter Löhr 15 Implementierung von Servants package counter; public class CounterImpl extends CounterPOA { int value = 0; // vgl.: MarshalByRefObject in .NET int addCount = 0; public int value() { return value; } public void inc (int value) { Mängel bei der Verteilungsabstraktion this.value += value; addCount++; } public void addTo(org.omg.CORBA.IntHolder clientValue) { clientValue.value += value; } public Info getInfo() { // Klasse Info wurde von idlj erzeugt! Info info = new Info(); info.value = value; info.counted = addCount; return info; } } Robert Tolksdorf und Peter Löhr 16 Erzeugung von Servants CounterImpl wird um eine main-Methode erweitert: package counter; import org.omg.CORBA.*; import org.omg.CosNaming.*; import org.omg.PortableServer.*; public class CounterImpl extends CounterPOA { public static void main(String[] arg) throws Exception { ORB orb = ORB.init(arg, null); // ORB initialisieren (arg s.u.) POA root = (POA)orb.resolve_initial_references("RootPOA"); // RootPOA greifen ... root.the_POAManager().activate(); // und POAManager aktivieren CounterImpl c = new CounterImpl(); ................................................ // Objekt registrieren - s.u. orb.run(); // Fernaufrufe erwarten } int value = 0; ............................. // wie S. 16 } Robert Tolksdorf und Peter Löhr 17 Ein Klient von CounterImpl package counter; import org.omg.CORBA.*; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; public class CounterClient { public static void main(String[] arg) throws Exception { ORB orb = ORB.init(arg, null); // ORB initialisieren .............................................. // Objekt counter beschaffen System.out.println("Wert: "+counter.value()); // 0 counter.inc(10); System.out.println("Wert: "+counter.value()); // 10 counter.inc(10); System.out.println("Wert: "+counter.value()); // 20 IntHolder myInt=new IntHolder(100); counter.addTo(myInt); System.out.println("myInt: "+myInt.value); // 120 Info info = counter.getInfo(); System.out.println("Info: "+info.value+" / "+info.counted); // 20 / 2 } } Robert Tolksdorf und Peter Löhr 18 Der CORBA-Namensdienst Robert Tolksdorf und Peter Löhr Namensdienst und Java • CORBA-Objekte werden bei einem Namensdienst (Name Service) registriert, damit sie über einen Namen aufgefunden werden können (ähnlich dem RMI Registry). • Die Schnittstelle des Namensdienstes ist - unabhängig von Programmiersprachen - in IDL beschrieben und als OMG-Standard festgelegt. • Die Funktionalität des Namensdienstes wird in Java über das Paket org.omg.CosNaming bereitgestellt. • In org.omg.CosNaming.NamingContextPackage und org.omg.CosNaming.NamingContextExtPackage finden sich Erweiterungen des Namensdienstes. • Der Dienst hat selbst einen Namen: NameService Robert Tolksdorf und Peter Löhr 20 Namensraum • Objekte können an einen Namen gebunden werden. • Jede Bindung ist relativ zu einem Namenskontext. • Innerhalb eines Namenskontextes sind alle Namen • • • • • eindeutig. Ein Namenskontext ist selbst ein Objekt und kann an einen Namen gebunden werden. Dadurch entsteht ein (zyklenfreier) Objektgraph - ähnlich einem Initialer Namenskontext Dateisystem. Ein Objekt wird durch einen documents FU Namenspfad identifiziert. Das Auflösen eines Namens calendar counter liefert einen Verweis auf ein Objekt. Auch Namenspfade sind Objekte. Robert Tolksdorf und Peter Löhr 21 Binden eines Namens • Initialen Namenskontext erfragen: org.omg.CORBA.Object naming = orb.resolve_initial_references("NameService"); NamingContextExt context = NamingContextExtHelper.narrow(naming); // casting • Namenspfad als Feld von Namenskomponenten erzeugen: NameComponent[] name = context.to_name("documents"); • Ein Objekt an den Namen binden context.rebind(name, someObjectRef); Robert Tolksdorf und Peter Löhr 22 Neuen Kontext einfügen • Neuen Kontext erzeugen und an einen Namen binden: NameComponent[] name2 = context.to_name("FU"); NamingContextExt context2 = (NamingContextExt)context.bind_new_context(name2); • Im neuen Kontext weitere Bindungen einfügen: NameComponent[] name3 = context2.to_name("calendar"); context2.rebind(name3, calendarRef); NameComponent[] name4 = context2.to_name("counter"); context2.rebind(name4, counterRef); Robert Tolksdorf und Peter Löhr 23 Benanntes Objekt finden • NameService greifen und Namen auflösen: org.omg.CORBA.Object naming = orb.resolve_initial_references("NameService"); NamingContextExt context = NamingContextExtHelper.narrow(naming); org.omg.CORBA.Object docs = context.resolve_str("documents"); org.omg.CORBA.Object calendar = context.resolve_str("FU/calendar"); org.omg.CORBA.Object counter = context.resolve_str("FU/counter"); Robert Tolksdorf und Peter Löhr 24 CounterImpl vollständig ..... public class CounterImpl extends CounterPOA { public static void main(String[] arg) throws Exception { ORB orb = ORB.init(arg, null); // ORB initialisieren (arg s.u.) POA root = (POA)orb.resolve_initial_references("RootPOA"); // RootPOA greifen ... root.the_POAManager().activate(); // und POAManager aktivieren CounterImpl c = new CounterImpl(); org.omg.CORBA.Object serv = root.servant_to_reference(c); // aus c ein CORBA-Objekt machen org.omg.CORBA.Object ns = orb.resolve_initial_references("NameService“); NamingContextExt naming = NamingContextExtHelper.narrow(ns); NameComponent[] name = naming.to_name("Counter"); naming.rebind(name, serv); // beim Namensdienst registrieren orb.run(); // Fernaufrufe erwarten } int value = 0; ...................... // Attribute und Methoden } Robert Tolksdorf und Peter Löhr 25 CounterClient vollständig package counter; import org.omg.CORBA.*; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; public class CounterClient { public static void main(String[] arg) throws Exception { ORB orb = ORB.init(arg, null); org.omg.CORBA.Object ns = orb.resolve_initial_references("NameService"); NamingContextExt naming = NamingContextExtHelper.narrow(ns); // Counter-Objekt beim Namensdienst aufsuchen org.omg.CORBA.Object c = naming.resolve_str("Counter"); Counter counter = CounterHelper.narrow(c); System.out.println("Wert: "+counter.value()); ..... } } Robert Tolksdorf und Peter Löhr 26 Lokaler Test Namensdienst wird durch ORB Daemon orbd realisiert: $ orbd "... Unable to create listener thread on the specified port: 900 ..." $ orbd -ORBInitialPort 1050 & [1] 9565 $ java counter.CounterImpl -ORBInitialPort 1050 & [2] 9569 $ java counter.CounterClient -ORBInitialPort 1050 Wert: 0 Wert: 10 Wert: 20 myInt: 120 Info: 20 / 2 $ Robert Tolksdorf und Peter Löhr 27 Verteilter Test human: orbd -ORBInitialPort 1050 & [1] 11364 athos: java counter.CounterImpl -ORBInitialPort 1050 \ -ORBInitialHost human & [1] 15147 lohr: java counter.CounterClient -ORBInitialPort 1050 \ -ORBInitialHost human Wert: 0 Wert: 10 Wert: 20 myInt: 120 Info: 20 / 2 (oder CORBA-konform: -ORBInitRef NameService=corbaloc::human.inf.fu-berlin.de:1050) Robert Tolksdorf und Peter Löhr 28 ... und programmatisch mit Properties Anstelle der Optionen -ORB... können auch programmatisch gesetzte Properties verwendet werden: ... Properties props = new Properties(); props.put("org.omg.CORBA.ORBInitialPort","1050"); props.put("org.omg.CORBA.ORBInitialHost","localhost"); ORB orb = ORB.init(arg, props); ... Aber: etwaige explizite Optionen auf der Befehlszeile haben Vorrang. Robert Tolksdorf und Peter Löhr 29 Interface Definition Language IDL www.omg.org/docs/formal/02-06-39.pdf Robert Tolksdorf und Peter Löhr IDL • IDL ist eine Sprache zur Definition von Schnittstellen: • Unabhängig von Programmiersprachen • Eigenes Typsystem • (Groß/Kleinschreibung wird ignoriert!) • IDL-Sprachkonstrukte werden zu Sprachkonstrukten der • jeweiligen Programmiersprache in Beziehung gesetzt: Language Mapping (durch OMG festgelegt für etliche Sprachen neben Java: C, C++, COBOL, Ada, Python, .....) Dies gelingt nicht immer; es müssen dann zur Laufzeit entsprechende Ausnahmen gemeldet werden. • IDL-Übersetzer (IDL compiler) erzeugt aus IDL-Text Code für Stubs etc. in der jeweiligen Sprache: • • • • • für Java: idlj (Sun ORB), idl (JacORB), jidl (Orbacus), ... für C++: idl (Orbix), idl (MICO), omniidl (omniORB), ... für Python: omniidl -bpython (omniORB) für Cobol: orxidl -cobol (Orbix) ..... Robert Tolksdorf und Peter Löhr 31 IDL-Typsystem (Ausschnitt) • Typvereinbarungen (= Einführung benannter Typen) type_dcl ::= typedef type_declarator | struct_type ..... type_declarator ::= type_spec declarators declarators ::= declarator { , declarator }* type_spec ::= base_type_spec | sequence_type | struct_type | string_type | name | ....... Beispiele: typedef string<20> name typedef float length[1000] struct complex { double re, im; } Robert Tolksdorf und Peter Löhr 32 Einfache Typen • Einfache Typen (base_type_spec) • Nicht interpretiertes Byte mit 8 Bit Länge octet • Ganzzahlen mit 16, 32, 64 Bit Länge, mit/ohne Vorzeichen: short long long long unsigned short unsigned long unsigned long long • Gleitkommazahlen mit einfacher, doppelter und erweiterter Genauigkeit nach IEEE, Festkommazahlen: float double long double • Zeichen für beliebige Zeichen, 8 oder 16 Bit char wchar string fixed wstring • Wahrheitswerte TRUE und FALSE: boolean • Typplatzhalter any • Zeichenketten string (gemäß Syntax nicht base_type_spec) Robert Tolksdorf und Peter Löhr 33 Zusammengesetzte Typen • Verbundtypen struct_type ::= struct identifier { member+ } member ::= type_spec declarators ; Beispiel: struct cumulativeWeatherInfo { long start, end; // interval in Unix time() format float sunshine; // hours of sunshine during interval float rainfall; // mm of rainfall during interval } Robert Tolksdorf und Peter Löhr 34 Zusammengesetzte Typen • Felder array_declarator ::= identifier fixed_array_size+ fixed_array_size ::= [ positive_int_const ] Beispiele: • Im member double vector[32] hat vector den „Typ double[32]“ • In typedef float length[1000] ist length der „Typ float[1000]“ • Folgen sequence_type ::= sequence < simple_type_spec > | sequence < simple_type_spec , positive_int_const > Beispiele: sequence<float> sequence<complex, 40> Robert Tolksdorf und Peter Löhr 35 Module und Schnittstellen • Schnittstelle • • • • • • • Vergleichbar dem interface in Java; enthält Konstanten Attribute Typdefinitionen Operationen Ausnahmedefinitionen … • Modul • Namensraum für zusammengehörige Schnittstellen • Qualifizierter Name: Modulname::Name • Vergleichbar dem package in Java Robert Tolksdorf und Peter Löhr 36 Module und Schnittstellen Beispiel (von oben): module counter { struct Info { long value; long counted; }; interface Counter { readonly attribute long value; void inc(in long value); void addTo(inout long clientValue); Info getInfo(); }; }; Robert Tolksdorf und Peter Löhr 37 Module specification ::= import* definition+ definition ::= type_dcl ; const_dcl ; except_dcl ; interface ; module ; value ; ..... | | | | | | module ::= module identifier { definition+ } Robert Tolksdorf und Peter Löhr 38 Schnittstellen interface ::= interface_header { export+ } interface_header ::= interface identifier [ inheritance ] inheritance ::= : identifer { , identifier }* export ::= type_dcl ; op_dcl ; except_dcl ; attr_dcl ; const_dcl ; ..... | | | | | ! Schnittstellen sind auch Typen - Verweistypen (wie in Java) Robert Tolksdorf und Peter Löhr 39 Operationen op_dcl ::= [ op_attribute ] op_type_spec identifier parameters [ raises_expr ] [ context_expr ] op_attribute ::= oneway op_type_spec ::= param_type_spec | void parameters ::= ( param_dcl { , param_dcl }* ) | ( ) param_dcl ::= param_attribute param_type_spec identifier param_attribute ::= in | out | inout param_type_spec ::= identifier | string_type (!) Achtung: Felder können nicht als Parameter übergeben werden - wohl aber Folgen (mit benanntem Folgentyp). Robert Tolksdorf und Peter Löhr 40 Operationen in out inout Wertparameter Ergebnisparameter Wert/Ergebnisparameter Bei regulärer Beendigung genau-einmal-Semantik. Bei Ausnahme höchstens-einmal-Semantik. oneway-Operationen: asynchrone Operationsausführung; setzt voraus: void, kein out, keine Ausnahme; höchstens-einmal-Semantik. Robert Tolksdorf und Peter Löhr 41 Ausnahmen raises_expr ::= raises ( identifier { , identifier }* ) Die so gemeldeten Ausnahmen müssen vereinbart sein: except_dcl ::= exception identifier { member* } Beispiel: ..... exception underflow { int amount; }; ..... void withdraw(in long amount) raises (underflow); ..... Robert Tolksdorf und Peter Löhr 42 Ausnahmen • In CORBA sind zwei Arten von Ausnahmen definiert: • Standardausnahmen: #define details {unsigned long minor; completion_status completed;} module CORBA { exception UNKNOWN details; // the unknown exception exception BAD_PARAM details; // invalid parameter exception NO_MEMORY details; // dynamic memory allocation failure exception IMP_LIMIT details; // violated implementation limit exception COMM_FAILURE details; // communication failure ..... • Deklarierte anwendungsspezifische Ausnahmen Robert Tolksdorf und Peter Löhr 43 Attribute Beispiele: attribute long interestRate; readonly attribute long balance; Zu jedem Attribut sind implizit getter/setter-Operationen vereinbart, bei readonly nur eine getter-Operation. Syntax: attr_dcl ::= [ readonly ] attribute param_type_spec identifier (Hier sind auch Ausnahmen zugelassen - siehe dazu in der IDL-Spezifikation die Syntaxregeln 104-111.) Robert Tolksdorf und Peter Löhr 44 Value Types Werttypen (value types) ähneln Schnittstellen und Klassen, sind aber keine Verweistypen (Parameterübergabe!). value_dcl ::= valuetype identifier { value_element* } value_element ::= export | state_member | init_dcl (wie interface, vgl. S. 39) state_member ::= ( public | private ) type_spec declarators ; init_dcl ::= factory identifier ( [ init_param_decls ] ) [ raises_expr ] ; (Auch Vererbung ist hier möglich.) Leseempfehlung: G. Brose et al.: JacORB 2.3 Programming Guide. www.jacorb.org/releases/2.3.0_beta2/ProgrammingGuide.pdf.gz Robert Tolksdorf und Peter Löhr 45 Java/IDL-Sprachanbindung Robert Tolksdorf und Peter Löhr Einfache Typen • Einfache Typen: boolean boolean char, wchar char string, wstring String octet byte short, unsigned short short long, unsigned long int long long, unsigned long long long float float double double fixed java.math.BigDecimal Robert Tolksdorf und Peter Löhr 47 Folge <--> Feld • IDL typedef sequence <float> severalFloats; typedef sequence <boolean,10> tenBooleans; tenBoleans op(in severalFloats sf); • Java boolean[] op(float[] sf); Robert Tolksdorf und Peter Löhr 48 Verbund <--> Klasse • IDL struct Info { long value; long counted; }; • Java public final class Info implements org.omg.CORBA.portable.IDLEntity { public int value = (int)0; public int counted = (int)0; public Info () { } public Info (int _value, int _counted) { value = _value; counted = _counted; } } Robert Tolksdorf und Peter Löhr 49 Operationen • Operationen <--> Methoden • Ausnahmen <--> Ausnahmen • Parameterübergabe • • • • Ergebniswerte unproblematisch in: normale Wertparameter in Java out und inout: keine Entsprechung in Java ... werden daher mit Hilfe von Holder-Klassen realisiert: der Aufgerufene erhält vom Aufrufer ein Holder-Objekt, in dem er das Ergebnis deponiert. Robert Tolksdorf und Peter Löhr 50 Holder-Klassen • Vordefiniert für vordefinierte Typen ... • ... z.B. für float: org.omg.CORBA.FloatHolder • Attribut: • public float value • Konstruktoren: • FloatHolder() setzt value auf 0.0 . • FloatHolder(float initial) setzt value auf initial . • Methoden zum Lesen und Schreiben des value . • Entsprechend IntHolder für long etc.etc. Robert Tolksdorf und Peter Löhr 51 Holder-Klasse bei Counter • IDL: void addTo(inout long clientValue); • Beim Klienten muss so programmiert werden: IntHolder myInt = new IntHolder(100); counter.addTo(myInt); int i = myInt.value; • Beim Counter-Objekt muss so programmiert werden: public void addTo(IntHolder clientValue) { clientValue.value += value; } Robert Tolksdorf und Peter Löhr 52 Holder-Klassen für eigene Typen Für eigene Typen (wie z.B. Info beim Counter) erzeugt der IDL-Übersetzer geeignete Holder-Klassen: package counter; /** * counter/InfoHolder.java . * Generated by the IDL-to-Java compiler (portable), version "3.2“ * from counter.idl * Freitag, 28. November 2008 18.14 Uhr CET */ public final class InfoHolder implements org.omg.CORBA.portable.Streamable{ public counter.Info value = null; public InfoHolder () { } public InfoHolder(counter.Info initialValue) { value = initialValue; } public void _read(org.omg.CORBA.portable.InputStream i) { value = counter.InfoHelper.read (i); } public void _write (org.omg.CORBA.portable.OutputStream o) { ..... Robert Tolksdorf und Peter Löhr 53 Der Umgang mit CORBA Robert Tolksdorf und Peter Löhr Wann CORBA verwenden? Typische Situation für den Einsatz von CORBA: • Gewisse Software S in Sprache A liegt vor und soll unter Verwendung von Sprache X erweitert werden. • Die vorliegende Software in A ist typischerweise entweder • Altsoftware (legacy software) in einer nicht mehr attraktiven Sprache (Cobol, C, ...) oder • Software „off the shelf“, die zufällig nicht in der Sprache X geschrieben ist, die für die Erweiterung verwendet werden soll. • (Weitere Möglichkeit: in verschiedenen Sprachen A,B,C,... vorliegender Code soll unter Verwendung der Sprache X zusammengefügt und erweitert werden.) Robert Tolksdorf und Peter Löhr 55 Wie CORBA verwenden? Die ideale Vorgehensweise: 1. Schnittstelle(n) von S mit IDL beschreiben in Datei s.idl . 2. IDL-Übersetzer für A einsetzen: idlA -server s.idl . 3. Den erzeugten Code übersetzen und mit S zusammenbinden. 4. IDL-Übersetzer für X einsetzen: idlX -client s.idl . 5. Klienten-Code entwickeln und mit dem erzeugten Code übersetzen und zusammenbinden. Robert Tolksdorf und Peter Löhr 56 IDL-Text verfassen 1. Schnittstelle(n) von S mit IDL beschreiben in Datei s.idl : Das kann schwierig sein für Sprachen die keinen (oder nur einen unscharfen) Begriff von Schnittstellen haben! Die IDL-Schnittstelle muss so formuliert werden, dass der vom IDL-Übersetzer in Schritt 2 generierte Code (Skeleton etc.) möglichst gut zu S passt - denn: S kann in der Regel nicht unmodifiziert übernommen werden - da die Verteilungsabstraktion nicht perfekt ist: Verpackungscode (wrapper code) muss geschrieben werden. Bemerkung: Wenn die Sprache A weniger reichhaltig ist als IDL, ist die Abbildung von A nach IDL und damit die Formulierung der IDL-Schnittstelle tendenziell einfacher als im umgekehrten Fall. Hinweis: Es gibt Übersetzer von Java-Schnittstellen nach IDL! Robert Tolksdorf und Peter Löhr 57 Anbieter-Software bereitstellen 2. IDL-Übersetzer für A einsetzen: idlA -server s.idl : Hier wird der anbieterseitige Quellcode für die Anbindung des Objekts generiert - unproblematisch. 3. Den erzeugten Code übersetzen und mit S zusammenbinden: Dies führt nur dann zu einem funktionsfähigen Anbieter, wenn der Verpackungscode korrekt ist. Merke: Beim Beispiel Counter tauchten keine Probleme auf, weil die IDL-Schnittstelle der Ausgangspunkt war und der anbieterseitige Code entsprechend formuliert wurde! Robert Tolksdorf und Peter Löhr 58 Klienten bereitstellen 4. IDL-Übersetzer für X einsetzen: idlX -client s.idl : Hier wird der klientenseitige Quellcode für die Anbindung des Klienten generiert - wiederum unproblematisch. 5. Klienten-Code entwickeln und mit dem erzeugten Code übersetzen und zusammenbinden: Dies ist im Prinzip unproblematisch, da von vornherein klar ist, wie der zu entwickelnde Code auszusehen hat ... ... aber: wenn die Sprache X weniger reichhaltig ist als IDL muss man Einschränkungen und Hilfskonstruktionen in Kauf nehmen (Beispiel: Holder-Objekte für Java). Robert Tolksdorf und Peter Löhr 59 Zusammenfassung Robert Tolksdorf und Peter Löhr Zusammenfassung 1. OMG CORBA 1. 2. 3. 4. Sprachunabhängiges Objektmodell ORB als Fernaufrufsystem Services und Facilities als definierte Dienstobjekte Namensdienst 2. IDL 1. 2. 3. Typsystem Module, Schnittstellen, Value Types Operationen 3. Java/IDL Mapping 1. funktioniert nicht bruchlos 4. (nicht behandelt: Persistenz, IORs, Speicherbereinigung, ...) Robert Tolksdorf und Peter Löhr 61 Literatur • OMG: CORBA 3.0 Specification. • • www.omg.org/technology/documents/formal/corba_2.htm 1150 Seiten! OMG: IDL Specification. www.omg.org/docs/formal/02-06-39.pdf ... etliche Bücher über CORBA allgemein ... • G. Brose, A. Vogel, K. Duddy: Java Programming with CORBA. • • • Wiley 2001 G. Brose et al.: JacORB 2.3 Programming Guide. www.jacorb.org/releases/2.3.0_beta2/ProgrammingGuide.pdf.gz J. Farley, W. Crawford: Java Enterprise in a Nutshell (3. ed.). O'Reilly 2005 (für idlj, orbd, servertool ist dies besser als man ) M. Henning: The Rise and Fall of CORBA. Comm. of the ACM 51.8 (August 2008), pp. 53-57 Robert Tolksdorf und Peter Löhr 62