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:
The IDL compiler reserves all identifiers starting with
OE_
and oe_
for internal use.
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 |
All constructed types are according to the standard with three (3) major exceptions.
Helper
functions
are named unmarshal (instead for read) and marshal (instead for write).
Helper
functions are OtpInputStream
for
input and OtpOutputStream
for output.
Constants are mapped according to the standard.
Operation invocation is implemented according to the standard.
The implementation is in the class _<nterfacename>Stub.java
which implements
the interface in <nterfacename>.java
.
test._iStub client; client.op(10);
The server is implemented through extension of the class
_<nterfacename>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; } }
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.
Attributes are supported according to the standard.
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
$OTPROOT/lib/ic_<version number>/priv
.
The generated client and server stubs use the classes
defined in the jinterface
package to communicate
whith 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.
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.
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.
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.
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 contains a number of java classes specially designed for the IC generated java-back-ends :
OtpErlangPid
and is used to
represend the Erlang built-in pid
type, a process's identity.
PidHelper and PidHolder are helper respectively holder classes for Pid.
OtpErlangRef
and is used to
represend the Erlang built-in ref
type, an Erlang reference.
RefHelper and RefHolder are helper respectively holder classes for Ref.
OtpErlangPort
and is used to
represend the Erlang built-in port
type, an Erlang port.
PortHelper and PortHolder are helper respectively holder classes for Port.
Any
and is used to
represend the Erlang built-in term
type, an Erlang term.
TermHelper and TermHolder are helper respectively holder classes for Term.
erlang.idl
located under $OTPROOT/lib/ic/include
.
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
determinated 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
For each interface, three (3) stub/skeleton files are generated :
_< interface name >Stub
which implements the java interface. Example : _stackStub
.java
_< interface name >ImplBase
which implements the java interface. Example : _stackImplBase
.java
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 refering to.
This is usefull when building asynchroinous clients.
java.lang.Object __server()
, which returns the server for the current connection.
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.
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 { : : }; public static void marshal(OtpOutputStream out, s value) throws java.lang.Exception { : : }; };
When using the generated java code you must have added
$OTPROOT/lib/ic_<version number>/priv
and
$OTPROOT/lib/jinterface_<version number>/priv
to your
CLASSPATH
variable to get
basic Holder types and the communication classes.