java language to idl mapping joint submission (rtf update) · joint submission (rtf update) inprise...

75
Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications Corporation Oracle Corporation Sun Microsystems, Inc. OMG TC Document orbos/98-07-19 Java Language to IDL Mapping

Upload: others

Post on 18-Aug-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

Joint Submission (RTF update)

Inprise Corporation

International Business Machines Corporation

Netscape Communications Corporation

Oracle Corporation

Sun Microsystems, Inc.

OMG TC Document orbos/98-07-19

Java Language to IDL Mapping

Page 2: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 2 8/7/98

Copyright © 1998 by Inprise CorporationCopyright © 1998 by International Business Machines CorporationCopyright © 1998 by Netscape Communications Corporation.Copyright © 1998 by Oracle CorporationCopyright © 1998 by Sun Microsystems, Inc.

The submitting companies listed above have all contributed to this “merged” submission. These companies recognize that this draft joint submission is the joint intellectual property of all the submitters, and may be used by any of them in the future, regardless of whether they ultimately participate in a final joint submission.

The companies listed above hereby grant a royalty-free license to the Object Management Group, Inc. (OMG) for worldwide 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 submitted to the OMG for evaluation. Submission of this document does not represent a commitment to implement any portion of this specification in the products of the submitters. WHILE THE INFORMATION IN THIS PUBLICATION IS BELIEVED TO BE ACCURATE,THE COMPANIES 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 listed above shall not be liable for errors contained herein or for incidental or consequential 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. Except as otherwise provided herein, no part of this work 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 the permission of one of the copyright owners. All copies of this document must include the copyright and other information contained on this page.The copyright owners grant member companies of the OMG permission to make a limited number of copies of this document (up to fifty copies) for their internal use as part of the OMG evaluation process.RESTRICTED RIGHTS 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.

IBM is a trademark of International Business Machines CorporationSun, Sun Microsystems, Java, JavaBeans, and JavaSoft are trademarks or registered trademarks of Sun Microsystems, Inc.CORBA, OMG, and Object Request Broker are trademarks of Object Management Group.

Page 3: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

Contents

1 Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

1.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71.2 Changes relative to orbos/98-02-01 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71.3 Changes relative to orbos/98-03-08 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81.4 Changes relative to orbos/98-03-16 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91.5 Changes relative to orbos/98-04-03 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91.6 Submission contact points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111.7 Guide to the submission . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121.8 Proof of concept . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

2 Response to RFP Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

2.1 Types that can be mapped into OMG IDL . . . . . . . . . . . . . . . . . . . . . . . . . . 132.2 Policies for converting classes, interfaces, and fields . . . . . . . . . . . . . . . . . 132.3 Mapping to IDL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132.4 Round-trip mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

3 Rationale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

3.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153.2 Specific goals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153.3 Reverse Mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163.4 Objects by Value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163.5 Supported Subset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163.6 Runtime limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183.7 Overview of Serialization. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193.8 Mappings for Java types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

Page 4: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 4 8/7/98

3.9 Restrictions on IDL identifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223.10 Overloaded methods. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223.11 Collisions on mangled names. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223.12 Portability APIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

4 The RMI/IDL subset of Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

4.1 Overview of conforming RMI/IDL types . . . . . . . . . . . . . . . . . . . . . . . . . . 274.2 Primitive types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274.3 RMI/IDL Remote Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274.4 RMI/IDL Value Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294.5 RMI/IDL Arrays. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304.6 RMI/IDL Exception Types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

5 The IDL mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

5.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315.2 Mapping Java names to IDL names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325.3 Mappings for primitive types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345.4 Mapping for RMI/IDL Remote Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . 355.5 Mapping for RMI/IDL value types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375.6 Mapping for RMI/IDL arrays. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425.7 Mapping RMI/IDL exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445.8 Mapping for non-conforming classes and interfaces . . . . . . . . . . . . . . . . . . 465.9 Mapping implementation classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485.10 Mapping abstract interfaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

6 Run-Time Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

6.1 Subclasses of value objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 516.2 Locating stubs for remote references . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 516.3 Narrowing. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 526.4 Allocating ties for remote values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 526.5 Wide character support. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 526.6 Locating stubs and ties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

7 Java ORB Portability Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . 55

7.1 Additions to existing portability APIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 557.2 New portability APIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 577.3 Generated classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 647.4 Additions to existing JDK APIs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

Page 5: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 5 8/7/98

8 Conformance & CORBA Changes . . . . . . . . . . . . . . . . . . . . . . . . . 69

8.1 Conformance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 698.2 Changes to Adopted Specifications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69

A IDL file structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

Page 6: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 6 8/7/98

Page 7: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

Preface 1

1.1 Introduction

The recently adopted IDL Java Language Mapping specification describes how IDL interfaces appear in Java. It is quite clear that tools such as Visigenic's Caffeine product can use that specification to generate IIOP stubs/skeletons and IDL directly from Java code which conforms to the rules of that mapping. There are very few degrees of freedom for such a tool.

The intent of this submission is to look at a much more interesting and currently unspecified area, that of defining a reverse mapping for Java code which uses the Java RMI style of remote invocation. In effect, this provides an interworking specification for mapping from Java RMI to IIOP. For a variety of reasons outlined in the rationale, we feel that it benefits the OMG to adopt such an open specification for this kind of a reverse mapping.

1.2 Changes relative to orbos/98-02-01

This document includes some errata relative to orbos/98-02-01:

• Removed Section 1.5 “Additional Refinements”. This referred to possible changes in the Portability APIs and was a leftover from an earlier draft.

• Added Rationale Section 3.5.5 “Restrictions on case sensitive naming” to reflect updates to Section 5.2.7 (see below).

• Removed Rationale Section 3.8.3 “Constructors and methods on value types”. This section is redundant with the changes to Sections 5.5.3 and 5.5.4 (see below).

• In Section 5.2.7 added the restriction that package names and interface/class names cannot differ in only case.

• In Sections 5.5 and 5.8 clarified that for Java types generated by the IDL to Java mapping, the original IDL definitions are used.

Page 8: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 8 8/7/98

1

• In Sections 5.5.3 and 5.5.4, by popular demand, specified a standard mapping to be used if RMI/IDL value type methods and constructors are mapped to IDL.

• In Section 5.5.6 specified that for custom value types, Java public data fields should be mapped to IDL.

• In Section 5.5.7 added a mangling rule for use when generating repository IDs from Java class names that include characters outside of ISO latin 1.

• In Section 5.6 revised the module structure used for sequence types, based on reviewer feedback.

• In Section 5.9 clarified that the composite server object should honour “is_a” on any of the composed interfaces.

• In Section 6.6 added an additonal note on the role of Java class loaders.

• In Section 7.1.3, stated that the org.omg.CORBA.portable.ObjectImpl._delegate field will be marked as transient.

• In Section 7.2.1 renamed UserException to be ApplicationException to avoid confusion with the existing org.omg.CORBA.UserException class.

• In Section 7.2.1 removed unnecessary convenience constructor from ApplicationException.

• In Section 7.2.2 renamed ReplyHandler to ResponseHandler to avoid class name conflict with another draft OMG spec.

• Merged Sections 7.2.4 and 7.2.5, merged the Tie and Servant classes and replaced the use of org.omg.CORBA.PortableServer.Servant with the use of org.omg.CORBA.portable.ObjectImpl.

• Added Section 7.2.5 defining the common Stub base class. This is to allow RMI/IIOP stubs to be conveniently serializable.

• In Section 7.2.7 removed incorrect phrase “or a tie object” from the definitions of Util.write_RemoteObject and Util.write_AbstractObject

• In Section 7.3.2 removed bogus “throws UserException” from _invoke method in example. This was debris from an earlier draft.

• In Section 7.4.1 for ease of programming, changed PortableRemoteObject.narrow to take a java.lang.Object rather than a java.rmi.RemoteObject.

• In Section 7.4.4 removed the “extends java.rmi.server.RemoteServer” from the definition of javax.rmi.PortableRemoteObject. This turned out to be unnecessray, and introduced undesirable inherited methods.

• In Section 8.2.1 clarified that the new Unicode escapes are only valid for wchar and wstring literals.

1.3 Changes relative to orbos/98-03-08• Fixed typo in example IDL code in Section 5.4.6: replaced “MammalOverload”

with “MammalOverloadEx” .

Page 9: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 9 8/7/98

1

• Fixed typos in example Java code in Sections 5.5.8 and 5.5.9: removed spurious commas after “extends Warthog” and “extends Wallaby”.

• In Section 5.6.2 added missing #pragma to example generated IDL code. Also removed a spurious extra “:”.

• Changed Sections 7.2.1 and 7.3.1 to reflect clarification to semantics of getId method.

• Changed Sections 7.2.2 and 7.3.2 to not pass the repository ID on the createExceptionReply method.

• Added two new sections 7.2.3 and 7.2.4 to separate the stream-based invocation mechanism from RMI ties.

• Updated Section 8.2.2 to clarify how the GIOP serialization specified in this RFP interacts with the marshalling mechanisms defined by the IDL to Java mapping.

1.4 Changes relative to orbos/98-03-16• In Section 7.1.1, added orb method to return the ORB that created the

OutputStream.

• Removed the org.omg.CORBA.portable.ServerImpl class (section 7.2.4).

• In Section 7.2.3, clarified how the _invoke method is used to dispatch requests.

• In Section 7.2.4, changed the javax.rmi.CORBA.Tie class to an interface. Added four methods to this interface and moved three methods previously on the javax.rmi.CORBA.Tie class to the javax.rmi.CORBA.Util class.

• Updated Section 7.3.2 to reflect change of javax.rmi.CORBA.Tie from class to interface.

• In the description of unexportObject in Section 7.4.1, updated reference to Tie.unexportObject to Util.unexportObject .

1.5 Changes relative to orbos/98-04-03• Issue 1577: methods on Delegate should not have leading underscores.

• Issue 1578: removed public modifier from methods in ResponseHandler Interface

• Issue 1589: added orb method to InputStream .

• Issue 1591: stub classes must have a public no-argument constructor.

• Issue 1592: IDLEntity interface extends java.io.Serializable.

• Issue 1594: removed SerializationInputStream and SerializationOutputStream classes and replaced them by ValueHandler interface and createValueHandler method. Also removed get_offset from OutputStream and removed get_offset, start_block and end_block from InputStream.

• Issue 1595: fixed examples in sections 5.2.4 and 5.5.7.

• Issue 1596: corrected mapping for multidimensional arrays in section 5.6.

Page 10: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 10 8/7/98

1

• Issue 1597: moved #pragma ID after its associated declaration.

• Issue 1598: Update and clarify sort algorithm for ordering of fields in IDL.

• Issue 1599: changed result type of PortableRemoteObject.narrow method to java.lang.Object.

• Issue 1600: fixed example in section 5.7.4.

• Issue 1602: stub returned by PortableRemoteObject.toStub implements the same remote interfaces as the implementation object.

• Issue 1605: fixed example in section A.2.

• Issue 1606: added new section 5.2.8 to deal with IDL name collisions.

• Issue 1608: clarify semantics of PortableRemoteObject.toStub.

• Issue 1609: exportObject method of PortableRemoteObject should throw RemoteException.

• Issue 1610: toStub and unexportObject methods of PortableRemoteObject should throw java.rmi.NoSuchObjectException.

• Issue 1611: added support for RMI/IDL abstract interfaces.

• Issue 1620: fix text in section 5.4.5 to include String constants.

• Issue 1621: added hashCode, equals, and toString methods to javax.rmi.CORBA.Stub.

• Issue 1641: map Java names that collide with IDL keywords by adding a leading underscore.

• Issue 1662: change read_AbstractObject to read_Abstract.

• Issue 1722: add RemarshalException to _invoke and invoke.

• Removed abstract from methods in Sections 7.1.1 and 7.1.2.

• Typo in Section 7.1.3, first paragraph: should be __delegate.

• Typo in section 7.2.6: description of Util.write_AbstractObject should refer to OutputStream.write_Abstract , not OutputStream.write_AbstractObject .

• In section 8.2.2, changed org.omg.CORBA.IDLEntity to org.omg.CORBA.portable.IDLEntity .

• Changed value keyword to valuetype.

• Updated “H:” repository ID syntax to match OBV spec.

• Added a clarification to section 3.11.

• Non-public Java fields now map to private IDL fields in value types.

• In javax.rmi.CORBA.Util , add { ... } to methods that did not have it.

• In section 5.5, say how Java value classes that were mapped from IDL types are identified.

Page 11: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 11 8/7/98

1

• In section 5.8, change references to org.omg.CORBA.Object to org.omg.CORBA.portable.IDLEntity .

• In section 6.6.1, changed the names of the JTS exceptions to match the latest JTA spec from Sun.

• Added section 3.6.4 stating the differences in exception handling between RMI/IDL and RMI using its native protocol.

1.6 Submission contact points

All questions about this submission should be directed to:

Simon NashIBM UK LtdMail Point 146Hursley ParkWinchesterHants SO21 2JNEnglandPhone: +44 1962 815156Fax: +44 1962 818999Email: [email protected]

Jim GellmanNetscape Communications Corporation501 E. Middlefield RoadMountain View, CA 94043, USAPhone: +1 650 254 1900Email: [email protected]

Umesh Bellur, Ph.D. Oracle Corp. 500 Oracle Parkway M/S 5op9Redwood Shores, CA 94065, USAPhone: + 1 650 506 9920 Fax: +1 650 633 1078 Email: [email protected]

Graham HamiltonSun Microsystems, JavaSoft Division901 San Antonio Road CUP02-201Palo Alto, CA 94303, USAEmail: [email protected]

Jeff MischkinskyInprise Corporation951 Mariner’s Island Blvd. Suite 120San Mateo, CA94404, USATel: +1 650 312 5158Email: [email protected]

Page 12: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 12 8/7/98

1

1.7 Guide to the submission

This proposal is in two main parts.

Section 4 defines a subset of Java (referred to as RMI/IDL) which is both a true subset of Java RMI and which is mappable to OMG IDL.

Section 5 then defines the mapping between that supported subset and IDL.

A design rationale is provided in Section 3.

1.8 Proof of concept

We have prototyped a subset of the proposal (excluding Value Objects) and used it to allow an IDL client to communicate via IIOP with a Java RMI server.

Page 13: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

Response to RFP Requirements 2

2.1 Types that can be mapped into OMG IDL

Proposals shall describe which Java types and declarations can be mapped into OMG IDL. A justification for Java types that are not mapped shall be provided. (e.g. It doesn’t make sense to pass a Java thread outside of a JVM environment.).

Sections 4.2 to 4.6 describe which Java types can be mapped to IDL.

2.2 Policies for converting classes, interfaces, and fields

Proposals shall describe policies determining which classes, interfaces and fields are converted to IDL interfaces and attributes.

Sections 5.4 to 5.7.4 describe how the allowed Java types are mapped to IDL.

2.3 Mapping to IDL

Proposals shall result in a mapping which is compatible with the adopted IDL/Java Language mapping. For example, the original Java implementation which was used to generate IDL (according to the proposed Java/IDL reverse mapping proposal) shall be a valid implementation of that IDL when the IDL/Java language mapping rules are applied to it.

In general the issue of mapping Java to IDL has become part of a larger issue of unifying the different styles of distributed programming in Java, so that the industry can converge on the use of IDL and IIOP. We have therefore tried to address the needs of the existing RMI community in defining the Java to IDL mapping, and therefore to support RMI style Java as the main basis for the Java to IDL mapping.

Page 14: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 14 8/7/98

2

We will attempt to provide compatibility between Java classes created with the IDL to Java mapping and Java classes created with the Java to IDL mapping, so that (for example) an object created with the IDL to Java mapping may be passed over an interface defined with the RMI/IDL mapping.

2.4 Round-trip mapping

Proposals may propose support for symmetric round-trip mapping.

We do not propose a round trip mapping.

Page 15: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

Rationale 3

3.1 Overview

The Java distributed programming community is currently forced to choose between two different mechanisms for distributed programming, Java Remote Method Invocation (RMI) and OMG IDL.

The RMI style of distributed programming has proven extremely popular because it is easy to use and avoids the need for Java programmers to learn a separate interface definition language. However, RMI lacks interoperability with other languages and it is not currently supported over standard protocols.

This proposal attempts to unify the ease-of-programming of Java RMI with support for cross-language operation (through OMG IDL) and support for standard protocols (through IIOP).

In order to encourage convergence between the RMI and CORBA programming communities, we believe that it is important to define a solution that is both fully compatible with current RMI semantics and fully compatible with OMG IDL, IIOP, and the CORBA object model.

We refer to the subset of Java that meets these goals as RMI/IDL.

3.2 Specific goals

In order to meet the needs of both communities, we have attempted to meet the following goals:

• RMI/IDL should be a strict subset of current Java RMI, to avoid creating yet a third distributed programming dialect.

• As large a subset of Java RMI as is practicable should be supported in RMI/IDL.

Page 16: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 16 8/7/98

3

• RMI/IDL must be implementable over standard IIOP and be mappable to standard OMG IDL, so that programs written in other languages using standard IDL tools and ORB infrastructure can use IDL and IIOP to access an RMI/IDL server. However, we assume suitable IDL and IIOP extensions for subclassable Value Objects.

• The generated IDL should be as stylistically “clean” as possible, so that it does not impose any unreasonable burden on IDL users. As far as possible, the generated IDL should look as though it had been written by a well-intentioned human.

3.3 Reverse Mapping

We do not specify a direct mapping for reversing the existing IDL to Java mapping. It is clear that a reverse mapping can easily be derived from the IDL to Java mapping. However there is no real need for this to be specified separately as the IDL to Java mapping constrains the design space sufficiently, that it is mostly a matter for tools vendors to provide development tools supporting direct Java to IDL environments.

3.4 Objects by Value

In order to support as large a subset of Java as possible in the Java to IDL mapping, it appears appropriate to take advantage of new IDL features that are being proposed as part of the Objects by Value proposals.

We have been working closely with the authors of the Objects by Value proposal (OMG TC Document orbos/98-01-18) from BEA Systems Inc., International Business Machines Corporation, Iona Technologies Plc., Netscape Communications Corporation, Novell Inc., and Visigenic Software Inc. We have attempted to ensure that this Java to IDL proposal meshes smoothly with that Objects by Value proposal.

3.5 Supported Subset

We have attempted to include as large a subset of Java RMI as possible in the RMI/IDL subset defined in Section 4.

With five minor additional restrictions (see below) the rules defined in Section 4 for RMI/IDL are the same rules that are defined for Java RMI.

3.5.1 Constant definitions in RMI/IDL

RMI/IDL constant definitions are restricted to compile time constants of primitive types or String. This restriction reflects the kinds of constants that are allowed in IDL.

In practice, this supports the normal uses of constants in Java and in RMI and is not a serious limitation.

Page 17: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 17 8/7/98

3

3.5.2 Name mangling collisions

We define name mangling rules (see Section 5.2) for mapping Java names to IDL names. RMI/IDL types must avoid using names that would conflict with these mangled names (see Section 3.11 below).

The name mangling rules have been chosen so that accidental collisions with normal Java identifiers are very unlikely.

3.5.3 Overloaded methods restrictions

We only generate mangled method names when we detect collisions between two method names. This means we can’t support cases where two Java interfaces independently define methods with the same name and the two interfaces are then both inherited by a third Java interface. The generated IDL for the two interfaces will use non-mangled method names and therefore there will be a method name collision when the two IDL interfaces are inherited to make the third IDL interface.

We therefore impose a restriction on the use of overloaded methods. We forbid the inheritance of an overloaded method name through different base interfaces. So this outlaws the case where an interface A defines a method foo, an interface B defines a different foo, and an interface C tries to inherit from both A and B.

Note that we still allow the case where an interface A defines a method foo and then an interface B inherits A and adds a different foo.

In practice we expect that this will only rarely be a problem for RMI/IDL programmers.

3.5.4 Interfaces and value type must be public

Since IDL is intended as an interoperability standard, all IDL types are implicitly “public”. However RMI allows the use of private and package-private types.

It would be possible to map private and package-private RMI types to “public” IDL types. However this may confuse developers about the intended use and status of these types.

We felt that it was safest to exclude the use of private and package-private types from the RMI/IDL subset and to require that all RMI/IDL types must be public. If this restriction proves to be awkward for developers, it will be easy to relax it in the future.

3.5.5 Restrictions on case sensitive naming

We do not support cases where package names differ only in case. Nor do we support cases where interface and/or class names within a package differ only in case.

Page 18: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 18 8/7/98

3

The most common use of case sensitivity in Java is when a variable or field is given a name that is the lower case version of its type name. So it is not uncommon to see a declaration such as “Fred fred”. We define name mangling rules (see Section 5.2.7) to cope with such cases.

However extending the name mangling rules to cope with package or interface name-sensitive collisions is problematic as the collision may only become visible when a third interface combines elements from the conflicting packages or interfaces or classes.

This restriction is unlikely to be a practical problem for Java developers.

3.6 Runtime limitations

Our proposed mapping implies four runtime limitations relative to current Java RMI.

3.6.1 Shared reference objects

In Java remote object references are represented as Java objects. This means that there can be several Java pointers to one object reference. This pointer sharing may be lost when transmitting graphs of Java objects across RMI/IDL.

In practice this is likely to have only very minor impact on Java programmers.

3.6.2 Distributed Garbage Collection

Java provides automatic garbage collection and RMI using its native protocol extends this to the net with distributed garbage collection.

CORBA does not currently provide support for distributed garbage collection. Therefore we do not propose to support distributed garbage collection as part of RMI/IDL. It is instead each server’s responsibility to maintain references to any server objects it wishes to keep active, and to free these references when it wishes the server object to be garbage collected.

However we believe that Distributed Garbage Collection would be a valuable addition to CORBA and would like to see it added in the future. We believe that both Java clients and clients in other languages would benefit from distributed gc.

3.6.3 Narrowing

Java provides type-checked casts as part of the language. RMI using its native protocol dynamically downloads stubs that accurately reflect the RMI interface types of each remote object reference, thereby allowing Java language casts to be used to narrow remote object references.

Page 19: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 19 8/7/98

3

Downloadable stubs are not currently part of the CORBA object model. Since we cannot rely on downloadable stubs, we cannot rely on simple Java casts to implement narrowing of object references. We have therefore defined an explicit narrow method (see Section 6.3) that programmers must use when narrowing portable RMI object references.

3.6.4 Exceptions

The way that some exceptions arising in an RMI/IDL server implementation are passed back to a client is different from RMI using its native protocol.

In RMI/IDL, Java errors and runtime exceptions thrown by a server implementation are caught by the ORB and passed back to the client as CORBA standard exceptions. The standard exception used is not specified, but it is common practice for ORBs to use the UNKNOWN exception. This will be mapped to java.rmi.RemoteException by an RMI/IDL client. A Java RemoteException thrown by a server implementation is passed back to the client as a CORBA UNKNOWN standard exception which is mapped to java.rmi.RemoteException by an RMI/IDL client.

RMI using its native protocol passes Java errors arising in a server implementation back to the client as java.rmi.ServerError , and it passes RemoteExceptions thrown by a server implementation back as java.rmi.ServerException. For runtime exceptions thrown by a server implementation, the behavior depends on whether Java 1.1 or 1.2 is being used. In Java 1.1, these are passed back as java.rmi.ServerRuntimeException. In Java 1.2, these are passed back unchanged as runtime exceptions.

3.7 Overview of Serialization

Java serialization is used as the standard way of supporting “value objects” with Java RMI. In order to be serializable a class must implement the java.io.Serializable interface.

Java serialization allows three different levels of control over the way that an object is serialized.

1. A class can rely on automatic serialization. In this case the class need provide no methods. The Java runtimes take care of automatically serializing all the non-transient fields of the class as needed. The fields are written sorted by the field names.

2. A class can override the default serialization mechanism for its own fields by supplying an explicit writeObject method. The serialization machinery will check each class in the class inheritance chain separately and will either use its writeObject method (if one is supplied) or do automatic serialization of that class’s fields. So if a class provides a writeObject method, that writeObject method is only responsible for saving the state of the immediate class, not of its base classes.

3. A class can take complete control of serializing the entire state of the object (including the state of any bases classes) by implementing the java.io.Externalizable interface and supporting the writeExternal and readExternal methods.

Page 20: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 20 8/7/98

3

Fortunately most Java programmers can ignore these different levels of control and simply use the automatic serialization provided by case (1). However case (2) is used for a number of the JDK core classes and must therefore be supported. Similarly, while case (3) is less common it is important to some customers.

The JDK team have attempted to make as many as possible of the core Java classes serializable. This means that they can also be used as value objects with RMI/IDL. This includes classes such as java.util.Hashtable, java.util.Vector, java.util.Date, java.lang.Number, and many more.

3.8 Mappings for Java types

3.8.1 Handling non-conformant types in RMI/IDL

In Java RMI, remote interface methods can be declared with arbitrary argument and result types. However at runtime the actual arguments and results must be passable between machines.

For example, an RMI method can have an argument “Foo x”, even though Foo is neither a remote interface nor is it serializable. Then at runtime when the method is called, the runtimes check that the actual argument object (which must be a subtype of Foo) is a conforming RMI/IDL type (i.e. is a serializable value type or a remote object reference).

We wish to be compatible with this behavior in RMI. We also want to map each non-conformant Java type to a distinct IDL type so that IDL programmers can distinguish between different non-conformant types.

Therefore, if when we are generating IDL for an RMI/IDL remote interface or an RMI/IDL value type we encounter a non-conformant Java type we generate an IDL type for it. Depending on what exceptions are thrown by the methods of the Java type, the generated IDL type may be either an abstract interface type or a “place-holder” value type. An abstract interface type is a type that at runtime can hold either an IDL value type or an IDL interface type. A place-holder value type can be inherited into other IDL value types, and it can be used as a type specifier for IDL method arguments and results. For place-holder types, we use stateful value types for classes and abstract value types for interfaces, as these provide the same inheritance rules in IDL that are present for classes and interfaces in Java.

Note that in practice most RMI interfaces specify types that are either RMI remote interfaces or RMI value types. The use of non-conformant RMI types in RMI interfaces is relatively rare.

3.8.2 Data member ordering

Java serialization serializes data fields in lexicographic order (primitives first, then non-primitives). IDL marshals data members in declaration order.

Page 21: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 21 8/7/98

3

Therefore, when mapping RMI/IDL value types to IDL, we map the data members in lexicographic order, with all primitives preceding all non-primitives. This means that the same serialization order will be used for both the RMI/IDL value type and the (mapped) IDL value type.

This simplifies the conversion of serialized data to IIOP data. It also ensures that any custom marshalling code is called in the same order in RMI and in C++ and in other language clients.

3.8.3 java.lang.Object

java.lang.Object is used by Java programmers in a very similar way to the way that any is used by IDL programmers. It is used, for example, in building generic data structures such as hash tables or vectors, that need to be able to accommodate arbitrary data types. A single hash-table might include both RMI/IDL value objects and RMI/IDL remote interface references.

It therefore seems natural to map explicit uses of java.lang.Object to any.

However, as noted in the subsetting rules, this doesn’t mean that completely arbitrary Java objects can be passed across RMI/IDL interfaces. At run-time, the Java object that is passed must be one of the other RMI/IDL types, so that it can be marshalled as an IDL any value.

3.8.4 java.lang.String

Java supports a pointer model for Strings. This allows the use of null pointers for Strings and also allows several pointers to one String. We wish to preserve both the null pointers and the pointer sharing when transmitting a graph of Java objects across IIOP.

If we simply mapped java.lang.String to wstring , we would lose both nulls and pointer sharing. We therefore map java.lang.String to a new CORBA type CORBA::WStringValue (defined in the Objects-By-Value proposal) that is a standard value object type that boxes up a wstring .

This provides full compatibility with Java semantics.

3.8.5 Java arrays

Java supports a pointer model for arrays. This allows the use of null pointers for arrays and also allows several pointers to one array. We wish to preserve both the null pointers and the pointer sharing for arrays when transmitting a graph of Java objects across IIOP.

If we simply mapped a Java array to an IDL sequence we would lose both nulls and pointer sharing. We therefore map each Java array to a CORBA value type that boxes up an IDL sequence.

This provides full compatibility with Java semantics.

Page 22: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 22 8/7/98

3

3.9 Restrictions on IDL identifiers

Currently IDL identifiers are restricted to the ISO-Latin character set and can’t include general unicode characters. In addition, IDL identifiers are required to avoid conflicting in case-insensitive comparisons.

Both of these limitations complicate the Java to IDL mapping. We have provided name manglings to work around them (see Section 5.2.4 and 5.2.7), but we recommend that OMG consider extending the definitions of IDL identifiers so that a wider range of unicode characters can be supported and so that case is significant in distinguishing identifiers.

3.10 Overloaded methods

Java (like C++) supports overloaded methods. The lack of support for overloaded methods in IDL has complicated the Java to IDL mapping. We define a name mangling scheme for mapping Java overloaded method names to IDL (see Section 5.2.6).

Because overloaded methods are a popular feature in object-oriented programming languages we recommend that OMG considers extending IDL to allow overloaded methods.

3.11 Collisions on mangled names

It is possible that the name mangling rules we define in Section 5.2 may result in name collisions. For example if a Java remote interface has methods foo(), foo(int x), and foo__long(), these will get mapped to the IDL names foo__ , foo__long , and foo__long , which is not legal IDL.

We believe that in practice the mangling rules we have chosen will create names that would not have been used by normal Java programmers, and that the risk of namespace collisions caused by the mangled names is acceptably low.

3.12 Portability APIs

3.12.1 Relationship to IDL/Java portability APIs

The RMI/IDL stubs and ties are based on similar technology to the portable stubs and skeletons APIs defined as part of the IDL to Java mapping. For example, each client-side stub is based around a Delegate object that is provided by the ORB, and both stubs and ties use extended versions of the existing portable input streams and output stream classes defined as part of IDL/Java.

We initially attempted to exactly follow the IDL/Java stub model, including using the same portable ObjectImpl base class and using the same DII/DSI based invocation model.

Page 23: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 23 8/7/98

3

Unfortunately this effort encountered a number of problems due to a mismatch of expectations between the existing IDL/Java stub structure and what was needed for RMI/IDL. Particularly significant problems included:

• The existing “any” based mechanism assumed that individual arguments could be written to separate temporary streams and then reassembled into the final output stream. Unfortunately this breaks object sharing between arguments, which is a required part of RMI semantics.

• The existing mechanisms tended to be based on the declared types of arguments. For RMI/IDL it is generally necessary to marshal and unmarshal values based on their true run-time types.

• The existing mechanisms tended to assume the creation of at least one stub class for each IDL type. We wanted to allow RMI/IDL programs to be able to freely access the Java value types and exceptions that are defined in the standard JDK, without having to generate separate stub files for all of these types. We therefore wanted a stub mechanism that would not require individual stub classes for value types and exceptions.

We attempted to make extensions to the existing APIs, including a variety of extensions to the existing Any class, to allow the RMI stubs to fit into the existing structure. Unfortunately it appeared that this effort was adding significant complexity (including some rather hard to explain features) to the existing APIs and was also making the RMI/IDL stubs considerably more complex than necessary.

We are instead proposing a small set of new portability APIs that are designed to support RMI/IDL stubs and ties. Where appropriate these APIs build upon or reuse existing APIs in the org.omg.CORBA package, but they are also able to omit many features that were required for the IDL to Java mapping. For example, the absence of INOUT or OUT parameters in RMI/IDL means that Holder classes are unnecessary. The use of dynamic typing means that there is no need for Helper classes. Etc.

We believe the proposed set of portability APIs will be easy to implement on top of existing Java ORBs, will support interoperability of stubs and ORBs, and will support the generation of compact and efficient stubs.

3.12.2 Interaction with Serialization

There are tricky implementation issues around how the RMI/IDL stream classes interact with the JDK 1.1 java.io.ObjectInputStream and java.io.ObjectOutputStream classes which are a defined part of the Java serialization API. For example, those classes currently have several key methods defined as “final” and there are non-trivial security issues in making them subclassable.

Our goal is to define consistent APIs for use by portable stubs and skeletons that buffer both ORB implementors and stub/skeleton code from these implementation issues. Thus we have defined one new interface, ValueHandler, that will be implemented by Sun to handle the interactions with the serialization machinery.

Page 24: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 24 8/7/98

3

The class that implements this interface will process any RMI/IDL value objects using the serialization machinery, and will read or write their data using the standard CORBA portable InputStream and OutputStream APIs. This allows ORB vendors to continue to use their own classes to manage the GIOP and CDR data, but to use the Sun-provided code to handle the translation of serializable value objects.

3.12.3 The pieces

The diagram above shows an RMI/IDL client (on the left) talking to an RMI/IDL server (on the right).

On the client side, the client application is talking to a set of portable stubs. These may have been generated by any third party tools. These use the standard portable ORB APIs to invoke the local ORB. This may have been supplied by any ORB vendor. When marshalling the arguments, the ORB makes a ValueHandler.write_Value call to process outgoing data, and the ValueHandler object calls through to the ORB provided subclass of OutputStream to actually send the data down the GIOP connection.

Similarly on the server side, the ORB calls into the portable tie (which also includes the skeleton code). This calls an ORB created ValueHandler object to read the arguments using ValueHandler.read_Value. The ValueHandler object calls into the ORB provided subclass of InputStream to read the data from the GIOP connection.

Portable stub

ValueHandlerORB

OutputStream

client application

Portable tie

ValueHandler ORB

InputStream

server object

Page 25: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 25 8/7/98

3

A similar path is followed for returning the results, with the server ORB using ValueHandler.write_Value to help marshal the results, and the client ORB using ValueHandler.read_Value to unmarshal those results.

Page 26: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 26 8/7/98

3

Page 27: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

The RMI/IDL subset of Java 4

This section describes the subset of Java RMI that is mapped to IDL and which can run over GIOP. We refer to this subset as RMI/IDL.

4.1 Overview of conforming RMI/IDL types

A conforming RMI/IDL type is a Java type whose values may be transmitted across an RMI/IDL remote interface at run-time.

A Java data type is a conforming RMI/IDL type if it:

• is one of the Java primitive types (see Section 4.2)

• is a conforming remote interface (as defined in Section 4.3)

• is a conforming value type (as defined in Section 4.4)

• is an array of conforming RMI/IDL types (see Section 4.5)

• is a conforming exception type (see Section 4.6)

4.2 Primitive types

All the standard Java primitive types are supported as part of RMI/IDL. These are:

• void, boolean, byte, char, short, int , long, float, double

4.3 RMI/IDL Remote Interfaces

An RMI remote interface defines a Java interface that can be invoked remotely.

A Java interface is a conforming RMI/IDL remote interface if:

1. The interface inherits from java.rmi.Remote either directly or indirectly.

2. The interface and any interfaces that it extends (either directly or indirectly) are public.

Page 28: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 28 8/7/98

4

3. All methods in the interface are defined to throw java.rmi.RemoteException. Throughout this section, references to methods in the interface include methods in any inherited interfaces.

4. Method arguments and result types may be of any types. However at run-time, the actual values passed as arguments or returned as results must be conforming RMI/IDL types (see Section 4.1). In addition, for each RMI/IDL remote interface reference, the actual value passed or returned must be either a stub object or a remote interface implementation object (see Section 4.3.1).

5. All specified method exceptions other than java.rmi.RemoteException are conforming RMI/IDL exception types (see Section 4.6)

6. Method names may be overloaded. However, when an interface directly inherits from several base interfaces, it is forbidden for there to be method name conflicts between the inherited interfaces. This outlaws the case where an interface A defines a method “foo”, an interface B also defines a method “foo”, and an interface C tries to inherit from both A and B.

7. Constant definitions in the form of interface variables are permitted. The constant value must be a compile-time constant of one of the RMI/IDL primitive types or String.

The following is an example of a conforming RMI/IDL interface definition:

public interface Wombat extends java.rmi.Remote {String BLEAT_CONSTANT = “bleat”;boolean bleat(Wombat other) throws java.rmi.RemoteException;

}

While the following is an example of a non-conforming RMI/IDL interface:

// Not public and also fails to implement Remote!!interface IllegalInterface {

// illegalExceptions fails to throw RemoteException.void illegalExceptions();

}

4.3.1 Stubs and remote implementation classes

At run time, when a reference to an RMI/IDL remote interface is passed across a remote interface, then the class of the actual object that is passed must be either a stub class or a remote implementation class.

A stub class is a class that has been created (normally by tools) to manage a remote object reference.

A remote implementation class is a class that acts as the server side implementation for a given RMI/IDL remote interface.

A given remote implementation class may implement several distinct RMI/IDL interfaces.

Page 29: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 29 8/7/98

4

4.4 RMI/IDL Value Types

An RMI/IDL value type represents a class whose values can be moved between systems. So rather than transmitting a reference between systems, the actual state of the object is transmitted between systems. This requires that the receiving system have an analogous class that can be used to hold the received value.

Value types may be passed as arguments or results of remote methods, or as fields within other objects that are passed remotely.

A Java class is a conforming RMI/IDL value type if:

1. The class must implement the java.io.Serializable interface, either directly or indirectly, and must be serializable at run-time. It may serialize references to other RMI/IDL types, including value types and remote interfaces.

2. The class may implement java.io.Externalizable. (This indicates it overrides some of the standard serialization machinery.)

3. The class and all its superclasses are public.

4. If the class is an inner class, then its containing class must also be a conforming RMI/IDL value type.

5. A value type must not either directly or indirectly implement the java.rmi.Remote interface. (If this were allowed then there would be potential confusion between value types and remote interface references.)

6. A value type may implement any public interface except for java.rmi.Remote.

7. There are no restrictions on the method signatures for a value type.

8. There are no restrictions on static fields for a value type.

9. There are no restrictions on transient fields for a value type.

Here is an example of a conforming RMI/IDL value type:

public class Point implements java.io.Serializable {public final static int CONSTANT_FOO = 3+3;private int x;private int y;public Point(int x, y) { ... }public int getX() { ... }public int getY() { ... }

}

4.4.1 The Java String type

The java.lang.String class is a conforming RMI/IDL value type following these rules.

Note, however, that String is handled specially when mapping Java to IDL (see Section 5.5.10).

Page 30: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 30 8/7/98

4

4.5 RMI/IDL Arrays

Arrays of any conforming RMI/IDL type are also conforming RMI/IDL types.

So int[] and String[][][] are conforming RMI/IDL types. Similarly if Wombat is a

conforming RMI/IDL interface type then Wombat[] is a conforming RMI/IDL type.

4.6 RMI/IDL Exception Types

An RMI/IDL exception type inherits from java.lang.Exception.

Since java.lang.Exception extends java.lang.Throwable which implements java.io.Serializable, it is unnecessary for an RMI/IDL exception class to directly implement java.io.Serializable.

A type is a conforming RMI/IDL exception if

1. The class directly or indirectly extends java.lang.Exception

2. The class meets the requirements for RMI/IDL value types defined in Section 4.4.

Here’s an example of a conforming RMI/IDL exception type:

public class MammalOverload extends MammalException {public MammalOverload(String message) {

super(message);}

}

Page 31: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

The IDL mapping 5

5.1 Overview

This section defines the mapping between RMI/IDL data types and IDL.

We describe:

• General rules for mapping Java names to IDL (Section 5.2).

• Mappings for primitive types (Section 5.3).

• Mappings for RMI/IDL remote interfaces (Section 5.4).

• Mappings for RMI/IDL value types (Section 5.5).

• Mappings for RMI/IDL arrays (Section 5.6).

• Mappings for RMI/IDL exceptions (Section 5.7).

• Mappings for Java types that are referenced in RMI/IDL remote interfaces or inherited by RMI/IDL value types, but which are not themselves conforming RMI/IDL types. (Section 5.8).

5.1.1 Summary of special case mappings

Some standard Java class and interface types benefit from special case mappings to specific CORBA types. These are described in the appropriate sections below, but for convenience the following table summarizes these mappings:

Java IDL

java.lang.Object any see Section 5.8.2

java.lang.String CORBA::WStringValue see Section 5.5.10

java.io.Serializable any see Section 5.8.1

Page 32: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 32 8/7/98

5

5.2 Mapping Java names to IDL names

In general, each Java name is mapped to an equivalent IDL name. However there are some exceptions when the Java name is not a legal identifier in IDL.

5.2.1 Mapping packages to modules

We map Java package names to IDL modules. Each Java package becomes a separate IDL module. Packages within packages are represented as modules within modules.

So a Java package a.b.c would turn into an IDL module ::a::b::c

5.2.2 Java names that clash with IDL keywords

For Java names that collide with IDL keywords, the Java names are mapped to IDL by adding a leading underscore. So the Java name oneway is mapped to the IDL name _oneway .

5.2.3 Java names with leading underscores

For Java names that have leading underscores, the leading underscore is replaced with “J_”. So _fred is mapped to J_fred .

5.2.4 Java names with illegal IDL identifier characters

Given the current lack of support for unicode in IDL (see Section 3.9) we define a simple name mangling scheme to support the mapping of Java identifiers to IDL identifiers.

For Java identifiers that contain illegal IDL identifier characters such as ‘$’ or unicode characters outside of ISO Latin 1, any such illegal characters are replaced by “U” followed by the 4 hexadecimal characters (in upper case) representing the Unicode value. So, the Java name a$b is mapped to aU0024b and x\u03bCy is mapped to xU03BCy .

5.2.5 Names for inner classes

When mapping names for Java inner classes, a composite name is formed by concatenating the name for the outer class, two underscores, and the name of the inner class. The corrections for illegal IDL identifiers described above are then applied.

java.io.Externalizable any see Section 5.8.1

java.rmi.Remote CORBA::Object see Section 5.4.1

Java IDL

Page 33: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 33 8/7/98

5

So for example, an inner class Fred inside a class Bert will get mapped to an IDL name of Bert__Fred .

5.2.6 Overloaded method names

If a Java RMI/IDL method isn’t overloaded, then the same method name is used in IDL as was used in Java.

Given the absence of overloaded methods in current IDL (see Section 3.10) we define a simple name mangling for overloaded methods.

Note that a method may be uniquely defined in a base interface (and therefore its name will not be mangled in that interface) and then be overloaded in a derived interface (in which case the name will be mangled in the derived interface).

For overloaded RMI/IDL methods, the mangled IDL name is formed by taking the Java method name and then appending two underscores, followed by each of the fully qualified IDL types of the arguments (removing any leading “::” and replacing embedded “::” with “_”) separated by two underscores.

For example, the three overloaded Java methods:

void hello();void hello(int x, a.b.c y, int z);void hello(int z[]);

are mapped to the IDL methods:

void hello__();void hello__long__a_b_c__long(in long x, in ::a::b::c y, in long z);void hello__org_omg_sequences_seq_long(

in ::org::omg::sequences::seq_long x);

5.2.7 Names differing only in case

While Java supports case-sensitive names, IDL does not. We therefore provide a general name mangling rule to allow unique IDL identifiers to be generated for Java names that differ only in case.

To simpify the mapping, we do not support the use of Java package names differing only in case. Nor do we support the use of class or interface names within the same package that differ only in case. Both of these are treated as errors.

For other case-sensitive collisions, the rule is that if two (or more) names that need to be defined in the same IDL name scope differ only in case, then a mangled name is generated consisting of the original name followed by an underscore, followed by an underscore separated list of decimal indices into the string, where the indices identify all the upper case characters in the original string. Indices are zero based.

Thus if a Java remote interface has methods jack, Jack and jAcK these names are mapped to jack_ , Jack_0 , and jAcK_1_3 .

Page 34: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 34 8/7/98

5

5.2.8 Names that would cause IDL name collisions

In some cases, applying these rules for name mappings would generate IDL with name collisions. This is because Java constants and fields can have the same names as methods, but IDL constants and fields cannot. The following rules are used to avoid such name collisions in IDL:

• Method names are mapped unchanged (subject to other mangling rules).

• Java constant or field names whose mapped name collides with the mapped name of a Java method (or would collide if the Java method were mapped to IDL) are mapped with an additional trailing underscore.

For example, if a Java class has both a constant foo and a method foo, the IDL method is called foo (if it is mapped) and the IDL constant is called foo_ .

5.3 Mappings for primitive types

Here are the IDL mappings for the Java primitive types:

The mappings for the Java void, boolean, short, int , long, float , and double types are straightforward as they have exact IDL analogues.

The 8 bit signed Java type byte is mapped to the 8 bit unsigned IDL type octet . The mapping is bit-for-bit so that Java byte value “-1” is transmitted as GIOP octet “0xFF”, and the GIOP octet “0xFF” is mapped back to the Java byte value “-1”. Thus when using this mapping, we will preserve full value and sign information when using RMI/IDL between a Java client and a Java server over GIOP.

The 16 bit Java Unicode char type is mapped to the IDL wchar type.

Java IDL

void void

boolean boolean

char wchar

byte octet

short short

int long

long long long

float float

double double

Page 35: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 35 8/7/98

5

5.4 Mapping for RMI/IDL Remote Interfaces

An RMI/IDL Remote Interface is mapped into an IDL interface with the corresponding name (see Section 5.2) in the IDL module corresponding to the Java interface’s package name (see Section 5.2.1).

5.4.1 Special case for java.rmi.Remote

As a special case, any explicit use of java.rmi.Remote as a parameter, result, or field, is mapped to CORBA::Object .

5.4.2 Inherited interfaces

Each inherited interface (other than java.rmi.Remote) in the Java interface is represented by an equivalent inherited interface in the IDL interface. The inherited IDL interface is a regular interface if the corresponding Java interface extends java.rmi.Remote, and an abstract interface otherwise

5.4.3 Property accessor methods

Methods that follow the JavaBeans design patterns for simple read-write properties or simple read-only properties are mapped to IDL interface attributes.

5.4.3.1 Read-Write properties

If an RMI/IDL remote interface has a pair of methods get<name> and set<name> where:

• the get<name> method has no arguments

• the set<name> method has a single argument and a void return type

• the result type of the get<name> method is the same as the argument type of the set<name> method

• get<name> and set<name> only throw java.rmi.RemoteException.

then this is mapped to an IDL read-write attribute where the attribute has the IDL type corresponding to the set<name> method’s argument type.

5.4.3.2 Read-only properties

If there is a get<name> method that:

• has no arguments

• has a non-void return type

• only throws java.rmi.RemoteException.

Page 36: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 36 8/7/98

5

but if there is no corresponding set<name> method that satisfies the rules defined in Section 5.4.3.1, then the get<name> method is mapped to a read-only IDL attribute whose type is obtained by mapping the method’s return type.

5.4.3.3 Boolean properties

For boolean properties an is<name> method may take the place of the get<name> method.

Thus, for example, a pair of methods

boolean isFoo() throws java.rmi.RemoteException;void setFoo(boolean b) throws java.rmi.RemoteException;

define a read-write attribute foo.

5.4.3.4 Attribute names

The JavaBeans design pattern for property names is that the property name is obtained from the method name(s) by:

• extracting the characters after the initial “get”, “is”, or “set” of the method name

• converting the first character to lower case unless both the first and second characters are upper case.

So the getFoo method implies a “foo” property, the setX method implies an “x” property, and the getURL method implies a “URL” property.

The IDL attribute name is obtained by taking the JavaBeans property name and applying the normal mapping rules (see Section 5.2). However, if this attribute name conflicts with a method name, then an extra pair of underscores “__” is added to the end of the attribute name to attempt to disambiguate it.

5.4.4 Methods

Except for property accessors (see 5.4.3 above), each method in the interface is mapped to an IDL method where:

1. The IDL method name is generated as described in Section 5.2.6.

2. The Java return type is mapped to the corresponding IDL return type.

3. Each Java argument is mapped to an IDL in parameter with the corresponding IDL type.

4. The IDL parameters may be given arbitrary names, but it is recommended that, where possible, the IDL names should be obtained by mapping the Java argument names.

5. Each declared Java exception (other than java.rmi.RemoteException) is mapped to the corresponding IDL exception.

6. java.rmi.RemoteException is assumed to be mapped to the implicit CORBA SystemException , and are therefore not explicitly declared in the IDL.

Page 37: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 37 8/7/98

5

5.4.5 Constants

Compile-time constants (“public final static” fields with compile-time constant values) for primitive types and Strings are mapped to similarly named IDL constants in the target interface with the same values. Individual wstring and wchar character values may need to be escaped as defined in the OMG IDL specification. See also Section 8.2.1 where extensions are made to OMG IDL to support unicode character and string literals.

5.4.6 An example

Here is an example of an RMI/IDL remote interface:

package alpha.bravo;

public interface Wombat extends java.rmi.Remote, omega.Wallaby {String BLEAT_CONSTANT = “bleat”;void chirp(int x) throws RemoteException;void buzz() throws RemoteException, omega.MammalOverload;int getFoo() throws RemoteException;void setFoo(int x) throws RemoteException;String getURL() throws RemoteException;

}

that gets mapped to the following IDL:

module alpha {module bravo {

interface Wombat: ::omega::Wallaby {const wstring BLEAT_CONSTANT = “bleat”;void chirp(in long arg0);void buzz() raises (::omega::MammalOverloadEx);attribute long foo;readonly attribute ::CORBA::WStringValue URL;

};};};

5.5 Mapping for RMI/IDL value types

This section covers the general mapping for RMI/IDL value types, including inner classes. However note that there is a special case mapping for java.lang.String (see Section 5.5.10).

RMI/IDL value classes that implement org.omg.CORBA.portable.IDLEntity directly or indirectly are not mapped to IDL, because these Java classes correspond to existing IDL types that were mapped to Java using the IDL to Java mapping. Instead, the original IDL definitions are used.

Page 38: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 38 8/7/98

5

Each RMI/IDL value class (except for those mapped from IDL using the IDL to Java mapping) is mapped to an IDL value type with the corresponding IDL name (see Section 5.2) in the IDL module corresponding to the Java class’s package name (see Section 5.2.1).

5.5.1 Inherited base class

If the RMI/IDL class extends some base class (other than java.lang.Object) then this inheritance is represented by having the IDL value type inherit from an IDL value type corresponding to the base class.

5.5.2 Inherited interfaces

Each inherited interface (other than java.io.Serializable and java.io.Externalizable) in the Java class is represented by an equivalent inherited type in the IDL type. See Section 5.8 for details.

5.5.3 Methods

It is not required that methods in RMI/IDL value classes be mapped into IDL.

This is partly due to concern that an automatic mapping would have a spaghetti effect, where referencing a single value type would result in mappings for methods that would pull in other RMI/IDL types, that would pull in other value types, etc.

In addition, many of the methods in common Java value types cannot be mapped usefully to IDL (because they reference non RMI/IDL types) or to other languages.

However, there may be cases where it is useful to map value type methods to IDL and tools may chose to support options to map methods. In those cases we require that the following mapping be used:

Each mapped method in a Java value type is mapped to an IDL method where:

1. The IDL method name is generated as described in Section 5.2.6.

2. The Java return type is mapped to the corresponding IDL return type.

3. Each Java argument is mapped to an IDL in parameter with the corresponding IDL type.

4. The IDL parameters may be given arbitrary names, but it is recommended that, where possible, the IDL names should be obtained by mapping the Java argument names.

5. Each declared Java exception is mapped to the corresponding IDL exception.

5.5.4 Constructors

As with methods, it is not required that RMI/IDL value type constructors be mapped to IDL. However, in those cases where constructors are mapped to IDL, we require that the following mapping be used:

Each mapped constructor in a Java value type is mapped to an IDL initializer where:

Page 39: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 39 8/7/98

5

1. Each Java argument is mapped to an IDL in parameter with the corresponding IDL type.

2. The IDL parameters may be given arbitrary names, but it is recommended that, where possible, the IDL names should be obtained by mapping the Java argument names.

3. Each declared Java exception is mapped to the corresponding IDL exception.

5.5.5 Constants

Compile-time constants (“public final static” fields with compile-time constant values) for primitive types and Strings are mapped to similarly named IDL constants in the target value type with the same values. Individual wstring and wchar character values may need to be escaped as defined in the OMG IDL specification. See also Section 8.2.1 where extensions are made to OMG IDL to support unicode character and string literals.

5.5.6 Data

The mapping of the data fields depends on whether the class is either externalizable (i.e. supports the java.io.Externalizable interface) or has a writeObject method. If either of these is true, then the class is overriding the default Java serialization mechanisms and is writing essentially a set of opaque data as its serialized form.

If the class is not externalizable and does not have a writeObject method, then each non-static non-transient field of the Java class is mapped to a corresponding IDL data member with the same name, with the corresponding IDL type. Java public fields will be mapped to IDL public data members. Non-public Java fields will be mapped to IDL private data member access.

The following rules apply to the ordering of fields in an IDL value type mapped from Java.

• All non-constant fields whose Java type is a primitive precede all other non-constant fields.

• The non-constant primitive fields are ordered by sorting their Java field names in increasing order. The sort compares the field name strings lexicographically. The comparison is based on the Unicode value of each character in the strings.

• The non-constant non-primitive fields are ordered by sorting their Java field names in the same way as non-constant primitive fields.

If the class either implements java.io.Externalizable or has a writeObject method, then the entire state of the Java class is treated as an opaque type, and it is defined as an IDL “custom valuetype ”. Java public fields will be mapped to IDL public data members.

5.5.7 Repository ID

To allow reliable detection of version mismatches, a #pragma ID is generated to assign each value type a specific repository ID string with a specific version string.

Page 40: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 40 8/7/98

5

The syntax of the repository ID follows the convention defined in the Objects By Value proposal, with an initial “H:” followed by a version string, followed by a “/” separated pathname corresponding to the Java class name.

For Java identifiers that contain illegal IDL identifier characters such as ‘$’ or unicode characters outside of ISO Latin 1, any such illegal characters are replaced by “\U” followed by the 4 hexadecimal characters (in upper case) representing the Unicode value. The use of a “\” is legal within a repository ID and it allows a reliable demangling from a repository ID back to the Java class name.

To allow us to accurately match RMI semantics in the Java to Java case, we use the Java RMI serialization version UID, transcribed as a 16 digit upper-case hex string, as the version string.

So for example, the Java type java.util.Hashtable would be mapped to the IDL type ::java::util::Hashtable with a repository ID of “H:13BB0F25214AE4B8:java/util/Hashtable” .

Similarly, a Java class a.x\u03bCy might be mapped to the IDL type ::a::xU03BCy with repository ID “H:0123456789ABCDEF:a/x\U03BCy” .

5.5.8 Example without writeObject

The RMI/IDL value type:

package alpha.bravo;public class Hedgehog extends Warthog implements java.io.Serializable {

public final static short MAX_WARTS = 12;private int length;protected boolean foobah;int height;public int size;public Hedgehog(int length) { ... }public int getLength() { ... }

}

gets mapped to the IDL value type:

Page 41: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 41 8/7/98

5

module alpha {module bravo {

valuetype Hedgehog: ::alpha::bravo::Warthog {const short MAX_WARTS = 12;private boolean foobah;private long height;private long length;public long size;

};#pragma ID Hedgehog “H:12345678ABCDEF00:alpha/bravo/Hedgehog”

};};

5.5.9 Example with writeObject

The RMI/IDL value type:

package alpha.bravo;public class Kangaroo extends Wallaby implements java.io.Serializable {

private int length;public Kangaroo(int length) { ... }private void writeObject(java.io.ObjectOutputStream s) { ... }public int getLength() { ... }

}

gets mapped to the IDL value type:

module alpha {module bravo {

custom valuetype Kangaroo: ::alpha::bravo::Wallaby {};

#pragma ID Kangaroo “H:87654321ABCDEF01:alpha/bravo/Kangaroo”};};

5.5.10 Mapping for java.lang.String

When used as a parameter type, return type, or data member, the Java String type is mapped to the type CORBA::WStringValue . However when mapping Java String constant definitions, a Java String is simply mapped to a wstring.

CORBA::WStringValue is a new type defined as part of the Objects-by-Value proposal. It is defined as

Page 42: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 42 8/7/98

5

valuetype WStringValue wstring;

which is semantically equivalent to:valuetype WStringValue {

public wstring data;};

5.6 Mapping for RMI/IDL arrays

An RMI/IDL array is mapped to a “boxed” value type containing an IDL sequence. We use the syntax “valuetype xyz foo ” (defined in the Objects-by-Value proposal) as a shorthand for defining a value type named “xyz ” that contains a single field of type “ foo ”.

The module for each such value type is determined by the IDL type of the array element. For multi-dimensional arrays, this is the type of the innermost array element, after all the dimensions are resolved.

Primitive IDL types such as long , boolean , etc are mapped directly into the ::org::omg::sequences module. For other types a module name is formed by taking the ::org::omg::sequences prefix and then adding the type’s existing module name to identify a sub-module. So the type a::b::c is mapped into the module ::org::omg::sequences::a::b .

The IDL value type name within the module is formed by prefixing the IDL element type name with “seq_ ” for each dimension of the array. Any spaces (such as in the IDL type long long ) are replaced with underscores.

Some example value definitions resulting from Java arrays:

boolean[] => in the module ::org::omg::sequences the definition:

valuetype seq_boolean sequence<boolean>;

long[] => in the module ::org::omg::sequences the definition:

valuetype seq_long_long sequence<long long>;

a.b.C[] => in the module ::org::omg::sequences::a::b the definition:

valuetype seq_C sequence<::a::b::C>;

x.Y[][] => in the module ::org::omg::sequences::x the definition:

valuetype seq_Y sequence<::x::Y>;valuetype seq_seq_Y sequence<seq_Y>;

5.6.1 #ifdefs for sequence definitions

To allow IDL files to include multiple IDL files that include similar generated sequence definitions, we require that each generated sequence definition be wrapped in an #ifndef and #endif pair. The tag of the #ifndef is formed by using the fully

Page 43: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 43 8/7/98

5

scoped name of the sequence value type, replacing the leading ‘:: ’ with two underbars, replacing each inner ‘:: ’ with one underbar, and adding two underbar characters at the end. The #ifndef is followed by a #define of the tag, followed by the sequence definition, followed by an #endif .

So a definition for a sequence of boolean would be wrapped in a preamble of

#ifndef __org_omg_sequences_seq_boolean__ #define __org_omg_sequences_seq_boolean__

and would be followed by an

#endif

5.6.2 Array example

Here’s a more complete example. The Java definition

package alpha.bravo;public class Charlie implements java.io.Serializable {

public omega.Dolphin fins[];}

would result in the following IDL definition:

#ifndef __org_omg_sequences_omega_seq_Dolphin__#define __org_omg_sequences_omega_seq_Dolphin__module org {module omg {module sequences {module omega {

valuetype seq_Dolphin sequence<::omega::Dolphin>;};};};};#endif

module alpha {module bravo {

valuetype Charlie { public ::org::omg::sequences::omega::seq_Dolphin fins;

}; #pragma ID Charlie “H:0123456789ABCDEF:alpha/bravo/Charlie”};

Page 44: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 44 8/7/98

5

5.7 Mapping RMI/IDL exceptions

IDL does not allow subclassing of exception types. By contrast Java programmers tend to make heavy use of exception subclassing, and the Java type system is used to distinguish different flavors of exceptions at run time. It is very common for a Java interface to say it raises a fairly generic exception (such as java.io.IOException) but for implementations to throw more specific sub-types (such as java.io.InterruptedIOException ) and for clients to use the Java instanceof operator to check for specific subtypes. In addition, RMI/IDL exceptions can be passed as normal value types, whereas IDL exceptions can only be used in raises clauses.

This mismatch of exception styles makes the mapping of RMI/IDL exception types to IDL problematic.

To allow full support for subclassing when communicating Java to Java we propose a mapping where an RMI/IDL exception type is mapped to both a specific IDL exception and to an IDL value type that allows subclassing. The IDL exception has a single field, which holds the corresponding value object.

This solution allows RMI/IDL to support the normal idiomatic use of Java exceptions, while still being correctly mappable into IDL.

5.7.1 The IDL value type

The standard Java class java.lang.Exception is treated as a special case. It is mapped to a standard IDL value type ::java::lang::Exception :

module java {module lang {

valuetype Exception {public ::CORBA::WStringValue detailMessage;

};};};

Every other RMI/IDL exception type is mapped to an IDL value interface in the IDL module corresponding to the Java exception’s package name (see Section 5.2.1). The value type’s name is formed by taking the RMI/IDL exception name and applying the normal corrections for illegal IDL names (see Section 5.2).

The IDL value type inherits from an IDL parent value type that corresponds to the base class of the RMI/IDL exception class. So if an RMI/IDL exception type Fred extends Bert, then its IDL value type Fred will inherit Bert .

The mapping of the field, methods, constants, and inherited interfaces to the IDL value type follow the same rules defined for other RMI/IDL value types in Sections 5.5.2 to 5.5.6.

Page 45: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 45 8/7/98

5

5.7.2 The IDL exception

Each RMI/IDL exception type is also mapped to an IDL exception in the IDL module corresponding to the Java exception’s package name (see Section 5.2.1). The IDL exception name is formed from the Java exception name by

• removing any trailing “Exception” or “Error ” suffix

• adding an “Ex” at the end of the name

• applying the normal corrections for illegal IDL names (see Section 5.2)

Thus for example:

java.lang.IllegalAccessException is mapped to ::java::lang::IllegalAccessEx

alpha.bravo.Foo is mapped to ::alpha::bravo::FooEx

This IDL exception name can then be used in the raises clause of IDL method definitions.

The IDL exception type is defined with a single data member named value that has the type of the associated value object.

5.7.3 Mapping references to RMI/IDL exceptions

Whenever an RMI/IDL exception is used in a Java throws clause, it is mapped to a use of the corresponding IDL exception type in the IDL raises clause.

Whenever an RMI/IDL exception is used as a data field or as a method argument, it is mapped to the corresponding IDL value type.

5.7.4 Example

For example the Java RMI/IDL definitions:

package omega;public class FruitbatException extends MammalException {

public FruitbatException(String message, int count) {...

}public int getCount() { ... }private int count;

}

public interface Thrower extends java.rmi.Remote {void doThrowFruitbat() throws FruitbatException, RemoteException;FruitbatException getLastException() throws RemoteException;

}

are mapped to IDL as:

Page 46: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 46 8/7/98

5

module omega {

valuetype FruitbatException: ::omega::MammalException {private long count;

};

#pragma ID FruitbatException“H:12345678ABCDEF11:omega/FruitbatException”

exception FruitbatEx {FruitbatException value;

};

interface Thrower {void doThrowFruitbat() raises (FruitbatEx);readonly attribute FruitbatException lastException;

};};

5.8 Mapping for non-conforming classes and interfaces

In addition to generating IDL for each conforming RMI/IDL type, IDL definitions are also required for each Java class or interface which:

• Is inherited (either directly or indirectly) by another Java type which has been mapped to IDL.

• Is specified as an argument type or as a result type to an RMI/IDL remote interface method.

• Has been mapped to a data member of a IDL value type.

Each such Java class or interface (except for interfaces that extend org.omg.CORBA.portable.IDLEntity directly or indirectly) is mapped to an IDL type with the corresponding name (see Section 5.2) in the IDL module corresponding to the Java type’s package name (see Section 5.2.1).

Java interfaces that extend org.omg.CORBA.portable.IDLEntity directly or indirectly are not mapped to IDL, because these Java interfaces correspond to existing IDL interfaces that were mapped to Java using the IDL to Java mapping.

Non-conforming Java classes are mapped to IDL concrete value types with no data members. Non-conforming Java interfaces are mapped as follows:

• Java interfaces whose method definitions (including inherited method definitions) all throw java.rmi.RemoteException are mapped to IDL abstract interfaces as described in Section 5.10.

• All other Java interfaces are mapped to IDL abstract value types with no data members.

Page 47: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 47 8/7/98

5

5.8.1 java.io.Serializable and java.io.Externalizable

As a special case, any use of java.io.Serializable or java.io.Externalizable as a parameter, result, or field is mapped to any.

5.8.2 Mapping for java.lang.Object

The Java type java.lang.Object is mapped to the IDL any type.

This is used when java.lang.Object is specified as the type of a parameter, result, or field. All Java classes implicitly inherit from java.lang.Object, but this implicit inheritance is not exposed as part of the RMI to IDL mapping.

5.8.3 Inherited interfaces

Each inherited Java class or interface (other than java.io.Serializable and java.io.Externalizable) in the Java type is represented by an equivalent inherited value type or abstract interface type in IDL.

5.8.4 Methods and constants

We do not specify a mapping for the methods and constants in these classes and interfaces.

5.8.5 Examples

The following non-conforming Java types

package alpha.bravo;

public interface Mammal {public int getSize();

}

public class PolarBear {private int length;public int weight;public PolarBear(int length, int weight) { ... }public int getSize() { ... }public int getWeight() { ... }

}

get mapped to the IDL value types:

Page 48: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 48 8/7/98

5

module alpha {module bravo {

abstract valuetype Mammal {};

valuetype PolarBear {};

};};

5.9 Mapping implementation classes

In general we do not need to map RMI implementation classes to IDL.

However, if a given RMI implementation class implements multiple distinct RMI/IDL interfaces types, then it is necessary to generate an IDL type that represents the unification of the distinct RMI/IDL types.

Any such composite RMI/IDL implementation class is mapped into an IDL interface with the corresponding name (see Section 5.2) in the IDL module corresponding to the Java class’s package name (see Section 5.2.1).

Each inherited RMI/IDL remote interface (other than java.rmi.Remote) inherited by the Java implementation class is represented by an equivalent inherited interface in the IDL interface. Inherited classes and inherited interfaces which are not RMI/IDL remote interfaces are ignored.

At run-time, any instances of the composite implementation class must, from a CORBA perspective, implement the corresponding composite IDL interface. This implies, for example, they must return true to any calls of “is_a” on any of the IDL interfaces associated with the distinct RMI/IDL interfaces.

5.9.1 Example

The RMI/IDL implementation class alpha.bravo.AB which implements the RMI/IDL remote interfaces alpha.bravo.A and alpha.bravo.B:

package alpha.bravo;public class AB extends javax.rmi.PortableRemoteObject

implements alpha.bravo.A, alpha.bravo.B {...

}

is mapped to the IDL:

Page 49: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 49 8/7/98

5

module alpha {module bravo {

interface AB: ::alpha::bravo::A, ::alpha::bravo::B {};

};};

5.10 Mapping abstract interfaces

Java interfaces that do not extend java.rmi.Remote directly or indirectly and whose method definitions (including inherited method definitions) all throw java.rmi.RemoteException are mapped to IDL abstract interfaces. Java interfaces that do not extend java.rmi.Remote directly or indirectly and have no methods are also mapped to IDL abstract interfaces.

5.10.1 Inherited interfaces

Each inherited Java interface in the Java type is represented by an equivalent inherited abstract interface in the IDL type.

5.10.2 Methods and constants

Methods and constants are mapped according to the rules specified in Section 5.4.4 and Section 5.4.5.

5.10.3 Examples

The following Java type

package alpha.bravo;

public interface Bear { public int getSize() throws java.rmi.RemoteException;}

gets mapped to the IDL type:

module alpha {module bravo {

abstract interface Bear {long getSize();

};};};

Page 50: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 50 8/7/98

5

Page 51: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

Run-Time Issues 6

In addition to the RMI/IDL mapping there are also run-time issues about how to implement Java RMI/IDL calls over GIOP.

6.1 Subclasses of value objects

It should be possible to send a subclass of an RMI/IDL value type where a base value type was specified in the IDL.

If this occurs, the recipient is responsible for locating a suitable implementation subclass to represent the value object subtype. In cases where a Java virtual machine is available, this might include attempting to load Java bytecodes for the subclass. In the Java to C++ case this might involve attempting to locate a suitable C++ subclass.

The name of the subclass can be obtained by parsing the value object’s repository ID, which must follow the “H:” repository ID convention (see Section 5.5.7).

If a suitable subclass is not available, then the recipient must raise an exception. It is not acceptable for an implementation to attempt to substitute a base class of the subclass value that was transmitted.

6.2 Locating stubs for remote references

When receiving an IOR from another system, it is the responsibility of the receiving system to know which RMI/IDL type is expected. The receiving system should be prepared to use stubs associated with this RMI/IDL type to manage the received object reference. However, the receiving system may also optionally use the Repository ID of the incoming IOR to locate and use stubs that more accurately reflect the true run-time type of the object reference.

Page 52: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 52 8/7/98

6

6.3 Narrowing

In order to narrow an RMI/IDL object reference to a different type, application programmers must use the static narrow method provided by the javax.rmi.PortableRemoteObject class (see Section 7.4.4).

Thus for example they might do:

alpha.bravo.Mammal m = getMammal();try {

b = (alpha.bravo.Bandicoot) javax.rmi.PortableRemoteObject.narrow(m, alpha.bravo.Bandicoot.class);

} catch (ClassCastException ex) {...

}

6.4 Allocating ties for remote values

Following normal RMI semantics, an RMI server-side implementation object may be passed across an RMI remote interface as though it were a remote reference.

The javax.rmi.CORBA.Util.write_RemoteObject method checks whether a transmitted object is an implementation object and if so, allocates or reuses a suitable tie object. The type of the tie object should correspond to the IDL type which the implementation object implements.

This tie class is located at run-time by finding the class of the implementation object and checking for a corresponding tie class (see Section 6.6 below). If no suitable tie class is found, the check is repeated on the implementation class’s base class and so on up the inheritance chain.

6.5 Wide character support

Since Java supports Unicode characters and strings, ORBs supporting RMI/IDL must provide some form of wide character support.

Note that as part of IIOP code set negotiation, ORBs are required to accept Unicode UTF16 for use as a fallback transmission format for wide characters, though they may negotiate to use other formats.

6.6 Locating stubs and ties

At various times it may be necessary for the ORB to locate either a stub class for a given RMI/IDL remote interface or a tie class for a given RMI/IDL implementation class. The name of the stub class is formed by taking the name of the RMI/IDL interface and appending "_Stub". The name of the tie class is formed by taking the name of the RMI/IDL implementation class and appending "_Tie".

Page 53: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 53 8/7/98

6

For example, for an RMI/IDL interface class a.b.Fred, the stub class would be named a.b.Fred_Stub. For an RMI/IDL implementation class x.y.Z the tie class would be named x.y.Z_Tie.

A given Java virtual machine may have several different “class loaders” active simultaneously. Each of these class loaders provides a separate naming context for Java classes. For example, a browser might be running applets from several different hosts. To avoid class name conflicts it will run the applets in different class loaders. Thus, two different applets might both reference a class called “Foo”, but each of them will get its own version of the “Foo” class from its own class loader.

The java.lang.Class.getClassloader method returns the class loader for a given Class. So given one Class it is possible to generate new class names and then attempt to load those additional classes from the original class’s class loader.

It is important in Java APIs to use an appropriate class loader when trying to locate a named class. To ease this problem in the ORB Portability APIs we normally pass around java.lang.Class objects rather than simply class names. When it is necessary to load named classes, runtime code should take care to use an appropriate class loader, e.g. by using one from an existing Class object.

6.6.1 Mapping CORBA SystemExceptions to RMI RemoteExceptions

In general CORBA SystemExceptions are simply mapped to instances of java.rmi.RemoteException. However some CORBA SystemExceptions are mapped to more specific subclasses of RemoteException. These are listed in the table below.

In all cases the RMI exception is created with a detail string that consists of:

• the string “CORBA ”

• followed by the CORBA name of the SystemException

CORBA Exception RMI Exception

COMM_FAILURE java.rmi.MarshalException

INV_OBJREF java.rmi.NoSuchObjectException

NO_PERMISSION java.rmi.AccessException

MARSHAL java.rmi.MarshalException

OBJECT_NOT_EXIST java.rmi.NoSuchObjectException

TRANSACTION_REQUIRED javax.transaction.TransactionRequiredException

TRANSACTION_ROLLEDBACK javax.transaction.TransactionRolledbackException

INVALID_TRANSACTION javax.transaction.InvalidTransactionException

Page 54: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 54 8/7/98

6

• followed by a space

• followed by the decimal value of the SystemException’s minor code

Thus a CORBA UNKNOWN SystemException with a minor code of 0x31 would be mapped to a RemoteException with a detail string of “CORBA UNKNOWN 49”

Page 55: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

Java ORB Portability Interfaces 7

This section describes extensions to the portable stubs and skeletons architecture defined in the IDL/Java language mapping (orbos/97-03-01). These extensions will allow stubs and skeletons to be created for this Java to IDL mapping that can rely on a standard set of Java ORB Portability APIs, including APIs for serializing Java objects to GIOP format.

These ORB portability APIs will also allow alternative implementations of the RMI/IDL APIs.

Sun Microsystems plans to support implementations of these ORB portability APIs as part of future versions of the Java Development Kit (JDK).

See Sections 7.3.1 and 7.3.2 for simple example stubs and ties.

7.1 Additions to existing portability APIs

7.1.1 OutputStream

The following methods will be added to org.omg.CORBA.portable.OutputStream

public void write_Value(java.io.Serializable value) {throw new org.omg.CORBA.NO_IMPLEMENT(); }

public void start_block() {throw new org.omg.CORBA.NO_IMPLEMENT(); }

public void end_block() { throw new org.omg.CORBA.NO_IMPLEMENT(); }

public ORB orb() {throw new org.omg.CORBA.NO_IMPLEMENT(); }

Page 56: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 56 8/7/98

7

The start_block and end_block methods are used to delimit a block of data that needs to be sent as GIOP chunked data. The writing of chunk headers is the responsibility of the OutputStream and it can arbitrarily divide the higher-level block into further chunks, e.g., when GIOP fragmentation is being used. Start_block/end_block pairs may be nested arbitrarily deeply.

The orb method returns the ORB that created the OutputStream.

7.1.2 InputStream

The following methods will be added to org.omg.CORBA.portable.InputStream

public org.omg.CORBA.Object read_Object(java.lang.Class clz) {throw new org.omg.CORBA.NO_IMPLEMENT(); }

public java.io.Serializable read_Value() {throw new org.omg.CORBA.NO_IMPLEMENT(); }

public java.lang.Object read_Abstract(java.lang.Class clz) {throw new org.omg.CORBA.NO_IMPLEMENT(); }

public ORB orb() {throw new org.omg.CORBA.NO_IMPLEMENT(); }

For read_Object, the clz argument is the Class object for the stub class which corresponds to the type that is statically expected. Typically, the ORB runtime will allocate and return a stub object of this stub class.

For read_Abstract, the ORB runtime will return either a value object or a suitable stub object.

The orb method returns the ORB that created the OutputStream from which this InputStream was created.

7.1.3 ObjectImpl and Delegate

In the org.omg.CORBA.portable.ObjectImpl class the private __delegate field will be marked as transient.

The following methods wll be added to org.omg.CORBA.portable.ObjectImpl. public OutputStream _request(String operation, boolean responseExpected) {

return _get_delegate().request(this, operation, responseExpected); }

public InputStream _invoke(OutputStream output) throws ApplicationException, RemarshalException {

return _get_delegate().invoke(this, output); }

public void _releaseReply(InputStream input) {_get_delegate().releaseReply(this, input);

}

Page 57: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 57 8/7/98

7

_request is called by a stub to obtain an OutputStream for marshalling arguments. The stub must supply the operation name, and indicate if a response is expected (i.e. is this a one way call).

_invoke is called to invoke an operation. The stub provides an OutputStream that was previously returned by a _request() call. _invoke returns an InputStream which contains the marshalled reply. If an exception occurs, _invoke may throw an ApplicationException object which contains an InputStream from which the user exception state may be unmarshalled. In some cases a RemarshalException may be thrown by _invoke, in which case the stub must catch the RemarshalException and immediately remarshal the request by calling _request, marshalling the arguments (if any) and then calling _invoke. The stub must repeat this process until _invoke returns normally or raises some exception other than RemarshalException.

_releaseReply may optionally be called by a stub to release a reply stream back to the ORB when unmarshalling has completed. The stub passes the InputStream returned by _invoke() or ApplicationException.getInputStream(). A null value may also be passed to _releaseReply, in which case the method is a noop.

The following methods will be added to org.omg.CORBA.portable.Delegate.

public OutputStream request(org.omg.CORBA.Object self, String operation, boolean responseExpected) {

throw new org.omg.CORBA.NO_IMPLEMENT(); }

public InputStream invoke(org.omg.CORBA.Object self, OutputStream output) throws ApplicationException, RemarshalException {

throw new org.omg.CORBA.NO_IMPLEMENT(); }

public void releaseReply(org.omg.CORBA.Object self, InputStream input) {throw new org.omg.CORBA.NO_IMPLEMENT();

}

7.2 New portability APIs

7.2.1 ApplicationException

A new class org.omg.CORBA.portable.ApplicationException is added. This is used for reporting application level RMI/IDL exceptions between ORBs and stubs.

Page 58: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 58 8/7/98

7

public class ApplicationException extends Exception {// Arguments are the CORBA repository ID of the exception, and// an input stream from which the exception data can be read.public ApplicationException(String id,

org.omg.CORBA.portable.InputStream ins) { ... }public String getId() { ... }public org.omg.CORBA.portable.InputStream getInputStream() { ... }

}

getId returns the CORBA repository ID of the exception without removing it from the exception’s input stream.

7.2.2 ResponseHandler

A new class org.omg.CORBA.portable.ResponseHandler is added. This class is supplied by an ORB to a servant at invocation time and allows the servant to later retrieve an OutputStream for returning the invocation results.public interface ResponseHandler {

/** * Called by servant during a method invocation. The servant should call * this method to create a reply marshal buffer if no exception occurred. * * Returns an OutputStream suitable for marshalling reply. */ OutputStream createReply();

/** * Called by servant during a method invocation. The servant should call * this method to create a reply marshal buffer if a user exception occurred. *

* Returns an OutputStream suitable for marshalling the exception ID and the * user exception body.

*/ OutputStream createExceptionReply();}

7.2.3 InvokeHandler

A new interface org.omg.CORBA.portable.InvokeHandler is added to provide a dispatching mechanism for an incoming call.

Page 59: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 59 8/7/98

7

public interface InvokeHandler {

/** * Invoked by the ORB to dispatch a request to a servant. * * ORB passes the method name, an InputStream containing the marshalled * arguments, and a ResponseHandler which the servant uses to construct * a proper reply. * * Only CORBA SystemException may be thrown by this method. * * The method must return an OutputStream created by the ResponseHandler * which contains the marshalled reply. * * A servant must not retain a reference to the ResponseHandler beyond the * lifetime of the method invocation. * * Servant behavior is defined as follows: * 1. determine correct method, and unmarshal parameters from InputStream * 2. Invoke method implementation. * 3. If no user exception, create a normal Reply using ResponseHandler * 4. if user exception occurred, create exception reply using ResponseHandler * 5. Marshal reply into OutputStream returned by ResponseHandler * 6. return OutputStream to ORB. */

OutputStream _invoke(String method, InputStream input, ResponseHandler handler)

throws org.omg.CORBA.SystemException; }

The _invoke method receives requests issued to any servant that implements the InvokeHandler interface.

7.2.4 Tie

A new interface javax.rmi.CORBA.Tie is added. This defines methods which all RMI/IDL server side ties must implement.

The “javax” prefix indicates these classes are part of a standard extension. The use of this prefix allows these interfaces and classes to be delivered as an add-on to existing JDKs. Security checks in the browsers prevent downloading of classes whose names begin with “java”, so Sun has defined the convention of using “javax” for extensions.

Page 60: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 60 8/7/98

7

public interface Tie extends org.omg.CORBA.portable.InvokeHandler {

// Return an object reference for this Tie. org.omg.CORBA.Object thisObject();

// Deactivate this Tie.void deactivate();

// Return the ORB for this Tie.ORB orb();

// Set the ORB for this Tie.void orb(ORB orb);

// setTarget must be implemented by tie classes. It will be called by// registerTarget to notify them when a target object is set for the tie.

void setTarget(java.rmi.Remote target);}

The thisObject method returns an object reference for the target object represented by the Tie. It is semantically equivalent to the _this_object() method of the org.omg.PortableServer.Servant class.

The deactivate method deactivates the target object represented by the Tie. It is semantically equivalent to the deactivate_object method of the org.omg.PortableServer.POA class.

The orb() method returns the ORB for the Tie. It is semantically equivalent to the _orb() method of the org.omg.PortableServer.Servant class.

The orb(ORB orb) method sets the ORB for the Tie. It is semantically equivalent to the _orb(ORB orb) method of the org.omg.PortableServer.Servant class.

7.2.5 Stub

A new class javax.rmi.CORBA.Stub is added. This is the standard base class from which all RMI/IDL stubs must inherit. Its main reason for existence is to act as a convenience base class to handle stub serialization.

public abstract class Stub extends org.omg.CORBA.portable.ObjectImpl implements java.io.Serializable {

public int hashCode() { ... }public boolean equals(java.lang.Object obj) { ... }public String toString() { ... }

// Serialization methods to save and restore the IOR state. private void readObject(java.io.ObjectInputStream s) { ...} private void writeObject(java.io.ObjectOutputStream s) { ... }

}

Page 61: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 61 8/7/98

7

The hashCode method shall return the same hash code for all stubs that represent the same remote object. The equals method shall return true when used to compare stubs that represent the same remote object. The toString method shall return the same string for all stubs that represent the same remote object.

7.2.6 ValueHandler

A new interface javax.rmi.CORBA.ValueHandler is added. This defines methods which allow serialization of Java objects to and from GIOP streams.

public interface ValueHandler {

void write_Value(org.omg.CORBA.portable.OutputStream out, java.io.Serializable value) { ... }

java.io.Serializable read_Value( org.omg.CORBA.portable.InputStream in, java.lang.Class clz, org.omg.SendingContext.RunTime sender) { ... }}

The write_Value method can be used to write GIOP data, including RMI remote objects and serialized data objects, to an underlying portable OutputStream.

The implementation of the write_Value method interacts with the core Java serialization machinery. The data generated during serialization is written using the underlying OutputStream object.

The read_Value method can be used to read GIOP data, including RMI remote objects and serialized data objects, from an underlying portable InputStream. The clz parameter is the Java class of the value to be demarshalled, if known, or null if not known. The sender parameter is the sending context object passed in the optional service context tagged SendingContextRunTime in the GIOP header, if any, or null if no sending context was passed.

The implementation of the read_Value method interacts with the core Java serialization machinery. The data required during deserialization is read using the underlying InputStream object.

7.2.6.1 Execution model for Serialization

Sun will provide an implementation of the ValueHandler interface that handles writing and reading RMI/IDL objects by making calls to lower-level CORBA OutputStream and InputStream objects which can be provided by an independent ORB vendor. The Sun-provided implementation will handle the interactions with the JDK serialization machinery and will write any serialized data through to the lower level stream.

So typically the ORB vendors will implement their own GIOP input and output streams. Before transmitting RMI/IDL data they will create an object that supports the ValueHandler interface by calling the createValueHandler method of the

Page 62: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 62 8/7/98

7

javax.rmi.CORBA.Util class (see Section 7.2.7). When they need to marshal a non-IDL value, they will call ValueHandler.write_Value, and when they need to demarshal a non-IDL value, they will call ValueHandler.read_Value.

The ValueHandler.write_Value method is responsible for marshalling the value tag, codebase URL (if present), type information (if present), and state data (if present), but not the end tag. The ValueHandler.read_Value method demarshals all these items including the end tag.

The marshalling code in write_Value makes start_block and end_block calls as needed on the underlying OutputStream to indicate points in the stream where value chunks must be started and ended. The underlying OutputStream is free to perform additional chunking if required, e.g., when fragmentation is being used.

Optimizing the encoding of the codebase URL or type information as indirections is the responsibility of the underlying ORB output and input streams and is transparent to the ValueHandler object.

7.2.7 Util

A utility class javax.rmi.CORBA.Util is also provided that can be used by stubs to perform common operations.

Page 63: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 63 8/7/98

7

public class Util {

// Map a CORBA SystemException to a java.rmi.RemoteException public static java.rmi.RemoteException mapSystemException(

SystemException ex) { ... }

// Write a Java object as a CORBA any. public static void writeAny(OutputStream out, Object obj) { ... }

// Read a CORBA any as a Java object. public static Object readAny(InputStream in) { ... }

public static void write_RemoteObject(OutputStream out,java.lang.Object obj) { ... }

public static void write_AbstractObject(OutputStream out,java.lang.Object obj) { ... }

// Register a target for a Tie. This both adds the target/tie mapping// to our internal table and calls setTarget on the tie object.public static void registerTarget(javax.rmi.CORBA.Tie tie,

java.rmi.Remote target) { ... }

// Deactivate an object and remove the associated Tie from our internal table.// Calls Tie.deactivate to deactivate the object.public static void unexportObject(java.rmi.Remote target) { ... }

// Return the tie (if any) for a given target object.// Returns null if no tie is registered for the given target.public static javax.rmi.CORBA.Tie getTie(java.rmi.Remote target) { ... }

public static ValueHandler createValueHandler() { ... }

}

The Util.write_RemoteObject method is a utility method for use by stubs when writing an RMI/IDL object reference to an output stream. If obj is a stub object, Util.write_RemoteObject simply writes obj to OutputStream.write_Object. However, if obj is an RMI/IDL implementation object, then Util.write_RemoteObject allocates (or reuses) a suitable Tie (see Section 6.4), plugs together the tie with obj, and writes the object reference for the tie to OutputStream.write_Object.

The Util.write_AbstractObject method is another similar utility method for use by stubs. If obj is a value object, or a stub object, Util.write_AbstractObject simply writes obj to OutputStream.write_Abstract. However, if obj is an RMI/IDL implementation object, then Util.write_AbstractObject allocates (or reuses) a suitable Tie (see Section 6.4), plugs together the tie with obj, and writes the object reference for the tie to the OutputStream.write_Abstract.

Page 64: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 64 8/7/98

7

In order to support unexportObject, it is necessary for the Util class to maintain a table mapping target objects back to their associated Ties. It is the responsibility of the code that allocates a Tie to also call the registerTarget method to notify the Util class of the target object for a given tie. The registerTarget method will call the Tie.setTarget method to notify the tie object of its target object.

The createValueHandler method returns a singleton instance of a class that implements the ValueHandler interface.

7.3 Generated classes

There are two kinds of classes generated as part of this proposal.

• Stub classes. These are used by RMI/IDL clients to send calls to a server. A stub class is required for each RMI/IDL remote interface.

• Tie classes. These are used to process incoming calls and dispatch the calls to a server implementation class. A tie class is required for each RMI/IDL implementation class.

No generated classes are required for RMI/IDL value types, exceptions, etc.

7.3.1 Stub classes

For each RMI/IDL remote interface Foo there will be a stub class Foo_Stub that extends javax.rmi.CORBA.Stub and implements Foo.

The stub class will support stub methods for all the RMI/IDL remote methods in the RMI/IDL remote interfaces that it implements, and must have a public no-argument constructor..

Here is a simple RMI/IDL interface and an example stub class:

public interface Aardvark extends java.rmi.Remote {public int echo(int x) throws java.rmi.RemoteException, Boomerang;

}

Page 65: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 65 8/7/98

7

public class Aardvark_Stub extends javax.rmi.CORBA.Stubimplements Aardvark {

public Aardvark_Stub() {} // can be implicit or explicit

public int echo(int x) throws java.rmi.RemoteException, Boomerang {InputStream in = null;try {

try { OutputStream out = _request(“echo”);

out.write_long(x);in = _invoke(out);return in.read_long();

} catch (ApplicationException ex) { in = ex.getInputStream();

String id = in.read_string(); if (id.equals("IDL:Boomerang/1.0")) {

throw (Boomerang)in.read_Value(); } else {

throw new java.rmi.UnexpectedException(id);}

} catch (RemarshalException ex) {return echo(x);

} } catch (SystemException ex) {

throw javax.rmi.CORBA.Util.mapSystemException(ex);} finally {

_releaseReply(in);}

}

7.3.2 Tie classes

For each RMI/IDL implementation class there will be a corresponding tie class that implements javax.rmi.CORBA.Tie . The tie class is called by the ORB to process an incoming call and to pass the call through to an associated target implementation object.

After the Tie object has been constructed, the target implementation object must be set with a call on Util.registerTarget .

Here is a simple RMI/IDL interface and an example Tie class:

public interface Aardvark extends java.rmi.Remote {public int echo(int x) throws java.rmi.RemoteException, Boomerang;

}

Page 66: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 66 8/7/98

7

public class Aardvark_Tie extends org.omg.PortableServer.Servant implements javax.rmi.CORBA.Tie {

private Aardvark target;

public void setTarget(java.rmi.Remote targ) {target = (Aardvark) targ;

}

public OutputStream _invoke(String method, InputStream in, ResponseHandler rh) {

try {if (method.equals(“echo”)) {

try {int x = in.read_long();int result = target.echo(x);OutputStream out = rh.createReply();

out.write_long(result);return out;

} catch (Boomerang ex) {String exid = "IDL:Boomerang/1.0";OutputStream out = rh.createExceptionReply();out.write_string(exid);out.write_Value(ex);

return out; } } else { throw new org.omg.CORBA.MARSHAL();

}} catch (java.rmi.RemoteException ex) {

// It is illegal for RMI servers to throw RemoteException.throw new org.omg.CORBA.UNKNOWN();

}}

public org.omg.CORBA.Object thisObject() { ... }

public void deactivate() { ... }

public ORB orb() { ... }

public void orb(ORB orb) { ... }}

7.4 Additions to existing JDK APIs.

A new baseclass is added for RMI/IDL servers, the javax.rmi.PortableRemoteObject class.

Page 67: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 67 8/7/98

7

7.4.1 PortableRemoteObject

The javax.rmi.PortableRemoteObject class is intended to act as a base class for RMI/IDL server implementation classes (see Section 4.3.1).

public class PortableRemoteObject {

protected PortableRemoteObject() throws RemoteException { ... }

public static void exportObject(java.rmi.Remote obj)throws RemoteException { ... }

public static java.rmi.Remote toStub(java.rmi.Remote obj)throws java.rmi.NoSuchObjectException { ... }

public static void unexportObject(java.rmi.Remote obj)throws java.rmi.NoSuchObjectException { ... }

public static java.lang.Object narrow(java.lang.Object obj,java.lang.Class newClass) throws ClassCastException { ... }

}

The protected constructor is called by the derived implementation class to initialize the base class state.

Server side implementation objects may either inherit from javax.rmi.PortableRemoteObject or they may simply implement an RMI/IDL remote interface and then use the exportObject method to register themselves as a server object.

It is up to to the implementation to decide when to actually export remote objects. It may be done in the PortableRemoteObject constructor (for objects that subclass PortableRemoteObject) or in the exportObject method, or it may be deferred until the remote object is actually written to an OutputStream.

The toStub method takes a server implementation object and returns a stub object that can be used to access that server object. The argument object must either be a subclass of PortableRemoteObject or have been previously the target of a call on PortableRemoteObject.exportObject. The returned stub implements the same RMI/IDL remote interfaces as the implementation object. If an RMI/IDL Tie class is available for the given object, the toStub method will return an IIOP stub; otherwise, it will return a JRMP stub. The toStub method may be passed a stub, in which case it simply returns this stub.

The unexportObject method is used to deregister a server object from the ORB runtimes, allowing the object to become available for garbage collection. This is implemented by calling through to Util.unexportObject .

Page 68: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 68 8/7/98

7

The narrow method takes an object reference or an object of an RMI/IDL abstract interface type and attempts to narrow it to conform to the given newClass RMI/IDL type. If the operation is successful the result will be an object of type newClass, otherwise an exception will be thrown.

Page 69: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

Conformance & CORBA Changes 8

8.1 Conformance

In order to be conformant with this specification, a product must implement the complete specification.

8.2 Changes to Adopted Specifications

The following modifications are made to existing OMG standards.

8.2.1 Unicode character and string literals

We add the ability to define Unicode character literals to the rules for character literals defined in CORBA V2.1, OMG IDL Syntax and Semantics, Section 3.2.5.

The new escape sequence \uhhhh can be used to introduce a Unicode character literal. This escape consists of a backslash ‘\’ followed by the character ‘u’ followed by one, two, three, or four hexadecimal digits. The sequence of hexadecimal digits is terminated by the first character that is not a hexadecimal digit.

Thus the character literal ‘\u002E’ represents the unicode period character ‘.’ and the character literal ‘\u3bC’ represents the unicode greek small letter mu.

Since a string literal is defined as a sequence of character literals, this change also allows the use of the \uhhhh escape in string literals.

These escapes are only valid in wstring and wchar literals.

8.2.2 Serialization of generated classes

This submission defines “native JVM serialization” support for GIOP. In order to take advantage of this support, the following changes shall be made as part of this submission:

Page 70: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 70 8/7/98

8

1. The generated Java classes and interfaces (from the direct mapping) shall be marked by implementing or extending a new marker interface org.omg.CORBA.portable.IDLEntity which extends java.io.Serializable and has no methods. The IIOP serialization classes will detect these instances and marshal them using the generated marshaling code in the Helper class.

2. The generated classes, including the stub classes, shall support Java object serialization semantics.

3. The generated stub classes shall provide a public no-argument constructor.

8.2.3 List of changes

Chapters 4 through 6 plus Sections 7.2 through 7.4 of this submission will be added to the CORBA 2.x spec (as is), the changes described in Sections 8.2.1 and 8.2.2 will be made, and Section 7.1 will be merged into the existing IDL/Java portability layer definition.

Page 71: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

IDL file structure A

This appendix is not part of the formal Java to IDL proposal, but it contains some suggestions for generated file structure.

As a convenience to developers we recommend mapping each RMI/IDL interface, value type, or exception type to a separate .idl file. This follows the normal Java style and is likely to be easier for Java RMI/IDL programmers to maintain than requiring that (say) all IDL definitions be put into a single IDL file.

This approach does raise some issues for the generated IDL, which are briefly worth mentioning.

First, the use of separate .idl files requires the use of “reopenable” modules, so that separate files can have separate free-standing module definitions.

Second, although IDL permits forward references to IDL interfaces, it does not support forward references to structs or exceptions, and there are some limits on the use of interface references. Any forward references to interfaces must be satisfied by later definitions of those interfaces.

To overcome these difficulties, we recommend using an IDL file layout consisting of:

1. The entire IDL definition is bracketed in standard C pre-processor boilerplate used to guarantee it is only included once:

#ifndef __foo__#define __foo__

...#endif

2. An IDL forward reference is generated for each IDL interface that is referenced. (This may require entering and exiting the appropriate target module.)

3. An IDL forward reference is generated for each IDL value type that is referenced. (This may require entering and exiting the appropriate target module.)

Page 72: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 72 8/7/98

4. Each exception referenced in the IDL is #included , in arbitrary order.

5. If the generated IDL is an interface we #include any inherited interfaces.

6. If the generated IDL is a value type we #include any inherited value types.

7. For each reference to an IDL sequence type we generate a bracketed value definition.

#ifndef __org_omg_sequences_fred_seq_Stuff__#define __org_omg_sequences_fred_seq_Stuff__module org {module omg {module sequences {module fred {

value seq_Stuff sequence<::fred::Stuff>;};};};};#endif

This allows different IDL files in the same module to independently define any necessary sequence typedefs.

8. We then (finally) generate the target IDL, in the appropriate module.

9. We #include any interfaces that we have declared forward references to.

10. We #include any value types that we have declared forward references to.

Below is an example of how a chunk of RMI/IDL gets mapped to Java.

A.1 The Java definition

Here’s an example RMI/IDL interface, where the referenced type fred.Stuff is an RMI/IDL value type, fred.Test2 is another RMI/IDL remote interface type, and fred.OurException is an RMI/IDL exception type.

Page 73: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 73 8/7/98

package fred;

import java.rmi.*;

public interface Test extends Remote {

void noop() throws RemoteException;

String echo(String arg) throws RemoteException;

Stuff echoStuff(Stuff p) throws RemoteException;

Test echoTest(Test t) throws RemoteException;

int[] echoInts(int args[]) throws RemoteException;

Stuff[] echoStuffs(Stuff args[]) throws RemoteException;

void manyArgs(char a, byte b, short c, int d, long e, float f, double g) throws RemoteException;

Test2 fetchTest2() throws RemoteException;

void throwAnException() throws RemoteException, OurException;}

Page 74: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 74 8/7/98

A.2 The generated IDL definition#ifndef __fred_Test__#define __fred_Test__

module fred {interface Test2;valuetype Stuff;

};

#include “fred/OurEx.idl”

#ifndef __org_omg_sequences_seq_long__#define __org_omg_sequences_seq_long__module org {module omg {module sequences {

valuetype seq_long sequence<long>;};};};#endif

#ifndef __org_omg_sequences_fred_seq_Stuff__#define __org_omg_sequences_fred_seq_Stuff__module org {module omg {module sequences {module fred {

valuetype seq_Stuff sequence<::fred::Stuff>;};};};};#endif

module fred {

interface Test {void noop();

::CORBA::WStringValue echo(in ::CORBA::WStringValue arg0);

::fred::Stuff echoStuff(in ::fred::Stuff arg0);

::fred::Test echoTest(in ::fred::Test arg0);

::org::omg::sequences::seq_long echoInts(in ::org::omg::sequences::seq_long arg0);

Page 75: Java Language to IDL Mapping Joint Submission (RTF update) · Joint Submission (RTF update) Inprise Corporation International Business Machines Corporation Netscape Communications

orbos/98-07-19: Java to IDL 75 8/7/98

::org::omg::sequences::fred::seq_Stuff echoStuffs(in ::org::omg::sequences::fred::seq_Stuff arg0);

void manyArgs( in wchar arg0, in octet arg1, in short arg2, in long arg3, in long long arg4, in float arg5, in double arg6);

::fred::Test2 fetchTest2();

void throwAnException() raises (::fred::OurEx);};};

#include “fred/Test2.idl”#include “fred/Stuff.idl”

#endif