19992009 Ericsson AB. All Rights Reserved. The contents of this file are subject to the Erlang Public License, Version 1.1, (the "License"); you may not use this file except in compliance with the License. You should have received a copy of the Erlang Public License along with this software. If not, it can be retrieved online at http://www.erlang.org/. Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. IDL to Java language Mapping 98-09-24 A ch_java.xml
Introduction

This chapter describes the mapping of OMG IDL constructs to the Java programming language for the generation of native Java - Erlang communication.

This language mapping defines the following:

All OMG IDL basic types

All OMG IDL constructed types

References to constants defined in OMG IDL

Invocations of operations, including passing of parameters and receiving of result

Access to attributes

Specialties in the Mapping
Names Reserved by the Compiler

The IDL compiler reserves all identifiers starting with OE_ and oe_ for internal use.

Basic OMG IDL Types

The mapping of basic types are according to the standard. All basic types have a special Holder class.

OMG IDL type Java type float float double double short short unsigned short short long int long long long unsigned long long unsigned long long long char char wchar char boolean boolean octet octet string java.lang.String wstring java.lang.String any Any long double Not supported Object Not supported void void OMG IDL basic types
Constructed OMG IDL Types

All constructed types are according to the standard with three (3) major exceptions.

The IDL Exceptions are not implemented in this Java mapping.

The functions used for read/write to streams, defined in Helper functions are named unmarshal (instead for read) and marshal (instead for write).

The streams used in Helper functions are OtpInputStream for input and OtpOutputStream for output.

Mapping for Constants

Constants are mapped according to the standard.

Invocations of Operations

Operation invocation is implemented according to the standard. The implementation is in the class Stub.java]]> which implements the interface in .java]]>.

test._iStub client; client.op(10);
Operation Implementation

The server is implemented through extension of the class ImplBase.java]]> and implementation of all the methods in the interface.

public class server extends test._iImplBase { public void op(int i) throws java.lang.Exception { System.out.println("Received call op()"); o.value = i; return i; } }
Exceptions

While exception mapping is not implemented, the stubs will generate some Java exceptions in case of operation failure. No exceptions are propagated through the communication.

Access to Attributes

Attributes are supported according to the standard.

Summary of Argument/Result Passing for Java

All types (in, out or inout) of user defined parameters are supported in the Java mapping. This is also the case in the Erlang mappings but not in the C mapping. inout parameters are not supported in the C mapping so if you are going to do calls to or from a C program inout cannot be used in the IDL specifications.

out and inout parameters must be of Holder types. There is a jar file ( ic.jar) with Holder classes for the basic types in the ic application. This library is in the directory /priv]]>.

Communication Toolbox

The generated client and server stubs use the classes defined in the jinterface package to communicate with other nodes. The most important classes are :

OtpInputStream which is the stream class used for incoming message storage

OtpOutputStream which is the stream class used for outgoing message storage

OtpErlangPid which is the process identification class used to identify processes inside a java node.

The recommended constructor function for the OtpErlangPid is OtpErlangPid(String node, int id, int serial, int creation) where :

String node, is the name of the node where this process runs.

int id, is the identification number for this identity.

int serial, internal information, must be an 18-bit integer.

int creation, internal information, must have value in range 0..3.

OtpConnection which is used to define a connection between nodes.

While the connection object is stub side constructed in client stubs, it is returned after calling the accept function from an OtpErlangServer object in server stubs. The following methods used for node connection :

OtpInputStream receiveBuf(), which returns the incoming streams that contain the message arrived.

void sendBuf(OtpErlangPid client, OtpOutputStream reply), which sends a reply message (in an OtpOutputStream form) to the client node.

void close(), which closes a connection.

OtpServer which is used to define a server node.

The recommended constructor function for the OtpServer is :

OtpServer(String node, String cookie). where :

node is the requested name for the new java node, represented as a String object.

cookie is the requested cookie name for the new java node, represented as a String object.

The following methods used for node registration and connection acceptance :

boolean publishPort(), which registers the server node to epmd daemon.

OtpConnection accept(), which waits for a connection and returns the OtpConnection object which is unique for each client node.

The Package com.ericsson.otp.ic

The package com.ericsson.otp.ic contains a number of java classes specially designed for the IC generated java-back-ends :

Standard java classes defined through OMG-IDL java mapping :

BooleanHolder

ByteHolder

CharHolder

ShortHolder

IntHolder

LongHolder

FloatHolder

DoubleHolder

StringHolder

Any, AnyHelper, AnyHolder

TypeCode

TCKind

Implementation-dependant classes :

Environment

Holder

Erlang compatibility classes :

Pid, PidHelper, PidHolder

The Pid class originates from OtpErlangPid and is used to represent the Erlang built-in pid type, a process's identity. PidHelper and PidHolder are helper respectively holder classes for Pid.

Ref, RefHelper, RefHolder

The Ref class originates from OtpErlangRef and is used to represent the Erlang built-in ref type, an Erlang reference. RefHelper and RefHolder are helper respectively holder classes for Ref.

Port, PortHelper, PortHolder

The Port class originates from OtpErlangPort and is used to represent the Erlang built-in port type, an Erlang port. PortHelper and PortHolder are helper respectively holder classes for Port.

Term, TermHelper, TermHolder

The Term class originates from Any and is used to represent the Erlang built-in term type, an Erlang term. TermHelper and TermHolder are helper respectively holder classes for Term.

To use the Erlang build-in classes, you will have to include the file erlang.idl located under $OTPROOT/lib/ic/include.

The Term Class

The Term class is intended to represent the Erlang term generic type. It extends the Any class and it is basically used in the same way as in the Any type.

The big difference between Term and Any is the use of guard methods instead of TypeCode to determine the data included in the Term. This is especially true when the Term's value class cannot be determined at compilation time. The guard methods found in Term :

boolean isAtom() returns true if the Term is an OtpErlangAtom, false otherwise

boolean isConstant() returns true if the Term is neither an OtpErlangList nor an OtpErlangTuple, false otherwise

boolean isFloat() returns true if the Term is an OtpErlangFloat, false otherwise

boolean isInteger() returns true if the Term is an OtpErlangInt, false otherwise

boolean isList() returns true if the Term is an OtpErlangList, false otherwise

boolean isString() returns true if the Term is an OtpErlangString, false otherwise

boolean isNumber() returns true if the Term is an OtpErlangInteger or an OtpErlangFloat, false otherwise

boolean isPid() returns true if the Term is an OtpErlangPid or Pid, false otherwise

boolean isPort() returns true if the Term is an OtpErlangPort or Port, false otherwise

boolean isReference() returns true if the Term is an OtpErlangRef, false otherwise

boolean isTuple() returns true if the Term is an OtpErlangTuple, false otherwise

boolean isBinary() returns true if the Term is an OtpErlangBinary, false otherwise

Stub File Types

For each interface, three (3) stub/skeleton files are generated :

A java interface file, named after the idl interface.

A client stub file, named after the convention Stub]]> which implements the java interface. Example : _stackStub.java

A server stub file, named after the convention ImplBase]]> which implements the java interface. Example : _stackImplBase.java

Client Stub Initialization, Methods Exported

The recommended constructor function for client stubs accepts four (4) parameters :

String selfNode, the node identification name to be used in the new client node.

String peerNode, the node identification name where the client process is running.

String cookie, the cookie to be used.

Object server, where the java Object can be one of:

OtpErlangPid, the server's process identity under the node where the server process is running.

String, the server's registered name under the node where the server process is running.

The methods exported from the generated client stub are :

void __disconnect(), which disconnects the server connection.

void __reconnect(), which disconnects the server connection if open, and then connects to the same peer.

void __stop(), which sends the standard stop termination call. When connected to an Erlang server, the server will be terminated. When connected to a java server, this will set a stop flag that denotes that the server must be terminated.

com.ericsson.otp.erlang.OtpErlangRef __getRef(), will return the message reference received from a server that denotes which call it is referring to. This is useful when building asynchronous clients.

java.lang.Object __server(), which returns the server for the current connection.

Server Skeleton Initialization, Server Stub Implementation, Methods Exported

The constructor function for server skeleton accepts no parameters.

The server skeleton file contains a server switch which decodes messages from the input stream and calls implementation (callback) functions. As the server skeleton is declared abstract, the application programmer will have to create a stub class that extends the skeleton file. In this class, all operations defined in the interface class, generated under compiling the idl file, are implemented.

The server skeleton file exports the following methods:

OtpOutputStrem invoke(OtpInputStream request), where the input stream request is unmarshalled, the implementation function is called and a reply stream is marshalled.

boolean __isStopped(), which returns true if a stop message is received. The implementation of the stub should always check if such a message is received and terminate if so.

boolean __isStopped(com.ericsson.otp.ic.Environment), which returns true if a stop message is received for a certain Environment and Connection. The implementation of the stub should always check if such a message is received and terminate if so.

OtpErlangPid __getCallerPid(), which returns the caller identity for the latest call.

OtpErlangPid __getCallerPid(com.ericsson.otp.ic.Environment), which returns the caller identity for the latest call on a certain Environment.

java.util.Dictionary __operations(), which returns the operation dictionary which holds all operations supported by the server skeleton.

A Mapping Example

This is a small example of a simple stack. There are two operations on the stack, push and pop. The example shows some of the generated files.

// The source IDL file: stack.idl struct s { long l; string s; }; interface stack { void push(in s val); s pop(); };

When this file is compiled it produces eight files. Three important files are shown below.

The public interface is in stack.java.

public interface stack { /**** * Operation "stack::push" interface functions * */ void push(s val) throws java.lang.Exception; /**** * Operation "stack::pop" interface functions * */ s pop() throws java.lang.Exception; }

For the IDL struct s three files are generated, a public class in s.java.

final public class s { // instance variables public int l; public java.lang.String s; // constructors public s() {}; public s(int _l, java.lang.String _s) { l = _l; s = _s; }; };

A holder class in sHolder.java and a helper class in sHelper.java. The helper class is used for marshalling.

public class sHelper { // constructors private sHelper() {}; // methods public static s unmarshal(OtpInputStream in) throws java.lang.Exception { \011: \011: }; public static void marshal(OtpOutputStream out, s value) throws java.lang.Exception { \011: \011: }; };
Running the Compiled Code

When using the generated java code you must have added /priv]]> and /priv]]> to your CLASSPATH variable to get basic Holder types and the communication classes.