idl2java
compiler. For each IDL construct there is a section that describes the corresponding Java construct, along with code samples. ISB for Java conforms with the OMG IDL/Java Language Mapping Specification. See the latest version of this specification for complete information, and especially, for information about the following:
This chapter includes the following major sections:
ooHelper
and fooHolder
are mapped to _fooHelper
and _fooHolder
, respectively, regardless of whether an interface named foo
exists. The Helper and Holder classes for interface fooHelper
are named _fooHelperHelper
and _fooHelperHolder
.
IDL names that would normally be mapped unchanged to Java identifiers that conflict with Java reserved words will have the collision rule applied.
Modules
The IDL module construct is mapped to a Java package and the package is given the same name as the IDL module. For all IDL types within the module that are mapped to Java classes or Java interfaces, the corresponding Java class or interface is declared inside the Java package that is generated. IDL declarations that are not enclosed in any modules are mapped into the unnamed Java global scope.
The following code example shows the Java code generated for an enumeration declared within an IDL module.
Mapping an IDL module to a Java package
/* IDL code from Example.idl: */
module Example { .... };
};// Generated Java code:
package Example;
...
} Global Scope
Any IDL construct declared in the global scope will be placed in a java package which is named IDL_GLOBAL. This name can be changed to a user defined one through the use of compiler options.
All the IDL examples used in this chapter are from the IDL module Example. Therefore, the generated Java declarations will all be placed inside the Java package Example.
Constants
Constants are mapped depending upon the scope in which they appear.
Constants within an Interface
Constants declared within an IDL interface are mapped to public static final
fields in the corresponding Java interface.
Mapping an IDL constant within a module to a Java class.
/* IDL code from Example.idl: */
module Example
interface Foo{
const long aLongerOne = -321;
};
};// Generated Java code:
package Example;
public interface Foo {
public static final int aLongerOne = (int) (-321L);
} Constants NOT within an Interface
Constants declared within an IDL module are mapped to a public interface with the same name as the constant and containing a public static final field named value. This field holds the constant's value.
NOTE: The Java compiler normally inlines the value when the class is used in other Java code.Mapping an IDL constant within a module to a Java class.
/* IDL code from Example.idl: */
module Example {
const long aLongOne = -123;
};
// Generated Java code:
package Example;
public interface aLongOne {
public static final int value = (int) (-123L);
}
NOTE: The Java null may only be used to represent the null object reference. For example, a zero length string, rather than null must be used to represent the empty string. This is also true for arrays.
Boolean
The IDL type boolean
is mapped to the Java type boolean
. The IDL constants TRUE and FALSE are mapped to the Java constants true and false.
char and wchar
IDL characters are 8-bit quantities representing elements of a character set, while Java characters are 16-bit unsigned quantities representing Unicode characters. To enforce type safety, the Java CORBA runtime asserts range validity of all Java char
s mapped from IDL char
s when parameters are marshaled during method invocation. If the char
falls outside the range defined by the character set, a CORBA::DATA_CONVERSION exception is thrown. The IDL wchar
maps to the Java char
type.
Octet
The IDL type octet
, an 8-bit quantity, is mapped to the Java type byte
.
String
The IDL type string
is mapped to the Java type java.lang.String
. Range checking for characters in the string as well as bounds checking of the string is done at marshal time.
WString
The IDL type wstring
, used to represent Unicode strings, is mapped to the Java type java.lang.String
. Bounds checking of the string is done at marshal time.
Integer Types
IDL short
and unsigned short
map to Java type short
. IDL long
and unsigned long
map to Java's int
.
NOTE: Because there is no support in Java for unsigned types, the developer is responsible for ensuring that negative integers in Java are handled correctly as large unsigned values.
narrow
operation defined for them.
// generated Java helper
public class <typename>Helper {
public static void
insert(org.omg.CORBA.Any a, <typename> t);
public static <typename> extract(Any a);
public static org.omg.CORBA.TypeCode type();
public static String id();
public static <typename> read(org.omg.CORBA.portable.InputStream istream)
{ ... };
public static void write(org.omg.CORBA.portable.OutputStream ostream, <typename> value)
{ ... };
// only for interface helpersThe helper class for a mapped IDL interface has a narrow operation defined for it. The helper class for a mapped IDL enum also has a from_int operation defined for it. Mapping of a named type to Java helper class
public static <typename> narrow(org.omg.CORBA.Object obj);
}
// IDL - named type
struct st {long f1, String f2};
// generated JavaMapping of a typedef sequence to Java helper class
public class stHelper {
public static void insert(org.omg.CORBA.Any any, st s) {...}
public static st extract(Any a) {...}
public static org.omg.CORBA.TypeCode type() {...}
public static String id() {...}
public static st read(org.omg.CORBA.InputStream is) {...}
public static void write(org.omg.CORBA.OutputStream os, st s) {...}
}
// IDL - typedef sequence
typedef sequence <long> IntSeq;
// generated Java helper
public class IntSeqHelper {
public static void insert(org.omg.CORBA.Any any, int[] seq);
public static int[] extract(Any a){...}
public static org.omg.CORBA.TypeCode type(){...}
public static String id(){...}
public static int[] read(org.omg.CORBA.portable.InputStream is)
{...}
public static void write(
org.omg.CORBA.portable.OutputStream os,
int[] seq)
{...}
}
org.omg.CORBA
package. Holder classes are generated for all named user-defined types except those defined by typedefs. For more information about Holder classes, see "Generated Classes."
For user-defined IDL types, the holder class name is constructed by appending Holder to the mapped Java name of the type.
For the basic IDL data types, the holder class name is the Java type name (with its first letter capitalized) to which the data type is mapped with an appended Holder
, for example IntHolder
.
Each holder class has a a default constructor and constructor from an instance, and a public instance member, value
, which is the typed value. The default constructor sets the value
field to the default value for the type as defined by the Java language:
org.omg.CORBA.portable.Streamable
interface.
The holder classes for the basic types are defined below. Note that they do not implement the Streamable interface. They are in the org.omg.CORBA
package.
// Java
package org.omg.CORBA;
final public class ShortHolder {
public short value;
public ShortHolder() {}
public ShortHolder(short initial) {
value = initial;
}
}
final public class IntHolder {
public int value;
public IntHolder() {}
public IntHolder(int initial) {
value = initial;
}
}
final public class LongHolder {
public long value;
public LongHolder() {}
public LongHolder(long initial) {
value = initial;
}
}
final public class ByteHolder {
public byte value;
public ByteHolder() {}
public ByteHolder(byte initial) {
value = initial;
}
}
final public class FloatHolder {
public float value;
public FloatHolder() {}
public FloatHolder(float initial) {
value = initial;
}
}
final public class DoubleHolder {
public double value;
public DoubleHolder() {}
public DoubleHolder(double initial) {
value = initial;
}
}
final public class CharHolder {
public char value;
public CharHolder() {}
public CharHolder(char initial) {
value = initial;
}
}
final public class BooleanHolder {
public boolean value;
public BooleanHolder() {}
public BooleanHolder(boolean initial) {
value = initial;
}
}
final public class StringHolder {
public java.lang.String value;
public StringHolder() {}
public StringHolder(java.lang.String initial) {
value = initial;
}
}
final public class ObjectHolder {
public org.omg.CORBA.Object value;
public ObjectHolder() {}
public ObjectHolder(org.omg.CORBA.Object initial) {
value = initial;
}
}
final public class AnyHolder {
public Any value;
public AnyHolder() {}
public AnyHolder(Any initial) {
value = initial;
}
}
final public class TypeCodeHolder {
public TypeCode value;
public typeCodeHolder() {}
public TypeCodeHolder(TypeCode initial) {
value = initial;
}
}
final public class PrincipalHolder {The Holder class for a user defined type <foo> is shown below:
public Principal value;
public PrincipalHolder() {}
public PrincipalHolder(TypeCode initial) {
value = initial;
}
}
}
// Java
final public class <foo>Holder
implements org.omg.CORBA.portable.Streamable {
public <foo> value;
public <foo>Holder() {}
public <foo>Holder(<foo> initial) {}
public void _read(org.omg.CORBA.portable.InputStream i)
{...}
public void _write(org.omg.CORBA.portable.OutputStream o)
{...}
public org.omg.CORBA.TypeCode _type() {...}
}
enum
is mapped to a Java final class
bearing the same name as the enum type. The final class declares a value method and two static data members per label, an integer conversion method, and a private constructor. An example follows:
An IDL enum mapped to a Java final class.
// Generated java
public final class <enum_name> {
//tech pair for each label in the enum
public static final int _<label> = <value>;
public static final <enum_name> <label> =
new <enum_name>(_<label>);
public int value() {...}
// get enum with specified value
public static <enum_name> from_int (int value);
//constructorOne of the members is a public static final that has the same name as the IDL enum label. The other has an underscore(_) prepended and is intended to be used in switch statements. The value method returns the integer value. Values are assigned sequentially starting with 0. If the enum has a label named value, there is no conflict with the value() method in Java. There will be only one instance of an enum. Since there is only one instance, pointer equality tests will work correctly. That is, the default
private <enum_name>(int) {...}
}
java.lang.Object
implementation of equals
and hash
will automatically work correctly for an enum's singleton object. The Java class for the enum also has an additional method, fromint
, which returns the enum with the specified value.
The holder class for the enum is also generated. Its name is the enum's mapped Java class name with Holder appended to it as follows:
Mapping an enum
public class <enum_name>Holder implements
org.omg.CORBA.portable.Streamable {
public <enum_name> value;
public <enum_name>Holder() {}
public <enum_name>Holder(<enum_name> initial) {...}
public void _read(org.omg.CORBA.portable.InputStream i)
{...}
public void _write(org.omg.CORBA.portable.OutputStream o)
{...}
public org.omg.CORBA.TypeCode _type() {...}
}
// IDL
enum EnumType {a, b, c};
// generated Java
public final class EnumType {
public static final int _a = 0;
public static final EnumType a = new EnumType(_a);
public static final int _b = 1;
public static final EnumType b = new EnumType(_b);
public static final int _c = 2;
public static final EnumType c = new EnumType(_c);
public int value() {...}
public static EnumType from_int(int value) { ... };
// constructor
private EnumType(int) {...}
};
final public class <class>Holder implements
org.omg.CORBA.portable.Streamable {
public <class> value;
public <class>Holder() {}
public <class>Holder(<class> initial) {...}
public void _read(org.omg.CORBA.portable.InputStream i)
{...}
public void _write(org.omg.CORBA.portable.OutputStream o)
{...}
public org.omg.CORBA.TypeCode _type() {...}
}
/* From Example.idl: */
struct StructType {
long field1;
string field2;
};
// generated Java
final public class StructType {
// instance variables
public int field1;
public String field2;
// constructors
public StructType() {}
public StructType(int field1, String field2)
{...}
}
final public class StructTypeHolder
implements org.omg.CORBA.portable.Streamable {
public StructType value;
public StructTypeHolder() {}
public StructTypeHolder(StructType initial) {...}
public void _read(org.omg.CORBA.portable.InputStream i)
{...}
public void _write(org.omg.CORBA.portable.OutputStream o)
{...}
public org.omg.CORBA.TypeCode _type() {...}
}
final public class <union_class>Holder
implements org.omg.CORBA.portable.Streamable {
public <union_class> value;
public <union_class>Holder() {}
public <union_class>Holder(<union_class> initial) {...}
public void _read(org.omg.CORBA.portable.InputStream i)
{...}
public void _write(org.omg.CORBA.portable.OutputStream o)
{...}
public org.omg.CORBA.TypeCode _type() {...}
}
/* From Example.idl: */
union UnionType switch (EnumType) {
case first: long win;
case second: short place;
case third:
case fourth: octet show;
default: boolean other;
};
// Generated java
final public class UnionType {
//constructor
public UnionType() {...}
//discriminator accessor
public int discriminator() { ... }
//win
public int win() { ... }
public void win(int value) { ... }
//place
public short place() { ... }
public void place(short value) { ... }
//show
public byte show() { ... }
public void show(byte value) { ... }
public void show(int discriminator, byte value) { ... }
//other
public boolean other() {...}
public void other(boolean value) { ... }
}
final public class UnionTypeHolder {
implements org.omg.CORBA.portable.Streamable {
public UnionType value;
public UnionTypeHolder() {}
public UnionTypeHolder(UnionType initial) {...}
public _void read(org.omg.CORBA.portable.InputStream is)
{...}
public void _write(org.omg.CORBA.portable.OutputStream os)
{...}
public org.omg.CORBA.TypeCode type() {...}
}
final public class <sequence_class>Holder {
public <sequence_element_type>[] value;
public <sequence_class>Holder() {};
public <sequence_class>Holder(
<sequence_element_type>[] initial) {...};
public void _read(org.omg.CORBA.portable.InputStream i)
{...}
public void _write(org.omg.CORBA.portable.OutputStream o)
{...}
public org.omg.CORBA.TypeCode _type() {...}
}
// IDL
sequence<long>UnboundedData;
sequence<long, 42> BoundedData;
// generated Java
final public class UnboundedDataHolder
implements org.omg.CORBA.portable.Streamable {
public int[] value;
public UnboundedDataHolder() {};
public UnboundedDataHolder(int[] initial) {...};
public void _read(org.omg.CORBA.portable.InputStream is)
{...}
public void _write(org.omg.CORBA.portable.OutputStream os)
{...}
public org.omg.CORBA.TypeCode type() {...}
}
final public class BoundedDataHolder
implements org.omg.CORBA.portable.Streamable {
public int[] value;
public BoundedDataHolder() {};
public BoundedDataHolder(int[] initial) {...};
public void _read(org.omg.CORBA.portable.InputStream is)
{...}
public void _write(org.omg.CORBA.portable.OutputStream os)
{...}
public org.omg.CORBA.TypeCode type() {...}
}
final public class <array_class>Holder
implements org.omg.CORBA.portable.Streamable {
public <array_element_type>[] value;
public <array_class>Holder() {}
public <array_class>Holder(
<array_element_type>[] initial) {...}
public void _read(org.omg.CORBA.portable.InputStream i)
{...}
public void _write(org.omg.CORBA.portable.OutputStream o)
{...}
public org.omg.CORBA.TypeCode _type() {...}
}
// IDL
const long ArrayBound = 42;
long larray[ArrayBound];
// generated Java
final public class larrayHolder
implements org.omg.CORBA.portable.Streamable {
public int[] value;
public larrayHolder() {}
public larrayHolder(int[] initial) {...}
public void _read(org.omg.CORBA.portable.InputStream is)
{...}
public void _write(org.omg.CORBA.portable.OutputStream os)
{...}
public org.omg.CORBA.TypeCode type() {...}
}
org.omg.CORBA.Object
interface.
The Java interface contains the mapped operation signatures. Methods can be invoked on an object reference to this interface.
The helper class holds a static narrow method that allows an instance of org.omg.CORBA.Object
to be narrowed to the object reference of a more specific type. The IDL exception CORBA::BAD_PARAM is thrown if the narrow fails.
There are no special "nil" object references. Java null
can be passed freely wherever an object reference is expected.
Attributes are mapped to a pair of Java accessor and modifier methods. These methods have the same name as the IDL attribute and are overloaded. There is no modifier method for IDL readonly attributes.
The holder class for the interface is also generated. Its name is the interface's mapped Java class name with Holder appended to it as follows:
Mapping an IDL interface to Java.
final public class <interface_class>Holder
implements org.omg.CORBA.portable.Streamable {
public <interface_class> value;
public <interface_class>Holder() {}
public <interface_class>Holder(
<interface_class> initial) {
value = initial;
public void _read(org.omg.CORBA.portable.InputStream i)
{...}
public void _write(org.omg.CORBA.portable.OutputStream o)
{...}
public org.omg.CORBA.TypeCode _type() {...}
}
/* From Example.idl: */
module Example {
interface Foo {
long method(in long arg) raises(e);
attribute long assignable;
readonly attribute long nonassignable;
}
}
// Generated java
package Example;
public interface Foo extends org.omg.CORBA.Object {
int method(int arg) throws Example.e;
int assignable();
void assignable(int i);
int nonassignable();
}
public class FooHelper {
// ... other standard helper methods
public static Foo narrow(org.omg.CORBA.Object obj)
{...}
}
final public class FooHolder
implements org.omg.CORBA.portable.Streamable {
public Foo value;
public FooHolder() {}
public FooHolder(Foo initial) {...}
public void _read(org.omg.CORBA.portable.InputStream is)
{...}
public void _write(org.omg.CORBA.portable.OutputStream os)
{...}
public org.omg.CORBA.TypeCode type() {...}
}
in
parameters implement call-by-value semantics, so IDL in
parameters are supplied by passing the actual parameter when a method is invoked. The results of IDL operations are returned as the result of the corresponding Java method.
The IDL out
and inout
parameters implement call-by-result and call-by-value/result semantics, so they cannot be mapped directly into the Java parameter passing mechanism. The mapping mechanism defines holder classes for all the IDL basic and user-defined types which are used to implement the parameter modes in Java. The client supplies an instance of the appropriate Java holder class that is passed by value for each IDL out
or inout
parameter. The contents of the holder instance, but not the instance itself, is modified by the invocation and the client uses the changed contents, if any changes were made, after the invocation returns.
IN parameter mapping to Java actual parameters.
/* From Example.idl: */In the example above, the result comes back as an ordinary result and the
module Example {
interface Modes {
long operation(in long inArg, out long outArg, inout long inoutArg);
};
};
// Generated Java:
package Example;
public interface Modes {
int operation(int inArg, IntHolder outArg, IntHolder inoutArg);
}
in
parameter is an ordinary value. But for the out
and inout
parameters, an appropriate holder must be constructed. A typical use case might look as follows:
// user Java codeBefore the invocation, the input value of the inout parameter must be set in the holder instance that will be the actual parameter. The inout holder can be filled in either by constructing a new holder from a value, or by assigning to the value of an existing holder of the appropriate type. After the invocation, the client uses the outHolder.value to access the value of the out parameter, and the inoutHolder.value to access the output value of the inout parameter. The return result of the IDL operation is available as the result of the invocation.
// select a target object
Example.Modes target = ...;
// get the in actual value
int inArg = 57;
// prepare to receive out
IntHolder outHolder = new IntHolder();
// set up the in side of the inout
IntHolder inoutHolder = new IntHolder(131);
// make the invocation
int result =target.operation(inArg, outHolder, inoutHolder);
// use the value of the outHolder
... outHolder.value ...
// use the value of the inoutHolder
... inoutHolder.value ...
Server implementation in Java using inheritance.
/* From Example.idl: */
module Example {
interface Account {
};
};
// Generated java
package Example;
abstract public class _sk_Account
extends org.omg.CORBA.Skeleton
implements Account { ... }
// Linking an implementation to the ORB :
class AccountImpl extends Example._sk_Account { ... } Server Implementation with Delegation
The use of inheritance to implement a server has one drawback: The server class extends the skeleton class, so it cannot use implementation inheritance for other purposes because Java only supports single inheritance. If the server class needs to use the inheritance link for another purpose, the delegation approach must be used.
When server classes are implemented using delegation, some extra code is generated:
Server implementation in Java using delegation.
/* From Example.idl: */
module Example {
interface Account
float balance();
};
};
// Generated java
package Example;
public interface AccountOperations {
public float balance();
};
package Example;
// Generated java
public class _tie_Account extends _sk_Account {
private AccountOperations delegate;
public _tie_Account(AccountOperations d) { ... }
public _tie_Account(AccountOperations d, String name) { ... }
public float balance() {
return delegate.balance();
}
}
// Linking an implementation to the ORB :
class AccountImpl implements Example.AccountOperations extends Whatever { ...}
...
Example.Account a_server = new Example._tie_Account(new AccountImpl());
... Interface Scope
Java does not allow declarations to be nested within an interface scope nor does it allow packages and interfaces to have the same name. Accordingly, interface scope is mapped to a package with the same name with an underscore suffix.
Mapping for Certain Nested Types
IDL allows type declarations nested within interfaces. Java does not allow classes to be nested within interfaces. Hence those IDL types that map to Java classes and that are declared within the scope of an interface must appear in a special "scope" package when mapped to Java.
IDL interfaces that contain these type declarations generate a scope package to contain the mapped Java class declarations. The scope package name is constructed by appending Package to the IDL type name.
Mapping for certain nested types
// IDL
module Example {
interface Foo {
exception e1 {};
};
}
// generated Java
package Example.FooPackage;
final public class e1 extends org.omg.CORBA.UserException {...} Mapping for Typedef
Java does not have a typedef construct.
IDL types that are mapped to simple Java types may not be subclassed in Java. Hence any typedefs that are type declarations for simple types are mapped to the original (mapped type) everywhere the typedef type appears. For simple types, Helper classes are generated for all typedefs.
Typedefs for non arrays and sequences are "unwound" to their original type until a simple IDL type or user-defined IDL type (of the non typedef variety) is encountered.
Holder classes are generated for sequence and array typedefs.
// IDL
struct EmpName {
string firstName;
string lastName;
};
typedef EmpName EmpRec;
// generated Java
// regular struct mapping for EmpName
// regular helper class mapping for EmpRec
final public class EmpName {
...
}
public class EmpRecHelper {
...
} Mapping for Exceptions
IDL exceptions are mapped very similarly to structs. They are mapped to a Java class that provides instance variables for the fields of the exception and constructors.
CORBA system exceptions are unchecked exceptions. They inherit (indirectly) from java.lang.RuntimeException
.
User-defined exceptions are checked exceptions. They inherit (indirectly) from java.lang.Exception
.
User-defined Exceptions
User-defined exceptions are mapped to Java classes that extend org.omg.CORBA.UserException
and are otherwise mapped just like the IDL struct type, including the generation of Helper and Holder classes.
If the exception is not defined within a nested IDL scope (essentially within an interface), its Java class name is defined within a special scope. Otherwise, its Java class name is defined within the scope of the Java package that corresponds to the exception's enclosing IDL module.
Mapping User-defined Exceptions
// IDL
module Example {
exception ex1 {string reason;}
}
// Generated Java
package Example;
final public class ex1 extends org.omg.CORBA.UserException {
public String reason; // instance
public ex1() {...} // default constructor
public ex1(String r) {...} // constructor
}
final public class ex1Holder
implements org.omg.CORBA.portable.Streamable {
public ex1 value;
public ex1Holder() {}
public ex1Holder(ex1 initial) { ... }
public void _read(org.omg.CORBA.portable.InputStream is)
{...}
public void _write(org.omg.CORBA.portable.OutputStream os)
{...}
public org.omg.CORBA.TypeCode type() {...}
}
Last Updated: 02/04/98 14:19:16
Any sample code included above is provided for your use on an "AS IS" basis, under the Netscape License Agreement - Terms of Use