Klassenhierarchie der Skeletons für eine Schnittstelle Foo IDL und Java " " Grober Aufbau eines IDL-Files: module package { interface RegisterServer { Handle register(inout Client cl); }; interface Handle { void publish (in string msg) raises(DirtyMsgEx); };}; Abbildung eines CORBA Interface auf – Java Klassen/Schnittstellen für Stubs,Skeletons Hilfsklasse (enth. u.a. narrow()) – Behälterklasse für In/Out-Parameter – Separierung von Klientenseite und Serverseite Vererbung/Sichtbarkeitsbereiche " " Unterstützung von Mehrfachvererbung interface base {} ; interface derived : base {}; – Diamantstruktur kein Problem bei Schnittstellen – keine Typpolymorphie Explizite Bereichsangaben: module M { module Inner1 { typedef string T1;}; module Inner2 { typedef Inner1::T1 T2;}; }; – IDL ist „case-insensitive“ d.h. alle benutzten Typen müssen gleich dem definierenden sein – Namen für unterschiedliche Elemente (Module, Schnittstellen, Typen etc.) dürfen nicht kollidieren => FooImpl ist kein CORBA Objekt => keine zulässige Ergebnisrückgabe Behälterklassen " Einsatz bei out und inout Parametern " Bsp: Schnittstelle Foo public class FooHolder implements org.omg.CORBA.portable.Streamable { public Foo value; public FooHolder() { } public FooHolder(Foo initial){ value = initial; } public org.omg.CORBA.TypeCode _type(){ return FooHelper.type() } ...} " Nach Ausführung der Methode beim Server Übertragung zum Klienten Strukturen struct MyStruct { short myShort; string myString; }; wird abgebildet auf: public final class MyStruct implements org.omg.CORBA.portable.IDLEntity { public short myShort; public String myString; public MyStruct() {}; public MyStruct(short myShort, String myString) { this.myShort = myShort; this.myString = myString; } } Aufzählungen Generische Typen enum Slot {am9, am10}; wird abgebildet auf: public final class Slot implements IDLEntity { private int _value; public static final int _am9 = 0; public static final int _am10 = 1; public static final Slot am9 = new Slot(_am9); public static final Slot am10 = new Slot(_am10); protected Slot(final int value) { this._value = value; } public int value() { return _value;} public static Slot from_int(final int val) { switch(val) { case _am9: return am9; case _am10: return am10; } } } " " " Vektoren (Felder mit variabler Länge): typedef sequence<long> LongSeq; Felder typedef octet[1024] KiloByte; Anonyme Typen werden abgelehnt struct Foo { octet[1024] data1; // deprecated KiloByte data2; // OK } Aktivieren des Servers Erzeugen der CORBA Objekte static void main(String args[]) { // catch everything try{ // create ORB object ORB orb = org.omg.CORBA.ORB.init(args, null); // get the default POA org.omg.CORBA.Object cob = orb.resolve_initial_references("RootPOA") POA poa = POAHelper.narrow(cob); // activate it poa.the_POAManager().activate(); Erzeugen, Anmelden des Servants // generate and connect servant org.omg.CORBA.Object scob = poa.servant_to_reference(new HelloServer()); // get name server cob = orb.resolve_initial_references("NameService"); NamingContextExt nc = NamingContextExtHelper.narrow(cob); // generate name NameComponent [] name = nc.to_name(“Hello“); // bind server to name nc.bind(name, scob); // done System.out.println("Server is ready."); orb.run(); } catch(Exception ex){ ex.printStackTrace(); System.exit(5); } } // main() } // class Zugriff auf den HelloServer class HelloClient { static void main(String args[]) { try{// get ORB and name server ORB orb = org.omg.CORBA.ORB.init(args, null); NamingContextExt nc = NamingContextExtHelper.narrow(orb.resolve_initial_references("NameService")); // generate name NameComponent [] name = nc.to_name( "Hello"); // query name server org.omg.CORBA.Object cob = nc.resolve(name); // get servant Hello serv = HelloHelper.narrow(cob); // use service System.out.println(serv.sayHello("Hansi")); } catch(Exception ex){ ex.printStackTrace(); System.exit(5);} }} Kompilierung des Beispiels " " Generierung der Skeletons/Stubs aus IDL-Spezifikation > idl hello.idl – Skeletons: – Stub: – Hilfsklassen: HelloHelper.java HelloHolder.java – Interfaces: " " Speicherung der IOR als Text in Datei – Übereinstimmung mit ~/.jacorb_properties ORBInitRef.NameService= http://www.inf.fu-berlin.de/~name/ns.ior Starten des Servers > jaco HelloServer Server is ready. Starten des Clients > jaco HelloClient Hello Hansi! Hello.java HelloOperations.java Dateistruktur des zur Verfügung gestellten Beispiels Starten des Name-Servers > ns /home/troll/name/public_html/ns.ior – _HelloStub.java Kompilation aller Java-Klassen > javac *.java Starten des Beispiels " HelloPOA.java HelloPOATie.java " Verzeichnishierarchie: – Src " " Java IDL vs01/helloCORBA/*.java vs01/helloCORBA/*.idl GENERATED – Classes Skripten: – make.sh erzeugt IDL, kompiliert Java Klassen – start_server.sh, start_client.sh – " " " startet Klient/Server aber nicht den Namensdienst Erweiterung des Klassenpfads um Classes/ Installation von JacORB " " Lokale Installation, für csh in /import/public/opt/JacORB/install.csh: setenv JACORB_HOME /import/public/opt/JacORB setenv PATH $JACORB_HOME/bin:$PATH setenv CLASSPATH $JACORB_HOME/lib/jacorb.jar:$CLASSPATH " Weitere Werkzeuge Sourcen mit Beispielen, Dokumentation etc.: http://www.jacorb.org/ " " " Kopieren und evtl. Konfiguration von jacorb.properties Starten von Java-Programmen mit jaco Kompilation von IDL-Schnittstellen mit idl (Achtung: Das richtige idl benutzen!) org.omg.CORBA.Object Portable Object Adapter ORB-Methoden " Zugriff auf den lokalen ORB " ORB ORB.init(String[] args,java.util.Properties props) " " Umwandlung CORBA Objektreferenzen ↔ Strings String ORB.object_to_string(org.omg.CORBA.Object obj) org.omg.CORBA.Object ORB.string_to_object(String ior) " " " Zugriff auf den Namensdienst CORBA.Object ORB.resolve_initial_references("NameService") " Wartet auf Terminierung aller registrierten Servants ORB.run() Analyse von IORs: >dior -f ~/public_html/ns.ior ------IOR components----TypeId : IDL:omg.org/CosNaming/NamingContext:1.0 Profile Id : TAG_INTERNET_IOP Host : 160.45.110.127 Port : 4799 ........ > cp $JACORB/jacorb_properties.template ~/.jacorb_properties " GUI für den Namensdienst: > nmg " " Sauberes Beenden des ORBs (mit POAs und Servants) ORB.shutdown(boolean wait_for_completion) " Existenz eines Objektes boolean Object.non_existent() Duplizieren einer Objektreferenz CORBA.Object Object.duplicate() Test ob Objektreferenz leer ist boolean Object.is_nil() Gleichheitstest auf Objektreferenzen true→gleich (•ø) boolean Object.is_equivalent(Object other) Zugriff auf den Standard-POA POA poa = POAHelper.narrow(orb.resolve_initial_references("RootPOA")) Anmelden eines Servants beim POA CORBA.Object servant_to_reference(Servant serv) Konfigurierbare Eigenschaften in .jacorb_properties " Ort der Objektreferenz für den Nameserver ORBInitRef.NameService= http://www.inf.fu-berlin.de/ ~name/ns.ior " " Debug Ausgaben (0-keine, 1-wichtige,...10) jacorb.verbosity=0 Graphische Anzeige aller POAs jacorb.poa.monitoring=on