Oracle8i CORBA Developer's Guide and Reference Release 3 (8.1.7) Part Number A83722-01 |
|
CORBA provides language independence. CORBA objects written in one language can send requests to objects implemented in a different language. Objects implemented in an object-oriented language such as Java or Smalltalk can talk to objects written in C or COBOL, and the converse.
Language independence is achieved through the use of a specification meta-language that defines the interfaces that an object--or a piece of legacy code wrappered to look like an object--presents to the outside world. As in any object-oriented system, a CORBA object can have its own private data and its own private methods. The specification of the public data and methods is the interface that the object presents to the outside world.
IDL is the language that CORBA uses to specify its objects. You do not write procedural code in IDL--its only use is to specify data, methods, and exceptions.
Each CORBA vendor supplies a compiler that translates IDL specifications into a specific language. Oracle8i JServer uses the idl2java
compiler from Inprise. The idl2java
compiler translates your IDL interface specifications into Java classes. See the Oracle8i Java Tools Reference for more information on this tool.
The following example demonstrates the IDL for the HelloWorld
example. See "Basic Example" for the complete example.
module hello { interface Hello { wstring helloWorld(); }; };
IDL consists of a module, which contains a group of related object interfaces. The IDL compiler uses the module name to name a directory where the Java classes are placed after generation. Also, the module name is used to name the Java package for the resulting classes.
This module defines a single interface: Hello
. The Hello
interface defines a single operation: helloWorld
, which takes no parameters and returns a wstring
(a wide string, which is mapped to a Java String
).
Note:
IDL data and exception types, such the |
The module and interface names must be valid Java identifiers and valid file names for your operating system. When naming interfaces and modules, remember that both Java and CORBA objects are portable, and that some operating systems are case sensitive and some are not, so be sure to keep names distinct in your project.
You can nest modules. For example, an IDL file that specifies the following modules maps to the Java package hierarchy package org.omg.CORBA
.
module org { module omg { module CORBA { ... }; ... }; ... };
Assume that the HelloWorld IDL is saved in a file called hello.idl
. When you run idl2java
to compile the hello
module, eight Java class files are generated and are placed in a subdirectory named hello
in the same directory as the IDL file:
% idl2java hello.idl Traversing hello.idl Creating: hello/Hello.java Creating: hello/HelloHolder.java Creating: hello/HelloHelper.java Creating: hello/_st_Hello.java Creating: hello/_HelloImplBase.java Creating: hello/HelloOperations.java Creating: hello/_tie_Hello.java Creating: hello/_example_Hello.java
The ORB uses these Java classes to invoke a remote object, pass and return parameters, and perform various other things. You can control the files generated, where they are put, and other aspects of IDL compiling--such as whether the IDL compiler generates comments in the Java files. See the complete description of the idl2java
compiler in the Oracle8i Java Tools Reference.
Each of the files generated is described below.
Hello |
This specifies, in Java, what the interface to a Hello object looks like. In this case, the interface is: package hello; public interface Hello extends org.omg.CORBA.Object { public java.lang.String helloWorld(); }
Because the file is put in a
You must implement the methods in the interface. It is recommended that the implementation class for the |
HelloHolder |
The application uses the holder class when parameters in the interface operation are of types |
HelloHelper |
The helper classes contain methods that read and write the object to a stream, and cast the object to and from the type of the base class. For example, the helper class has a LoginServer lserver = LoginServerHelper.narrow (orb.string_to_object (loginIOR));
Note that when you get an object reference using the JNDI |
_st_Hello |
The generated files that have These classes are installed on the client that calls the remote object. In effect, when a client calls a method on the remote object, it is really calling into the stub, which then performs the operations necessary to perform a remote method invocation. For example, it must marshall parameter data for transport to the remote host. |
_HelloImplBase |
Generated source files of the form |
HelloOperations |
The server uses these two classes for Tie implementations of server objects. See "Using the CORBA Tie Mechanism" for information about Tie classes. |
_example_Hello |
The |
An IDL interface body contains the following kinds of declarations:
This section gives a brief description of IDL datatypes and their mapping to Java datatypes. For more information about IDL types not covered here, see the CORBA specifications and the books cited in "For More Information".
Mapping between IDL basic types and Java primitive types is straightforward. Table 2-1 shows the mappings, as well as possible CORBA exceptions that can be raised on conversion.
The IDL character type char
is an 8-bit type, representing an ISO Latin-1 character that maps to the Java char
type, which is a 16-bit unsigned element representing a Unicode character. On parameter marshalling, if a Java char
cannot be mapped to an IDL char
, a CORBA DATA_CONVERSION exception is thrown.
The IDL string
type contains IDL chars. On conversion between Java String
, and IDL string
, a CORBA DATA_CONVERSION can be thrown. Conversions between Java strings and bounded IDL string
and wstring
can throw a CORBA MARSHALS exception if the Java String
is too large to fit in the IDL string.
Perhaps the most useful IDL constructed (aggregate) type for the Java developer is the struct. The IDL compiler converts IDL structs to Java classes. For example, the IDL specification:
module employee { struct EmployeeInfo { long empno; wstring ename; double sal; }; ...
causes the IDL compiler to generate a separate Java source file for an EmployeeInfo
class. It looks like this:
package employee; final public class EmployeeInfo { public int empno; public java.lang.String ename; public double sal; public EmployeeInfo() { } public EmployeeInfo( int empno, java.lang.String ename, double sal ) { this.empno = empno; this.ename = ename; this.sal = sal; } ...
The class contains a public constructor with parameters for each of the fields in the struct. The field values are saved in instance variables when the object is constructed. Typically, these are passed by value to CORBA objects.
The two types of ordered collections in CORBA are sequences and arrays. An IDL sequence maps to a Java array with the same name. An IDL array is a multidimensional aggregate whose size in each dimension must be established at compile time.
The ORB throws a CORBA MARSHAL exception at runtime if sequence or array bounds are exceeded when Java data is converted to sequences or arrays.
IDL also generates a holder class for a sequence. The holder class name is the sequence's mapped Java class name with Holder
appended to it.
The following IDL code shows how you can use a sequence of structs to represent information about employees within a department:
module employee { struct EmployeeInfo { long empno; wstring ename; double sal; }; typedef sequence <EmployeeInfo> employeeInfos; struct DepartmentInfo { long deptno; wstring dname; wstring loc; EmployeeInfos employees; };
The Java class code that the IDL compiler generates for the DepartmentInfo
class is:
package employee; final public class DepartmentInfo { public int deptno; public java.lang.String dname; public java.lang.String loc; public employee.EmployeeInfo[] employees; public DepartmentInfo() { } public DepartmentInfo( int deptno, java.lang.String dname, java.lang.String loc, employee.EmployeeInfo[] employees ) { this.deptno = deptno; this.dname = dname; this.loc = loc; this.employees = employees; }
Notice that the sequence employeeInfos
is generated as a Java array EmployeeInfo[]
.
Specify an array in IDL as follows:
const long ArrayBound = 12; typedef long larray[ArrayBound];
The IDL compiler generates this as:
public int[] larray;
When you use IDL constructed and aggregate types in your application, you must make sure to compile the generated .java
files and load them into the Oracle8i database when the class is a server object. You should scan the generated .java
files, and make sure that all required files are compiled and loaded. Study the Makefile
(UNIX) or the makeit.bat
batch file (Windows NT) of CORBA examples that define these types to see how the set of IDL-generated classes is compiled and loaded into the data server.
You can create new user exception classes in IDL with the exception key word. For example:
exception SQLError { wstring message; };
The IDL can declare that operations raise user-defined exceptions. For example:
interface employee { attribute name; exception invalidID { wstring reason; }; ... wstring getEmp(long ID) raises(invalidID); }; };
Mapping between OMG CORBA system exceptions and their Java form is also quite straightforward. These mappings are shown in Table 2-2.
The Oracle8i JVM development environment offers the Inprise Caffeine tools, which enable development of pure Java distributed applications that follow the CORBA model. You can write your interface specifications in Java and use the java2iiop
tool to generate CORBA-compatible Java stubs and skeletons.
Developers can also use the java2idl
tool to code in pure Java, yet still have IDL available that can be shipped to customers who are using a CORBA server that does not support Java. This tool generates IDL from Java interface specifications.
See the Oracle8i Java Tools Reference, for more information about java2iiop
and java2idl
.
|
Copyright © 1996-2000, Oracle Corporation. All Rights Reserved. |
|