Diese Sektion befaßt sich mit dem CORBA-to-Java Mapping für allgemeine CORBA Konstrukte.
Ein CORBA IDL module wird in ein Java package mit dem gleichen Namen wie das IDL module transformiert:
OMG IDL |
Java |
|
|
Abbildung 1 zeigt die CORBA Exception Hierarchie. CORBA defniert zwei Arten von Exceptions:
Exception Hierarchie
Im CORBA/Java Mapping leiten sich die Standard CORBA SystemExceptions indirekt von der java.lang.Runtime.Exception ab. Sie transformieren es zu final Java Klassen, die
org.omg.CORBA.SystemException
erweitern
Die Namen der Java Klassen, die Standard IDL Exception repräsentieren, ist die gleiche wie der IDL Name, der im
org.omg.CORBA Package
deklariert ist. Der String explanation
dient zur Aufnahme einer Beschreibung, die die Ursache der Exception erläutert.
OMG IDL |
Java |
|
|
Als Basis für das Beispiel dient das Programm aus
Eine erste JavaCORBA Anwendung.Zunächst wird das CORBA IDL Interface verändert. Es wird eine Exception eingefügt, die von increment ausgelöst werden soll, wenn die Variable sum bei einem weiterem Inkrementiervorgang den Wertebereich ihren Typs verläßt. Da dies im Falle eines long recht lange dauert, wird der Typ von sum von long zu octet hin verändert. Dieser Typ wird vom IDL Compiler in byte transformiert.
module Counter {
exception NumberToBigException {
string explanation;
};
interface Count {
attribute octet sum;
octet increment() raises (NumberToBigException);
};
};
Mit octet increment() raises(NumberToBigException);
wird angegeben, daß increment()
eine Exception des Typs NumberToBigException
auslösen kann. Wenn increment()
mehrere Exceptions auslösen kann, so wir dies allgemein durch folgendes ausgedrückt:
Typ Methodenname(Parameter1, ..., Parametern) raises (Exception1, ..., Exceptionn);
Durch
Prompt> idl2java Count.idl -no_comments -no_tie
wird ein Package Counter erstellt, das die folgenden Dateien beinhaltet:
Jetzt muß CountImpl wie folgt verändert werden:
import Counter.NumberToBigException;
class CountImpl extends Counter._CountImplBase {
private byte sum;
CountImpl(String name) {
super(name);
System.out.println("Count Object Created");
sum = 0;
}
public byte sum() {
return sum;
}
public void sum(byte val) {
sum = val;
}
public byte increment() throws NumberToBigException {
if (sum < 127) {
sum++;
return sum;
}
else
throw new NumberToBigException("sum to big");
}
}
Zuletzt muß noch CountClient so verändert werden, daß die benutzerdefinierte Exception abgefangen wird:
class CountClient {
public static void main(String args[]) {
try {
System.out.println("Initializing the ORB");
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null);
System.out.println("Binding to Count Object");
Counter.Count counter = Counter.CountHelper.bind(orb, "My Count");
System.out.println("Setting sum to 0");
counter.sum((byte)0);
long startTime = System.currentTimeMillis();
System.out.println("Incrementing");
for (int i = 0; i < 1000; i++)
try {
counter.increment();
}
catch (Exception e) {
System.out.println(e.toString());
counter.sum((byte)0);
}
long stopTime = System.currentTimeMillis();
System.out.println("Avg Ping = " + ((stopTime - startTime)/1000f) + "msecs");
System.out.println("Sum = " + counter.sum());
}
catch(org.omg.CORBA.SystemException e) {
System.err.println("System Exception");
System.err.println(e);
}
}
}
Die Klasse CountServer muß nicht verändert werden, da sich nichts an der Initialisierung verändert hat.
Jetzt muß alles mit
Prompt> vbjc CountClient.java
Prompt> vbjc CountServer.java
Prompt> vbjc CountImpl.java
compiliert werden und danach kann das Beispiel durch
Prompt> start osagnet -c
Prompt> start vbj CountServer
Prompt> vbj CountClient
gestartet werden.
Die Quellen:
CORBA IDL definiert drei Parameter Übergabe-Modi:
in
, out
und inout
. Hingegen unterstützt Java lediglich den Modus in
. Wie ihre Java Gegenstücke, implementieren in
Parameter die Call-by-Value Semantik. Deswegen werden sie in normale Java Parameter transformiert. Genauso geschieht es mit den Rückgabewerten, die direkt in die entsprechenden Java Typen transformiert werden.
Hingegen besitzen die IDL
out
und inout
Parameter keine Gegenstücke in Java. Deswegen muß das IDL-to-Java Mapping zusätzliche Mechanismen zur Unterstützung von Call-by-Reference für IDL out
und inout
Parametern bieten. Das Mapping definiert sogenannte Holder Klassen, die als Container für sämtliche IDL Basis und benutzerdefinierten Typen dienen. Diese Holder implementieren zusätzliche Parameter Übergabe Modi in Java. Der Client muß eine Instanz der entsprechenden Holder Klasse für jeden IDL out
oder inout
Parameter bilden.
Der ORB bietet Holder Klassen für sämtliche IDL Basis Datentypen, die Teil des
org.omg.CORBA
Package sind, an. Der Name einer Holder Klasse entspricht dem Namen des Java Datentyps mit angehängtem Holder (beispielsweise ShortHolder
für den Java Datentyp short
).
Zum Speichern beziehungsweise Auslesen eines Wertes aus der Holder Klasse wird auf
public Typ value
zugegriffen, wobei mit Typ der Typ des zu übergebenden Parameters gemeint ist.
Als Basis für das Beispiel dient wieder Eine erste JavaCORBA Anwendung. Diesmal wird das IDL Interface um eine Methode erweitert, der als Parameter ein Integer übergeben wird. Diesem Integer
wird innerhalb der Methode der Wert des Attributes sum
zugewiesen. Da im übergebenen Integer
der Wert des Attributes sum
gespeichert wird ist es erforderlich, daß der Parameter über Call-by-Reference übergeben wird. Da der ursprüngliche Wert des übergebenen Parameters nicht weiter interessiert, ist der Parameter sum
ein IDL out
Parameter. Wäre der ursprüngliche Wert zunächst für die Methode von Interesse, so müßte der Parameter ein IDL inout
Parameter sein.
module Counter {
interface Count {
attribute long sum;
long increment ();
void getSum(out long sum);
};
};
Mit dem Aufruf
Prompt> idl2java Count.idl -no_comments -no_tie
werden die folgenden Dateien generiert:
Als nächstes wird die Implementation von Count
erstellt. Der einzige Unterschied zwischen dem hier entwickelten CountImpl
und dem in erstelltem CountImpl
liegt darin, daß eine weitere Methode hinzugekommen ist.
Beim betrachten der Methode ist zu erkennen, daß der IDL Compiler out long sum
in die entsprechende Holder Klasse transformiert hat.
class CountImpl extends Counter._CountImplBase {
private int sum;
CountImpl(String name) {
super(name);
System.out.println("Count Object Created");
sum = 0;
}
public int sum() {
return sum;
}
public void sum(int val) {
sum = val;
}
public int increment() {
sum++;
return sum;
}
public void getSum(
org.omg.CORBA.IntHolder sum
) {
sum.value = this.sum;
}
}
Beim eigentlichem Server müssen keine Veränderungen vorgenommen werden, da das Erzeugen einer Instanz von CountImpl
identisch zum Erzeugen der Klasse in Eine erste JavaCORBA Anwendung ist.
In der CountClient
Klasse wird eine Instanz der Klasse IntHolder
gebildet. Sie dient als Übergabeparameter an die Methode getSum
der Klasse CountImpl
.
Nachdem das Inkrementieren beendet ist, wird die Instanz der Klasse IntHolder
an getSum
übergeben und der in ihr gespeicherte Wert ausgegeben.
class CountClient {
public static void main(String args[]) {
try {
org.omg.CORBA.IntHolder sum = new org.omg.CORBA.IntHolder();
System.out.println("Initializing the ORB");
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null);
System.out.println("Binding to Count Object");
Counter.Count counter = Counter.CountHelper.bind(orb, "My Count");
System.out.println("Setting sum to 0");
counter.sum((int)0);
long startTime = System.currentTimeMillis();
System.out.println("Incrementing");
for (int i = 0; i < 100; i++)
counter.increment();
counter.getSum(sum);
long stopTime = System.currentTimeMillis();
System.out.println("Avg Ping = "
+ ((stopTime - startTime)/1000f) + "msecs");
System.out.println("Sum = " + sum.value);
}
catch(org.omg.CORBA.SystemException e) {
System.err.println("System Exception");
System.err.println(e);
}
}
}
Die Quellen:
Helper Klassen beinhalten Methoden, die die Manipulation von IDL Typen auf verschiedenen Wegen erlauben. Der IDL-to-Java Compiler generiert eine Helper Java Klasse für jeden IDL Typ und jedes Interface, das vom Entwickler definiert wurden ist. Der Name der Klasse ist der Name des definierten Typs mit einem angehängten Helper (beispielsweise CountHelper.java für Count.java).
CORBA IDL Interfaces können Attribute besitzen. Jedes Attribut wird zu Java Ausgabe- und Manipulationsmethoden mit dem Namen des Attributs transformiert. Ein IDL Attribut kann als readonly gekennzeichnet werden. In einem solchen Fall werden nur die Ausgaberoutinen Operationen definiert.
OMG IDL |
Java |
|
|
Es muß leider an dieser Stelle darauf hingewiesen werden, daß die Namengebung zwar mit den Konventionen von CCRBA C++ und Smalltalk übereinstimmen, aber im Konflikt mit den Java Namenskonventionen stehen.
© Copyright 1998 André Möller, Oliver Mentz & Magnus Wiencke