The Mozilla
Organization
Our Mission
Who We Are
Getting Involved
Community
Editorials
What's New
Newsbot
Development
Roadmap
Module Owners
Blue Sky
Projects
Status
Tools
Products
Source Code
Binaries
Documentation
License Terms
Bug Reports
Quality
Search
Feedback
XPIDL Binding to Java

XPIDL Binding to Java

DRAFT: 23 July 1999

Note: This document is not a formal specification, but notes on a work in progress. Feedback is encouraged.

Overview

To use XPCOM interfaces from Java, we must have a consistent mapping that meets the following design goals:

  1. Interfaces, and their (hidden) implementations, must look and behave like regular Java classes as much as possible.
  2. Since Java is a strongly typed language, and strong typing contributes to both efficiency and correctness, the binding should use Java's type system as much as possible.
  3. Only standard Java syntax and semantics are allowed; no implementor of a JVM must adopt extensions to the JVM and Java language specs.

The following mapping is not the only one possible, and because of the mismatches between Java and XPCOM no mapping can be perfect. The author believes, however, that this mapping makes the best compromises for the sake of usability and simplicity.

Interfaces

Each XPCOM interface corresponds to a public Java interface of the same name.

In addition to the constants defined in the interface, each Java interface also has two additional public static final fields: INTERFACENAME_IID, of type org.mozilla.xpcom.nsID, containing the interface's IID, and INTERFACENAME_IID_STRING, a java.lang.String containing the IID's string value.

For backwards-compatibility, names beginning with "ns" will become NS_INTERFACENAME_IID{_STRING}, e.g. nsISupports has an IID field called NS_ISUPPORTS_IID.

Namespaces

By default, all XPCOM interfaces reside in the Java package org.mozilla.xpcom.

A "namespace" attribute on the interface places the interface in the package named by the attribute's value.

Types

Each XPIDL/XPCOM type maps to a Java type. Basic types -- integers, floating-point numbers, booleans and characters -- map to the corresponding Java "primitive" type. If a parameter's or attribute's type declaration has a "ref" or "ptr" attribute, the mapping uses the listed "reference" type.

Strings, interfaces, and nsIDs always use a reference type. and other complex types always use a reference type.

In some cases, no Java type corresponds exactly to the XPIDL type; conversions between the XPIDL and Java values are noted.

XPIDL Java C++ (NSPR) Notes
primitive reference
void void --- void
--- byte Byte PRInt8
short short Short PRInt16
long int Int PRInt32
long long long Long PRInt64
octet byte Byte PRUInt8 Sign bit converted to unsigned's high bit.
unsigned short short Short PRUInt16
unsigned long int Int PRUInt32
unsigned long long long Long PRUInt64
float float Float float
double double Double double
boolean boolean Boolean PRBool
char char (16-bit) Character char (8-bit) Java values truncated to 8 bits
wchar char Character PRUnichar
string --- String char * Java values converted to UTF-8
wstring --- String PRUnichar *
interface --- namespace. interface interface *
[ptr, nsid] native(nsID) --- org.mozilla.xpcom.nsID nsID *
[ptr, ns_iid(id-param)] native(void) --- org.mozilla.xpcom.nsISupports void *
all other [ptr] native(type) --- Type-dependent: The implementation may use a pre-defined class, or simply ignore declarations containing the type. type *

Typedefs

Because Java has no corresponding "typedef" declaration, the Java type for a defined type is the "expanded" type from unravelling that and all intermediate typedefs.

Forward References

Java does not require forward references per se. If the interface resides in a different namespace from the interface being generated, the generated Java interface will include an appropriate import statement; otherwise, the import will be omitted.

A "namespace" attribute on a forward reference tells the XPIDL compiler which package the named interface belongs in, should the compiler not be able to discover that information itself.

For more information, see Namespaces, above.

Constants

Each constant defined within the interface corresponds to a public static final field of the same name, of the Java type corresponding to the XPIDL type, according to the mapping above.

Methods

Each method defined within the interface corresponds to a public method the same name. The signature and Java types of the methods conform to patterns summarized in the table below.

XPIDLJavaC++
void Method(in type var) void Method(type var)
NS_IMETHOD Method(type var)
void Method(out type var)
or void Method(inout type var)
void Method(type[] var)
NS_IMETHOD Method(typevar)
type Method()
or void Method([retval] out type var)
type Method()
NS_IMETHOD Method(type *_retval)
[notxpcom] type Method() type Method() type Method()
[noscript] void Method() /* not supported */ NS_IMETHOD Method()
Error Codes

Instead of explicitly returning an "nsresult" as the C++ binding does, Java XPCOM methods throw an org.mozilla.xpcom.XPCOMException when the nsresult is negative (or greater than 0x80000000). XPCOMException is a RuntimeException, so it is not declared in the method's throws clause.

Justification:

An explicit "nsresult" return value would place the burden of testing for successful return on the programmers; failing to do so would lead to mysterious bugs later. Unlike C++, Java has a well-established and fully portable exception mechanism for just this purpose.

Declaring the exception, instead of using a RuntimeException, would forces the programmer to consider method failure ... but catching an exception for every single XPCOM method would prove too tedious, and lead to the dangerous practice of "catching" the exception to keep the compiler happy without doing anything useful with it.

Success Codes

Any nsresults greater than 0 (but less than 0x80000000) are available by calling {method in class TBD}. This value is stored per thread, so it must be used before calling another XPCOM method.

Out Parameters and Return Values

The method's return value, or its out parameter marked with the "retval" attribute, becomes the return value of the corresponding Java method.

Other out or inout parameters become arguments of the array type corresponding to the XPIDL's parameter type. For example, an "out double" becomes an argument of Java type "double[]". Callers pass in an array of at least one element, which the method would fill with its value.

Justification:

The CORBA-to-Java binding uses type-safe "holder" objects for out values, but that would require generating an extra class for every interface. A Holder for type Object, on the other hand, would not be type-safe.

Length-one arrays provide type safety without extra classes, even though arrays have extra overhead and the small possibility of being allocated as zero-length. MS-COM takes this approach in its binding.

Because of the overhead for arrays or holders, the binding maps the XPIDL return value to the Java method's return value. (This is another motivation for using exceptions instead of success/error return codes; see above.)

Attributes

Each attribute corresponds to a pair of methods of the form public AttributeType getAttributeName() and public void setAttributeName(AttributeType value) . The first letter of AttributeName is capitalized, if necessary. Readonly attributes have only the "get" method. Each method behaves exactly as described in the "Methods" section.

Justification:

The "get" and "set" methods begin with lowercase, unlike most XPCOM methods, to fit the JavaBeans naming pattern.

Support Classes and Interfaces

class org.mozilla.xpcom.XPCOMException

TBD

class org.mozilla.xpcom.nsID

TBD

interface org.mozilla.xpcom.nsISupports

TBD

interface org.mozilla.xpcom.nsIComponentManager

TBD

interface org.mozilla.xpcom.nsIServiceManager

TBD

class namespace.InterfaceName__Proxy

TBD


Frank Mitchell
Last modified: Thu Jul 22 15:34:49 PDT 1999

Copyright © 1998-1999 The Mozilla Organization.