This document describes the mapping of OMG IDL constructs to Java constructs.
This document is still being changed frequently
Please send comments to:
[email protected]
This document is not complete. We anticipate changes to improve compatibility with other vendors.
Items not yet addressed by this mapping are, DII, DSI and IDL Type Extensions.
We have no mapping for the concept of IDL Context's.
This document does not describe the exact mapping generated by a stubber. This document exhibits a nominal mapping, which is detailed enough for application programmers to use. An application is conformant when it works with the nominal mapping. A stubber is conformant when when it emits Java that works with any conformant application.
The actual name of this package is not a part of this submission, but we hope that the issue will be resolved in the actual OMG standard.
Available Java documentation
provides mixed and inconsistent messages about package names. We do not dare predict whether the OMG will follow the painful and inconsistently used DNS naming convention; i.e, name their package COM.omg.corba. More likely the OMG might state that CORBA is a standard and is not likely to cause conflicts; consequently the package name would be simply CORBA.
We have considered a design where all required classes are named with a prefix ``corba_''. The Java import with a ``*'' does not support import of packages, only import of classes. By prefixing all classes we would enable the user to write an import statement like
and opening up the corba package without fear of conflicts. We decided to ignore this issue and propose use of a short package name where programmers would not be tempted to use the import syntax with the asterisk. We view this limitation of the asterisk import to classes as a shortcoming in the Java language and urge removing this limitation in future versions of Java.import CORBA.*;
We only use a separator if we concatenate name pieces where one is defined by a programmer and the other is defined by this mapping.
Anticipating some mappings:
/* From the IDL source: */ module Example { interface FooBar_Mumble { ... }; };
// Generated names in package myprefix.Example class FooBar_Mumble_stub ... interface FooBar_Mumble ...
We believe that a consistent style which distinguishes composition according to whether it is coming from IDL or from the mapping might make programs easier to maintain.
The two main choices for the separator in mapping-defined compositions are underscore and the empty string. The underscore makes for a linguistically weaker binding, which combines more appropriately with IDL names that are themselves compositions of names in the problem domain. E.g., "alloc_bank_account" and "alloc_BankAccount" is a better set of choices than "allocbank_account" and "allocBankAccount".
IDL nested scopes (not modules) are handled by concatenating the names and using a separator.
maps to the Java classes example0 and example0_nest1./* IDL */ interface example0 { ... struct nest1 { ... } ... };
This is likely to happen to user defined names only because for most IDL defined names the capitalization prevents conflicts with Java keywords.
We do not yet specify how we handle other name conflicts due to unlucky names in an IDL file.
A module in IDL is mapped to a Java packages with the same name. The Java package tree is isomorphic to the module tree in IDL save that a top-level package prefix may be specified in an implementation-dependent fashion. This top-level package prefix can be set independently for each IDL module.
For an IDL type declared in a particular module, the corresponding Java classes and interfaces are declared inside the Java package generated for that module.
IDL allows definitions outside the scope of modules. We strongly discourage use of such IDL.
The generated mapping is as if each module in the file were complete; re-opening is considered only for modules whose only direct elements are themselves modules.
/* From the IDL source: */ module Example { const float pi = 3.1415; };
// Generated Java: package myprefix.Example; public final class pi { public static final float value = 3.1415; }
A client of Example::pi would reference the value as
myprefix.Example.pi.value
The IDL type char is mapped to the Java type char.
The Java type char which needs 16 bits can express characters which are not present in IDL's 8 bit character set. Characters which can't be represented cause a CORBA.CharacterRangeException exception or a subclass thereof to be thrown when marshalling. CORBA.CharacterRangeException is a subclass of CORBA.MARSHAL described later.
The IDL type octet is mapped to the Java type byte.
As the Java type byte contains a signed value from -128..127 the mapping will preserve equality modulo 256.
Both bounded and unbounded IDL string types are mapped to the Java type java.lang.String. Characters in the Java string which can't be represented as IDL characters cause an CORBA.CharacterRangeException exception, or a subclass thereof, to be thrown when marshalling.
Bounded IDL Strings are length checked when marshaling.
Attempts to marshal or unmarshal bounded strings with a length exceeding the bound will cause a CORBA.LengthException exception or subclass thereof to be raised.
IDL Java Number of bits short short 16 unsigned short short 16 long int 32 unsigned long int 32
An anticipated 64-bit integer type would be mapped into long.
IDL unsigned data types are mapped into the very same data type as the corresponding signed data types. Numbers which can't be correctly represented because of a lacking bit are represented by their corresponding bit pattern assuming a two's complement implementation.
IDL float maps into Java float; IDL double maps into Java double.
If an ORB uses a representation that limits precision, it needs to be documented.
All generated Java classes which are defined in this section as a mapping from an IDL type are named like the IDL type.
An IDL enum type is mapped to the Java int type. Additionally, a Java class is generated to hold a static final int for each enum member. The class name is the name of the IDL enum type.
/* From the IDL source: */ module Example { enum MyColor { white, red, blue, green }; };
// Generated Java: package myprefix.Example; public class MyColor { public static final int white = 0; public static final int red = 1; public static final int blue = 2; public static final int green = 3; public static final int narrow(int i) throws CORBA.EnumerationRangeException /* or a subclass */ { ... } }
The static narrow method either returns its input or throws an exception. It is used to verify that Java int's are in the range of the IDL enum.
An IDL struct is mapped to a Java class which has public instance variables for the fields. The class is named with the name of the IDL struct. It has a static method named alloc to create a new instance. The alloc method has one version that leaves fields unspecified and another version that initializes all fields.
/* From the IDL source: */ module Example { struct StructExample { short mumble; string greeting; }; };
// Generated to java: package myprefix.Example; public class StructExample { public short mumble; public String greeting; public static StructExample alloc() { ... } public static StructExample alloc(short mumble, String greeting) { ... } }
An IDL union is mapped to a Java class named with the name of the IDL union.
To construct values applications use one of the static allocation procedures which take both a discriminator value and a branch value. If the discriminator value is not legal for the chosen branch a CORBA.DiscriminantException exception or a subclass thereof is thrown. The allocation procedure is named after the branch with the prefix ``alloc_''.
The method discriminator returns the value of the discriminator.
The accessor method for a branch is named by the name of the branch with the prefix ``get_'' Attempts to call an accessor for other than the actual branch will throw a CORBA.DiscriminantException exception or a subclass thereof.
/* From the IDL source: */ module Example { union UnionExample switch (MyColor) { case red: long abc; case blue: short efg; case green: default: boolean xyz; }; };
// Generated Java: package myprefix.Example; public final class UnionExample { public int discriminator() throws CORBA.DiscriminantException /* or a subclass */ { ... } // abc public int get_abc() throws CORBA.DiscriminantException /* ...*/ { ... } public static UnionExample alloc_abc(int discriminator, int value) throws CORBA.DiscriminantException /* ...*/ { ... } // efg public short get_efg() throws CORBA.DiscriminantException /* ...*/ { ... } public static UnionExample alloc_efg(int discriminator, short value) throws CORBA.DiscriminantException /* ...*/ { ... } // xyz public boolean get_xyz() throws CORBA.DiscriminantException /* ...*/ { ... } public static UnionExample alloc_xyz(int discriminator, boolean value) throws CORBA.DiscriminantException /* ...*/ { ... } }
The allocation method alloc returns an union in an unknown state. A value is assigned with a setter named after the branch with the prefix ``set_''.
The setter methods take two arguments: a discriminator value and a branch value. If the discriminator value is not legal for the chosen branch a CORBA.DiscriminantException or subclass thereof is thrown. The setter methods returns the union.
Invoking accessor methods or the discriminator accessor, on uninitialized unions may throw an CORBA.DiscriminantException or could generate other Java runtime errors.
The following methods would be added to the example union class:
public static UnionExample alloc() { ... } public UnionExample set_abc(int discriminator, int value) throws CORBA.DiscriminantException /* ...*/ { ... } public UnionExample set_efg(int discriminator, short value) throws CORBA.DiscriminantException /* ...*/ { ... } public UnionExample set_xyz(int discriminator, boolean value) throws CORBA.DiscriminantException /* ...*/ { ... }
Marshaling will not modify union values but treat in arguments as readonly and allocate new unions for out or inout arguments.
Changing a union is not an atomic operation; however synchronization or single threaded usage is the clients responsibility.
An IDL sequence is mapped to a Java array. Everywhere the sequence type is needed, an array of the element type is used.
Bounded sequences have their bounds checked when
they are marshaled as parameters to IDL operations; a CORBA.LengthException exception, or a subclass thereof, is raised when the bounds are exceeded.
Exception: Sequences of characters are mapped to java.lang.String
Recalling the mapping for IDL structs:
/* From the IDL source: */ module Example { struct BarSequenceCont { sequence< StructExample > ubs; sequence< StructExample, 17 > fls; }; };
// Generated Java: package myprefix.Example; public final class BarSequenceCont { public myprefix.Example.StructExample[] ubs; public myprefix.Example.StructExample[] fls; public static BarSequenceCont alloc() { } public static BarSequenceCont alloc(myprefix.Example.StructExample[] ubs, myprefix.Example.StructExample[] fls) { ... } }
Note: The mapping does not prescribe any Java class for sequences. This means that no client visible operations needs such a class; it does not imply that an ORB couldn't use such a class for internal reasons.
An IDL array is mapped to a Java array. Everywhere the array type is needed, an array of the element type is used. The bounds are checked
when marshaling and a CORBA.LengthException exception, or a subclasst thereof, is raised when the bounds do not match.
The length of an array is not directly available as a constant. IDL modules designed with Java in mind will typically define an IDL constant if this number is desired.
/* From the IDL source: */ module Example { const long count = 17; struct FooStruct { long fooarray[count]; }; };
// Generated Java: package myprefix.Example; public final class FooStruct { public int[] fooarray; public static FooStruct alloc() { } public static FooStruct alloc(int[] fooarray) { ... } }
If ILU-style Optionals are ever adopted into the OMG IDL type system they will be mapped as follows:
If the base type of the optional maps into a Java primitive type we will represent the optional with the corresponding Java wrapper or container class. (Boolean, Character, Double, Float, Integer, or Long). The null value represents absence of the parameter.
If the base type of the optional maps into a Java object type, the optional is mapped as if it weren't optional. The null value represents absence of the parameter.
In the case of Java Strings the difference between a null String and an empty string serves this distinction perfectly.
Java has no concept for renaming a class. We ignore a typedef'ed name and ask the programmer to use its definition instead.
The ORB is always allowed to raise subclasses of the exception specified to be raised.
The Java class CORBA.Exception follows:
package CORBA; public class Exception extends java.lang.Exception { // may extend a subtype of java.lang.Exception instead // CORBA defined exception types. static public final int noException = 0; static public final int userException = 1; static public final int systemException = 2; // Accessors public int exceptionType() ... public String exceptionId() ... }
Note that there may be no public constructor.
It is a convention in Java that all subclasses of Throwable have two specific constructors. Most ORB's will honor this convention but the constructors may be declared off limits to users.
The exceptionId method returns the repository identifier for the exception.
The IDL defined exceptions have corresponding Java exceptions. All Java exceptions from the mapping of IDL defined system exceptions are (direct or indirect) subclasses of the CORBA.SystemException exception. CORBA.SystemException is a (direct or indirect) subclass of CORBA.Exception.
The standard system exceptions allow access to the minor code and completion status for the exception. All standard system exceptions are (maybe indirect) subclasses of CORBA.SystemException, shown here:
package CORBA; public class SystemException extends CORBA.Exception { // may extend a subtype of CORBA.Exception instead // Completion status constants. static public final int completedYes = 0; static public final int completedNo = 1; static public final int completedMaybe = 2; // Accessors public int completed() { ... } public int minor() { ... } }
There should be no public constructors for CORBA.SystemException. Applications should instantiate subclasses only.
The IDL standard system exceptions are mapped to the Java classes:
CORBA.UNKNOWN CORBA.BAD_PARAM CORBA.NO_MEMORY CORBA.IMP_LIMIT CORBA.COMM_FAILURE CORBA.INV_OBJREF CORBA.NO_PERMISSION CORBA.INTERNAL CORBA.MARSHAL CORBA.INITIALIZE CORBA.NO_IMPLEMENT CORBA.BAD_TYPECODE CORBA.BAD_OPERATION CORBA.NO_RESOURCES CORBA.NO_RESPONSE CORBA.PERSIST_STORE CORBA.BAD_INV_ORDER CORBA.TRANSIENT CORBA.FREE_MEM CORBA.INV_IDENT CORBA.INV_FLAG CORBA.INTF_REPOS CORBA.BAD_CONTEXT CORBA.OBJ_ADAPTER CORBA.DATA_CONVERSION CORBA.OBJECT_NOT_EXIST
As with CORBA.SystemException the constructors may be private and should not be used by applications. Instead of using a constructor, a static allocation method is provided for use by applications.
One allocation method requires default values for the minor code and completion status; another allocation method supplies default values. .
As an example, CORBA.UNKNOWN is declared to include:
This mapping document describes also a few exceptions that are subclasses of standard system exceptions. For example CORBA.CharacterRangeException, CORBA.LengthException, CORBA.EnumerationRangeException and CORBA.DiscriminantException are subclasses of CORBA.BAD_PARAM or a subclass thereof.package CORBA; public class UNKNOWN extends CORBA.SystemException { public static UNKNOWN alloc() {...} public static UNKNOWN alloc(int minor, int completed) {...} }
We have considered making CORBA.EnumerationRangeException and CORBA.DiscriminantException subclasses of java.lang.RuntimeException. In that case they would have been runtime errors and therefore methods which were declared to throw those exceptions could be used outside the scope of try-catch statements. It was a close call whether this benefit outweighs the conceptional cost of explain which exceptions are and which are not subclasses of CORBA.Exception. It would even be possible for ORBs to catch these runtime errors at marshal or unmarshal time and rethrow corresponding CORBA.SystemExceptions.
IDL user-defined exceptions are mapped similarly to IDL structs. A Java class is generated that provides instance variables for the fields of the exception. The class has static methods to construct instances. One version of the allocator method requires no arguments; an overloaded version requires all the fields of the exception.
IDL user-defined exceptions extend the Java class CORBA.UserException (or a subclass thereof, which in turn extends CORBA.Exception which indirectly extends java.lang.Exception). This makes it possible to catch specific user-defined exceptions, to catch all user-defined exceptions by catching CORBA.UserException, or, to catch all user-defined exceptions and system exceptions by catching CORBA.Exception.
/* From the IDL source: */ module Example { exception Barf { string because; }; };
// Generated Java: package myprefix.Example; public class Barf extends CORBA.UserException /*or a subclass*/ { public String because; public static Barf alloc() { ... } public static Barf alloc(String because) { ... } }
Operations of the IDL class CORBA::Object are special; these operations are not implemented by a object reference interface but are implemented as static methods of an ORB specific class. See the section Methods on CORBA::Object for details.
/* From the IDL source: */ module Example { interface MyIf { public void doit(); }; };
We show the generated Java interface, which is named by the name of the IDL interface.
// Generated Java: package myprefix.Example; public interface MyIf extends CORBA.Object { //or a subinterface thereof void doit() throws CORBA.SystemException; }
The Java interface extends the CORBA.Object Java interface.
To model IDL multiple interface inheritance in Java we use multiple inheritance in the Java interfaces.
This example shows a multiple inheritance lattice:
/* From the IDL source: */ module Example { interface Base { ... }; interface A: Base { ... }; interface B: Base { ... }; interface AB: A, B { ... }; };
or, as a picture:
Example::Base / \ / \ / \ / \ Example::A Example::B \ / \ / \ / \ / Example::AB
and its mapping to Java:
// Generated Java files
package myprefix.Example; public interface Base extends CORBA.Object { // ... operations }
package myprefix.Example; public interface A extends CORBA.Object, myprefix.Example.Base { // ... operations }
package myprefix.Example; public interface B extends CORBA.Object, myprefix.Example.Base { // ... operations }
package myprefix.Example; public interface AB extends CORBA.Object, myprefix.Example.A, myprefix.Example.B { // ... operations }
Each Java interface extends the Java interfaces for any base IDL interfaces.
This mapping is straight forward. We have considered more complex mappings, which map the CORBA::Object (P)IDL methods to methods of the CORBA.Object Java interface. These mappings use multiple Java interfaces to correspond to one IDL interface, and impose extra runtime cost on every local method call. Our mapping makes the CORBA::Object methods a little more expensive to implement, but the general simplicity using the same interfaces for stubs and skeletons is well worth that cost.
IDL parameter passing modes: in, out, and inout are mapped as follows:
IDL in parameters use pass-by-value. The value is not changed by the server.
IDL out parameters are mapped by passing a singleton (one element) array as a holder because the Java language has no corresponding parameter passing mode. A client supplies the singleton array of the appropriate class that is passed (by value) for each IDL out parameter. The content of the array element (but not the array itself) is modified by the invocation, and the client extracts the changed content after the invocation returns.
IDL inout parameters use the same singleton array holder as IDL out parameters do. The element is passed in by value and before the function return, the result value is assigned to the holder element. The input argument is not modified but a new value for the output argument is assigned to the array element.
/* From the IDL source: */ module Example { interface ResultType ... ; interface InType ... ; interface OutType ... ; interface InOutType ... ; interface Modes { ResultType operation(in InType inArg, out OutType outArg, inout InOutType inoutArg); }; };
// Generated Java: package myprefix.Example; public interface Modes { myprefix.Example.ResultType operation(myprefix.Example.InType inArg, myprefix.Example.OutType[] outArg, myprefix.Example.InOutType[] inoutArg) throws CORBA.SystemException; }
The result comes back as an ordinary Java result value; the in parameter needs only an ordinary value as the actual; but for the out and inout parameters, an appropriate singleton array must be constructed. A typical calling sequence for this operation might look like:
// sample Java program myprefix.Example.Modes target = ... // this will be the target object myprefix.Example.InType inArg = ... // prepare the "in" argument myprefix.Example.OutType[] outHolder = // prepare to receive the "out" new myprefix.Example.OutType[1]; myprefix.Example.InOutType[] inoutHolder = // set up "in" side of "inout" new myprefix.Example.InOutType[1]; inoutHolder[0] = (...); myprefix.Example.ResultType result = // invoke the operation target.operation(inArg, outHolder, inoutHolder); ... outHolder[0] ... // use "out" value from outHolder ... inoutHolder[0] ... // use "inout" value of inoutHolder
To prepare the call, the ``in`` side of the inout parameter must be put in the array for the inout actual. After the invocation, the client can use outHolder[0] to access the value of the out parameter, and inoutHolder[0] to access the out side of the inout parameter. The return result of the IDL operation is available as the result of the invocation; no holder is required.
Some designs limit the inout parameters for unbounded sequences and strings to not return longer sequences then their input. The Java mapping has NO such limitation. Such a limitation makes sense only for languages without automatic memory management.
We have considered several designs for holder classes. One version uses holder classes named after the IDL type they are holding; the second design used holder classes named after the Java type they are holding. Using arrays bypasses the problem of how holders are named and in which package holders are stored. It also requires the smallest number of Java classes and files generated.
We have also considered to not using any holder classes for types which are represented with Java objects which are mutable. In particular for the case of inout types struct, sequence, array, and if they were mutable Any and unions, the parameter could be modified in place. We believe that our design of allocating new objects is more robust and easier to use for applications.
IDL attributes are syntactic sugar for accessor and modifier operations for typed fields. We will define an accessor method and a modifier method, if the IDL attribute is not read-only. The name of the accessor method is the name of the attribute prefixed by ``get_''. The name of the modifier method is the name of the attribute prefixed by ``set_''.
/* From the IDL source: */ module Example { interface SampleAttributes { attribute long mutable; readonly attribute long readable; }; };
// Generated Java: package myprefix.Example; public interface SampleAttributes { int get_mutable() throws CORBA.SystemException; void set_mutable(int arg) throws CORBA.SystemException; int get_readable() throws CORBA.SystemException; }
Client applications have no need to know about the stub class directly as these are instantiated by the ORB.
As the reference interface doesn't contain the methods on CORBA::Object, the stub class doesn't need to implement these methods either; see the chapter Methods on CORBA::Object. The Java stub class has a private constructor, so clients can not create new IDL object references.
A Java null can be passed anywhere a null object reference is needed.
/* From the IDL source: */ module Example { interface ResultType ...; interface ParameterType ...; exception Barf { ... }; interface Service { ResultType operation(in ParameterType arg) raises (Barf); }; };
// Generated Java: package myprefix.Example; public interface Service extends CORBA.Object { //or a subclass thereof myprefix.Example.ResultType operation(myprefix.Example.ParameterType arg) throws CORBA.SystemException, myprefix.Example.Barf; }
// Generated Java: package myprefix.Example; public class Service_stub implements CORBA.Object, //or a subinterface thereof myprefix.Example.Service { // IDL operations // Implementation of ::Example::Service::operation public myprefix.Example.ResultType operation(myprefix.Example.ParameterType arg) throws CORBA.SystemException, myprefix.Example.Barf { ... }
We use the very same mapping for object references on the server side as we do on the client side.
To implement an IDL interface, an application needs to provide a class that implements the corresponding Java interface. A stubber might optionally generate a template class which could be used to fill in the actual methods. A implementer must be free to use (edit, extend) such an automatically generated template or to write the whole class from scratch.
A server side object implementation must declare itself as implementing the Java interface corresponding to the IDL interface. An ORB may impose the restriction on applications that Java servant objects must not make use of the Java finalize method. No other demands are made on an implementation. In particular, there is no requirement that the implementation extend any Java classes.
We have also considered the following requirement:
To implement an IDL interface clients also need to declare to implement the CORBA.ServantSupport Java interface. This interface does not require any methods to be implemented; it is strictly used for type checking. If an ORB vendor chooses to provide an skeleton base class for server applications, or provides the automatically generated skeleton, that skeleton base class shall be a subclass of a class named CORBA.ServantBase and shall implement CORBA.ServantSupport.
The finalize method is off limits and replaced by a specific interface to enable an ORB vendor to make circular structures containing servant objects and enforce a finalization order of its choice. This is necessary for certain ORB's to implement distributed garbage collection.
package CORBA; public interface ServantFinalizable extends CORBA.Object { public void servantFinalize() throws Throwable; } package CORBA; public class ServantFinalizer { public static void doFinalize(ServantFinalizable obj) { //... ensures call of obj.servantFinalize() } }
The requirement on the server application to call ServantFinalizer.servantFinalize in its normal finalize method enables an ORB which doesn't have any internal reasons to call servantFinalize to do so easily without keeping any state variables.
While the mechanism of calling ServantFinalizer.doFinalize initially looks complicated, it bears no runtime cost if the application does not require its own finalization.
The CORBA::Object type maps to the Java interface
CORBA.Object.
The Java interface for each user-defined
IDL interface extends the Java interface
CORBA.Object, or a subclass thereof, so that any Java interface can
be passed anywhere a CORBA.Object is expected.
The CORBA.Object interface does not include Java methods that manipulate CORBA::Object object
references but a class CORBA.ObjectClass provides static methods for this purpose.
Applications must not subclass CORBA.Object directly because ORBs are allowed to return implementation specific subinterfaces of CORBA.Object and might relax input arguments to a implementation specific superinterfaces of CORBA.Object.package CORBA; public class ObjectClass extends ... implements ... { // // Check if this object supports the interface represented // by the argument. public static boolean isA(CORBA.Object that, String repositoryIdentifier) throws CORBA.SystemException { ... } //Optionally may accept a superinterface of CORBA.Object // Other methods as specified in section 7.2 of the CORBA 2 spec }
Since Java has automatic memory management, duplicate and release are not required functions.
The methods of CORBA::Object appear in CORBA.ObjectClass instead of CORBA.Object so that server programmers don't have to implement any generic CORBA-mandated methods.
package CORBA; public class TypeCode extends ... { public static TypeCode find(java.lang.String corba_rep_id) throws CORBA.SystemException {...} public java.lang.String id() throws CORBA.SystemException {...} public java.lang.String name() throws CORBA.SystemException {...} public int kind() throws CORBA.SystemException {...} // ... Other methods as specified in section 6.7 of the CORBA 2 spec ... public static final TypeCode tc_null; public static final TypeCode tc_void; public static final TypeCode tc_short; public static final TypeCode tc_long; public static final TypeCode tc_ushort; public static final TypeCode tc_ulong; public static final TypeCode tc_float; public static final TypeCode tc_double; public static final TypeCode tc_boolean; public static final TypeCode tc_char; public static final TypeCode tc_octet; public static final TypeCode tc_any; public static final TypeCode tc_TypeCode; public static final TypeCode tc_Object; public static final TypeCode tc_string; }TypeCodes are constant.
package CORBA; public class TCKind { public static final int tk_null = 0; public static final int tk_void = 1; public static final int tk_short = 2; public static final int tk_long = 3; public static final int tk_ushort = 4; public static final int tk_ulong = 5; public static final int tk_float = 6; public static final int tk_double = 7; public static final int tk_boolean = 8; public static final int tk_char = 9; public static final int tk_octet = 10; public static final int tk_any = 11; public static final int tk_TypeCode = 12; public static final int tk_objref = 14; public static final int tk_struct = 15; public static final int tk_union = 16; public static final int tk_enum = 17; public static final int tk_string = 18; public static final int tk_sequence = 19; public static final int tk_array = 20; public static final int tk_alias = 21; public static final int tk_except = 22; // the actual numeric values are implementation dependent, // and implementation-dependent extension typekinds may be present. public static final int narrow(int i) throws CORBA.EnumerationRangeException /* or a subclass */ {...} }
The Any class has no public constructor; there is a static ``alloc'' method which allocates and initializes the Any. The Any class also has ``type'' and ``value'' methods for obtaining the TypeCode of the Any, and its value as a Java object.
All ORB methods which accept an Any may accept a superclass; all methods which generate an Any may generate a subclass. As a consequence of the class not being fully specified, portable applications can not subclass Any directly.
package CORBA: public class Any extends ... { public static Any alloc(CORBA.TypeCode type, java.lang.Object value) throws CORBA.SystemException { // The Any return value can be a subclass. // The formal value input argument needs to have the Java class // or subclass for the mapping of the IDL type. If an input // argument is mapped to a Java basic type, this procedure will // accept the corresponding Java wrapper class. ... } public TypeCode type() throws CORBA.SystemException { // Returns a TypeCode for the value contained in the Any. ... } public java.lang.Object value() throws CORBA.SystemException { // Returns a Java value for the value contained in the Any. // Returns instances of Java wrapper classes instead of Java basic types. ... } //... More methods are desribed in the section on helper classes }All operations may throw a CORBA.SystemException or a subclass thereof; in particular CORBA.DiscriminantException may be thrown.
We are using a static method to create Any to allow ORBs to deal in subclasses.
We were contemplating a design where Any values were mutable. This design used a set method to assign some value to an Any and a setClone method to extract and assign the value from another Any. Modifying an CORBA.Any would not have been an atomic operation; synchronization or single threaded usage were the client's responsibility. We decided that the simplicity of the immutable design is desirable. If ever an application would require mutability it can use a holder array; respectively in IDL make an interface with an Any attribute.
For the IDL type, barType, the following helper class is generated.
// Generated Java: // Assuming barType is an IDL type defined in module Example // and mappedBarType is the Java type prescribed by the // mapping of barType. // package myprefix.Example; public class barType_help { public static CORBA.Any toAny(mappedBarType t) throws CORBA.SystemException {...} public static mappedBarType fromAny(CORBA.Any) throws CORBA.SystemException {...} public static boolean isContained(CORBA.Any) throws CORBA.SystemException {...} public static CORBA.TypeCode typecode() throws CORBA.SystemException {...} public static String repository_id() throws CORBA.SystemException {...} }The issue of a helper class for anonymous IDL sequences or arrays (i.e., not named with a typedef) is not addressed.
For IDL standard types we intend to include methods to the Any class as follows, where Foo stands for the IDL types short, long, ushort, ulong, float, double, boolean, char, octet, any, TypeCode, Object, string and mappedFoo stands for the Java type from the mapping of Foo:
// In CORBA.Any: // public static Any from_Foo(mappedFoo value) throws CORBA.SystemException {...} public boolean contains_Foo() throws CORBA.SystemException {...} public mappedFoo value to_Foo(Any) throws CORBA.SystemException {...}
The Java Language Specification
http://www.javasoft.com/doc/language_specification/index.html
Mapping proposal from Sun
http://splash.javasoft.com/pages/IDLtoJava.html
Mapping proposal from Blackwidow
http://www.visigenic.com/BW/idl2javamapping.html
Mapping proposal from Orbix
http://www.iona.com/Orbix/OrbixWeb/doc/pguide/map.html
The final Java modifier for the mapping of structs is removed.
Standard exceptions are created with one single call; Standard exceptions which are not IDL defined are subclases of CORBA.BAD_PARAM.
A restriction on ObjectClass is removed.
Included a new paragraph on a replacement for the finalize Java method.
Introduction of helper classes to support TypeCode and Any.
Change-bar like comments can be found in the html source of this document.
The companies and organizations listed above hereby grant a royalty-free license to the Object Management Group (OMG) for world-wide distribution of this document or any derivative works thereof, so long as the OMG reproduces the copyright notices and the below paragraphs on all distributed copies.
The material in this document is provided for evaluation by the OMG. Submission of this document does not represent a commitment to implement any portion of this specification in the products of the above said companies and organisations.
While the information in the publication is believed to be accurate, the companies and organisations listed above make no warranty of any kind with regard to this material including but not limited to the implied warranties of merchantability and fitness for a particular purpose. The companies and organisations listed above shall not be liable for errors contained herein or for incidental or consequent damages in connection with the furnishing, performance or use of this material. The information contained in this document is subject to change without notice.
This document contains information which is protected by copyright. All Rights Reserved. No part of this work covered by copyright here on may be reproduced or used in any form or by any means - graphic, electronic, or mechanical, including photocopying, recording, taping, or information storage and retrieval systems - without permission of the copyright owners. All copies of this document must include the copyright and other information contained on this page.
The copyright owners grant the Object Management Group permission to reproduce and use the information contained in this document. The copyright owners grant a limited waiver of the copyright on this document to members of the Object Management Group so that they can each reproduce up to 50 copies of this document for their internal use as part of the OMG evaluation process.
RIGHTS RESERVED LEGEND. Use, duplication, or disclosure by government is subject to restrictions as set forth in subdivision (c)(1)(ii) of the Right in Technical Data and Computer Software Clause at DFARS 252.227.7013.
CORBA, OMG IDL are trademarks of The Object Management
Group, Inc.
Java is a trademark of Sun Microsystems Inc.