aboutsummaryrefslogtreecommitdiffstats
path: root/lib/jinterface/doc/src/jinterface_users_guide.xml
diff options
context:
space:
mode:
Diffstat (limited to 'lib/jinterface/doc/src/jinterface_users_guide.xml')
-rw-r--r--lib/jinterface/doc/src/jinterface_users_guide.xml448
1 files changed, 448 insertions, 0 deletions
diff --git a/lib/jinterface/doc/src/jinterface_users_guide.xml b/lib/jinterface/doc/src/jinterface_users_guide.xml
new file mode 100644
index 0000000000..7865a0cab4
--- /dev/null
+++ b/lib/jinterface/doc/src/jinterface_users_guide.xml
@@ -0,0 +1,448 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2000</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ 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.
+
+ </legalnotice>
+
+ <title>The Jinterface Package</title>
+ <prepared>Gordon Beaton, Babbis Xagorarakis</prepared>
+ <responsible>Gordon Beaton, Babbis Xagorarakis</responsible>
+ <docno></docno>
+ <approved></approved>
+ <checked></checked>
+ <date>000822</date>
+ <rev>A</rev>
+ <file>jinterface_users_guide.xml</file>
+ </header>
+ <p>The <seealso marker="java/com/ericsson/otp/erlang/package-summary">Jinterface</seealso> package provides
+ a set of tools for communication with Erlang processes. It can also be used for communication with
+ other Java processes using the same package, as well as C processes using the Erl_Interface library. </p>
+ <p>The set of classes in the package can be divided into two categories:
+ those that provide the actual communication, and those that provide a
+ Java representation of the Erlang data types. The latter are all
+ subclasses of OtpErlangObject, and they are identified by the
+ OtpErlang prefix.</p>
+ <p>Since this package provides a mechanism for communicating with Erlang,
+ message recipients can be Erlang processes or instances of
+ com.ericsson.otp.erlang.OtpMbox, both of which are identified with
+ pids and possibly registered names. When pids or mailboxes are
+ mentioned as message senders or recipients in this section, it should
+ assumed that even Erlang processes are included, unless specified
+ otherwise.
+ The classes in
+ <seealso marker="java/com/ericsson/otp/erlang/package-summary">Jinterface</seealso> support the following:</p>
+ <list type="bulleted">
+ <item>manipulation of data represented as Erlang data types</item>
+ <item>conversion of data between Java and Erlang formats</item>
+ <item>encoding and decoding of Erlang data types for transmission or storage</item>
+ <item>communication between Java nodes and Erlang processes</item>
+ </list>
+ <p>In the following sections, these topics are described:</p>
+ <list type="bulleted">
+ <item>mapping of Erlang types to Java</item>
+ <item>encoding, decoding, and sending Erlang terms</item>
+ <item>connecting to a distributed Erlang node</item>
+ <item>using nodes, mailboxes and EPMD</item>
+ <item>sending and receiving Erlang messages and data</item>
+ <item>remote procedure calls</item>
+ <item>linking to remote processes</item>
+ <item>compiling your code for use with Jinterface</item>
+ <item>tracing message flow</item>
+ </list>
+
+ <section>
+ <title>Mapping of Basic Erlang Types to Java</title>
+ <p>This section describes the mapping of Erlang basic types to Java. </p>
+ <table>
+ <row>
+ <cell align="left" valign="middle">Erlang type</cell>
+ <cell align="left" valign="middle">Java type</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">atom</cell>
+ <cell align="left" valign="middle"><seealso marker="java/com/ericsson/otp/erlang/OtpErlangAtom">OtpErlangAtom</seealso></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">binary</cell>
+ <cell align="left" valign="middle"><seealso marker="java/com/ericsson/otp/erlang/OtpErlangBinary">OtpErlangBinary</seealso></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">floating point types</cell>
+ <cell align="left" valign="middle"><seealso marker="java/com/ericsson/otp/erlang/OtpErlangFloat">OtpErlangFloat</seealso>or <seealso marker="java/com/ericsson/otp/erlang/OtpErlangDouble">OtpErlangDouble</seealso>, depending on the floating point value size</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">integral types</cell>
+ <cell align="left" valign="middle">One of <seealso marker="java/com/ericsson/otp/erlang/OtpErlangByte">OtpErlangByte</seealso>,<seealso marker="java/com/ericsson/otp/erlang/OtpErlangChar">OtpErlangChar</seealso>,<seealso marker="java/com/ericsson/otp/erlang/OtpErlangShort">OtpErlangShort</seealso>,<seealso marker="java/com/ericsson/otp/erlang/OtpErlangUShort">OtpErlangUShort</seealso>,<seealso marker="java/com/ericsson/otp/erlang/OtpErlangInt">OtpErlangInt</seealso>,<seealso marker="java/com/ericsson/otp/erlang/OtpErlangUInt">OtpErlangUInt</seealso>or<seealso marker="java/com/ericsson/otp/erlang/OtpErlangLong">OtpErlangLong</seealso>, depending on the integral value size and sign</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">list</cell>
+ <cell align="left" valign="middle"><seealso marker="java/com/ericsson/otp/erlang/OtpErlangList">OtpErlangList</seealso></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">pid</cell>
+ <cell align="left" valign="middle"><seealso marker="java/com/ericsson/otp/erlang/OtpErlangPid">OtpErlangPid</seealso></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">port</cell>
+ <cell align="left" valign="middle"><seealso marker="java/com/ericsson/otp/erlang/OtpErlangPort">OtpErlangPort</seealso></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">ref</cell>
+ <cell align="left" valign="middle"><seealso marker="java/com/ericsson/otp/erlang/OtpErlangRef">OtpErlangRef</seealso></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">tuple</cell>
+ <cell align="left" valign="middle"><seealso marker="java/com/ericsson/otp/erlang/OtpErlangTuple">OtpErlangTuple</seealso></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">term</cell>
+ <cell align="left" valign="middle"><seealso marker="java/com/ericsson/otp/erlang/OtpErlangObject">OtpErlangObject</seealso></cell>
+ </row>
+ <tcaption>Mapping of Erlang basic types to Java</tcaption>
+ </table>
+ </section>
+
+ <section>
+ <title>Special Mapping Issues</title>
+ <p>The atoms <c>true</c> and <c>false</c> are special atoms, used as boolean values.
+ The class <seealso marker="java/com/ericsson/otp/erlang/OtpErlangBoolean">OtpErlangBoolean</seealso> can be used to represent these.</p>
+ <p>Lists in Erlang are also used to describe sequences of printable characters (strings).
+ A convenience class <seealso marker="java/com/ericsson/otp/erlang/OtpErlangString">OtpErlangString</seealso>
+ is provided to represent Erlang strings.</p>
+ </section>
+
+ <section>
+ <title>Nodes</title>
+ <p>A node as defined by Erlang/OTP is an instance of the Erlang Runtime
+ System, a virtual machine roughly equivalent to a JVM. Each node has a
+ unique name in the form of an identifier composed partly of the
+ hostname on which the node is running, e.g "[email protected]". Several
+ such nodes can run on the same host as long as their names are unique.
+ The class <seealso marker="java/com/ericsson/otp/erlang/OtpNode">OtpNode</seealso>
+ represents an Erlang node. It is created with a name
+ and optionally a port number on which it listens for incoming
+ connections. Before creating an instance of
+ <seealso marker="java/com/ericsson/otp/erlang/OtpNode">OtpNode</seealso>,
+ ensure that Epmd is running on the host machine. See the Erlang documentation
+ for more information about Epmd. In this example, the host name is appended
+ automatically to the identifier, and the port number is chosen by the
+ underlying system:</p>
+ <code type="none">
+OtpNode node = new OtpNode("gurka"); </code>
+ </section>
+
+ <section>
+ <title>Mailboxes</title>
+ <p>Erlang processes running on an Erlang node are identified by process
+ identifiers (pids) and, optionally, by registered names unique within
+ the node. Each Erlang process has an implicit mailbox that is used to
+ receive messages; the mailbox is identified with the pid of the
+ process.</p>
+ <p>Jinterface provides a similar mechanism with the class
+ <seealso marker="java/com/ericsson/otp/erlang/OtpMbox">OtpMbox</seealso>, a
+ mailbox that can be used to send and receive messages asynchronously.
+ Each OtpMbox is identified with a unique pid and , optionally, a registered
+ name unique within the
+ <seealso marker="java/com/ericsson/otp/erlang/OtpNode">OtpNode</seealso>. </p>
+ <p>Applications are free to create mailboxes as necessary. This is done
+ as follows:</p>
+ <code type="none">
+ OtpMbox mbox = node.createMbox(); </code>
+ <p>The mailbox created in the above example has no registered name,
+ although it does have a pid. The pid can be obtained from the mailbox
+ and included in messages sent from the mailbox, so that remote
+ processes are able to respond. </p>
+ <p>An application can register a name for a mailbox, either when the
+ mailbox is initially created:</p>
+ <code type="none">
+ OtpMbox mbox = node.createMbox("server"); </code>
+ <p>or later on, as necessary:</p>
+ <code type="none">
+ OtpMbox mbox = node.createMbox();
+ mbox.registerName("server"); </code>
+ <p>Registered names are usually necessary in order to start
+ communication, since it is impossible to know in advance the pid of a
+ remote process. If a well-known name for one of the processes is
+ chosen in advance and known by all communicating parties within an
+ application, each mailbox can send an initial message to the named
+ mailbox, which then can identify the sender pid.</p>
+ </section>
+
+ <section>
+ <title>Connections</title>
+ <p>It is not necessary to explicitly set up communication with a remote
+ node. Simply sending a message to a mailbox on that node will cause
+ the OtpNode to create a connection if one does not already exist. Once
+ the connection is established, subsequent messages to the same node
+ will reuse the same connection.</p>
+ <p>It is possible to check for the existence of a remote node before
+ attempting to communicate with it. Here we send a ping message to the
+ remote node to see if it is alive and accepting connections:</p>
+ <code type="none">
+ if (node.ping("remote",2000)) {
+ System.out.println("remote is up");
+ }
+ else {
+ System.out.println("remote is not up");
+ } </code>
+ <p>If the call to ping() succeeds, a connection to the remote node has
+ been established. Note that it is not necessary to ping remote nodes
+ before communicating with them, but by using ping you can determine if
+ the remote exists before attempting to communicate with it.</p>
+ <p>Connections are only permitted by nodes using the same security
+ cookie. The cookie is a short string provided either as an argument
+ when creating OtpNode objects, or found in the user's home directory
+ in the file <c>.erlang.cookie</c>. When a connection attempt is made, the
+ string is used as part of the authentication process. If you are
+ having trouble getting communication to work, use the trace facility
+ (described later in this document) to show the connection
+ establishment. A likely problem is that the cookies are different.</p>
+ <p>Connections are never broken explicitly. If a node fails or is closed,
+ a connection may be broken however.</p>
+ </section>
+
+ <section>
+ <title>Sending and Receiving Messages</title>
+ <p>Messages sent with this package must be instances of
+ <seealso marker="java/com/ericsson/otp/erlang/OtpErlangObject">OtpErlangObject</seealso>
+ or one of its subclasses. Message can be sent to processes or pids,
+ either by specifying the pid of the remote, or its registered name and
+ node.</p>
+ <p>In this example, we create a message containing our own pid so the
+ echo process can reply:</p>
+ <code type="none">
+ OtpErlangObject[] msg = new OtpErlangObject[2];
+ msg[0] = mbox.self();
+ msg[1] = new OtpErlangAtom("hello, world");
+ OtpErlangTuple tuple = new OtpErlangTuple(msg); </code>
+ <p>When we send the message, a connection will be created:</p>
+ <code type="none">
+ mbox.send("echo", "[email protected]", tuple); </code>
+ <p>And here we receive the reply:</p>
+ <code type="none">
+ OtpErlangObject reply = mbox.receive(); </code>
+ <p>Messages are sent asynchronously, so the call to <c>send()</c> returns as
+ soon as the message has been dispatched to the underlying
+ communication layer. This means that you receive no indication whether
+ the operation completed successfully or the remote even existed. If
+ you need this kind of confirmation, you should wait for a response
+ from the remote process.</p>
+ <p>The echo server itself might look like this:</p>
+ <code type="none">
+ OtpNode self = new OtpNode("gurka");
+ OtpMbox mbox = self.createMbox("echo");
+ OtpErlangObject o;
+ OtpErlangTuple msg;
+ OtpErlangPid from;
+
+ while (true) {
+ try {
+ o = mbox.receive();
+ if (o instanceof OtpErlangTuple) {
+ msg = (OtpErlangTuple)o;
+ from = (OtpErlangPid)(msg.elementAt(0));
+ mbox.send(from,msg.elementAt(1));
+ }
+ catch (Exception e) {
+ System.out.println("" + e);
+ }
+ } </code>
+ <p>In the examples above, only one mailbox was created on each node.
+ however you are free to create as many mailboxes on each node as you
+ like. You are also free to create as many nodes as you like on each
+ JVM, however because each node uses some limited system resources such
+ as file descriptors, it is recommended that you create only a small
+ number of nodes (such as one) on each JVM.</p>
+ </section>
+
+ <section>
+ <title>Sending Arbitrary Data</title>
+ <p>This package was originally intended to be used for communicating
+ between Java and Erlang, and for that reason the send and receive
+ methods all use Java representations of Erlang data types. </p>
+ <p>However it is possible to use the package to communicate with remote
+ processes written in Java as well, and in these cases it may be
+ desirable to send other data types.</p>
+ <p>The simplest way to do this is to encapsulate arbitrary data in
+ messages of type
+ <seealso marker="java/com/ericsson/otp/erlang/OtpErlangBinary">OtpErlangBinary</seealso>.
+ The OtpErlangBinary class can be created from arbitrary Java objects that implement the
+ Serializable or Externalizable interface:</p>
+ <code type="none">
+ o = new MyClass(foo);
+ mbox.send(remote,new OtpErlangBinary(o)); </code>
+ <p>The example above will cause the object to be serialized and
+ encapsulated in an OtpErlangBinary before being sent. The recipient
+ will receive an OtpErlangBinary but can extract the original object
+ from it:</p>
+ <code type="none">
+ msg = mbox.receive();
+ if (msg instanceof OtpErlangBinary) {
+ OtpErlangBinary b = (OtpErlangBinary)msg;
+ MyClass o = (MyClass)(b.getObject());
+ } </code>
+ </section>
+
+ <section>
+ <title>Linking to Remote Processes</title>
+ <p>Erlang defines a concept known as linked processes. A link is an
+ implicit connection between two processes that causes an exception to
+ be raised in one of the processes if the other process terminates for
+ any reason. Links are bidirectional: it does not matter which of the
+ two processes created the link or which of the linked processes
+ eventually terminates; an exception will be raised in the remaining
+ process. Links are also idempotent: at most one link can exist between
+ two given processes, only one operation is necessary to remove the
+ link.</p>
+ <p>Jinterface provides a similar mechanism. Also here, no distinction is
+ made between mailboxes and Erlang processes. A link can be created to
+ a remote mailbox or process when its pid is known:</p>
+ <code type="none">
+ mbox.link(remote); </code>
+ <p>The link can be removed by either of the processes in a similar manner:</p>
+ <code type="none">
+ mbox.unlink(remote); </code>
+ <p>If the remote process terminates while the link is still in place, an
+ exception will be raised on a subsequent call to receive():</p>
+ <code type="none">
+ try {
+ msg = mbox.receive();
+ }
+ catch (OtpErlangExit e) {
+ System.out.println("Remote pid " + e.pid() + " has terminated");
+ }
+ catch (OtpErlangDecodeException f) {
+ System.out.println("Received message could not be decoded: " + f);
+ } </code>
+ <p>When a mailbox is explicitly closed, exit messages will be sent in
+ order to break any outstanding links. If a mailbox is never closed but
+ instead goes out of scope, the objects <c>finalize()</c> method will call
+ <c>close()</c>. However since Java provides no guarantees about when or even
+ if finalize() will be called, it is important that your application
+ explicitly closes mailboxes when they are no longer needed if you
+ want links to work in a timely manner.
+ </p>
+ </section>
+
+ <section>
+ <title>Using EPMD</title>
+ <p>Epmd is the Erlang Port Mapper Daemon. Distributed Erlang nodes
+ register with epmd on the localhost to indicate to other nodes that
+ they exist and can accept connections. Epmd maintains a register of
+ node and port number information, and when a node wishes to connect to
+ another node, it first contacts epmd in order to find out the correct
+ port number to connect to.</p>
+ <p>The basic interaction with EPMD is done through instances of
+ <seealso marker="java/com/ericsson/otp/erlang/OtpEpmd">OtpEpmd</seealso> class.
+ Nodes wishing to contact other nodes must first request information
+ from Epmd before a connection can be set up, however this is done automatically
+ by <seealso marker="java/com/ericsson/otp/erlang/OtpSelf#connect(com.ericsson.otp.erlang.OtpPeer)">OtpSelf.connect()</seealso> when necessary. </p>
+ <p>When you use <seealso marker="java/com/ericsson/otp/erlang/OtpSelf#connect(com.ericsson.otp.erlang.OtpPeer)">OtpSelf.connect()</seealso> to connect to an Erlang node,
+ a connection is first made to epmd and, if the node is known, a
+ connection is then made to the Erlang node.</p>
+ <p>Java nodes can also register themselves with epmd if they want other
+ nodes in the system to be able to find and connect to them.
+ This is done by call to method <seealso marker="java/com/ericsson/otp/erlang/OtpEpmd#publishPort(com.ericsson.otp.erlang.OtpLocalNode)">OtpEpmd.publishPort()</seealso>.</p>
+ <p>Be aware that on some systems (such as VxWorks), a failed node will
+ not be detected by this mechanism since the operating system does not
+ automatically close descriptors that were left open when the node
+ failed. If a node has failed in this way, epmd will prevent you from
+ registering a new node with the old name, since it thinks that the old
+ name is still in use. In this case, you must unregister the name
+ explicitly, by using <seealso marker="java/com/ericsson/otp/erlang/OtpEpmd#unPublishPort(com.ericsson.otp.erlang.OtpLocalNode)">OtpEpmd.unPublishPort()</seealso></p>
+ <p>This will cause epmd to close the connection from the far end. Note
+ that if the name was in fact still in use by a node, the results of
+ this operation are unpredictable. Also, doing this does not cause the
+ local end of the connection to close, so resources may be consumed.</p>
+ </section>
+
+ <section>
+ <title>Remote Procedure Calls</title>
+ <p>An Erlang node acting as a client to another Erlang node
+ typically sends a request and waits for a reply. Such a request is
+ included in a function call at a remote node and is called a remote
+ procedure call. Remote procedure calls are supported through the class
+ <seealso marker="java/com/ericsson/otp/erlang/OtpConnection">OtpConnection</seealso>.
+ The following example shows how the
+ <seealso marker="java/com/ericsson/otp/erlang/OtpConnection">OtpConnection</seealso>
+ class is used for remote procedure calls:</p>
+ <code type="none">
+
+OtpSelf self = new OtpSelf("client", "hejsan" );
+OtpPeer other = new OtpPeer("server@balin");
+OtpConnection connection = self.connect(other);
+
+connection.sendRPC("erlang","date",new OtpErlangList());
+OtpErlangObject received = connection.receiveRPC();
+ </code>
+ <p><c>erlang:date/0</c> is just called to get the date tuple
+ from a remote host. </p>
+ </section>
+
+ <section>
+ <title>Compiling and Loading Your Code</title>
+ <p>In order to use any of the <seealso marker="java/com/ericsson/otp/erlang/package-summary">Jinterface</seealso>
+ classes, include the following line in your code:</p>
+ <code type="none">
+import com.ericsson.otp.erlang.*; </code>
+ <p>Determine where the top directory of your OTP installation is. You
+ can find this out by starting Erlang and entering the following
+ command at the Eshell prompt:</p>
+ <code type="none">
+Eshell V4.9.1.2 (abort with ^G)
+1> code:root_dir().
+/usr/local/otp </code>
+ <p>To compile your code, make sure that your Java compiler knows where
+ to find the file <c>OtpErlang.jar</c> which contains the package.
+ This is done by specifying an appropriate <c>-classpath</c>
+ argument on the command line, or by adding it to the <c>CLASSPATH</c>
+ definition in your <c>Makefile</c>. The correct value for this path is
+ <c>$OTPROOT/lib/jinterface</c><em>Vsn</em><c>/priv/OtpErlang.jar</c>, where <c>$OTPROOT</c>
+ is the path reported by <c>code:root_dir/0</c> in the above example and <em>Vsn</em> is the version of Jinterface, for example <c>jinterface-1.2</c></p>
+ <code type="none">
+$ javac -classpath ".:/usr/local/otp/lib/jinterface-1.2/priv/OtpErlang.jar"
+ myclass.java </code>
+ <p>When running your program, you will also need to specify the path to
+ <c>OtpErlang.jar</c> in a similar way.</p>
+ <code type="none">
+$ java ".:/usr/local/otp/lib/jinterface-1.2/priv/OtpErlang.jar" myclass </code>
+ </section>
+
+ <section>
+ <title>Tracing</title>
+ <p>Communication between nodes can be traced by setting a system property
+ before the communication classes in this package are initialized.
+ The value system property "OtpConnection.trace" is the default trace
+ level for all connections. Normally the default trace level is zero,
+ i.e. no tracing is performed. By setting
+ <seealso marker="java/com/ericsson/otp/erlang/OtpConnection">OtpConnection.trace</seealso>
+ to some non-zero value, the communication protocol can be shown in more or
+ less detail. The valid values are:</p>
+ <list type="bulleted">
+ <item>0: no tracing is performed</item>
+ <item>1: only ordinary send and reg-send messages are shown</item>
+ <item>2: control messages such as link, unlink and exit are shown</item>
+ <item>3: connection setup (handshake) is shown</item>
+ <item>4: epmd requests are shown</item>
+ </list>
+ <p>Each level also includes the information shown by all lower levels.</p>
+ </section>
+</chapter>
+