Home > English, Erlang, Java > How to create a Java “Erlang” node with JInterface!

How to create a Java “Erlang” node with JInterface!


For some things (maybe) Erlang is not the best language. Sometimes you have to deal with databases, GUI and other things that can be treated better with Java or other languages. But I’m sure about one things: if you want to built a distributed, fault tolerant system, you have to use Erlang.

The question thus is the following: how can we make Erlang code interact with other languages?

Well, if you are familiar to Java you may want to use JInterface, a library provided in the Erlang standard installation (or at least it should) that provides you functionalities for dealing with Erlang. As the title of the post says, my goal today is to build a Java “Erlang” node and pass messagges from it to a standard Erlang node.

The first instruction provided by JInterface you must know for this is the following:

OtpNode myOtpNode = new OtpNode("server");

Basically it creates a new node with the standard cookie, but you may also set a different cookie for the node using: 

OtpNode myOtpNode = new OtpNode("server", "mycookie");

So far I have only created an object myOtpNode which represents a node running in the host where it is executed, to “spawn” a new process you have to create a mailbox, that is identified by a pid or a registered name.

You can do it easily in the following way:

OtpMbox myOtpMbox = myOtpNode.createMbox("counter");

As you can see a new mailbox was created with name counter, actually the creation and naming can be done separately in the following way:

OtpMbox myOtpMbox = myOtpNode.createMbox();
myOtpMbox.registerName("counter");

Now you can refer to this node by its name, or by its pid that can be retrieve using:

OtpErlangPid myOptErlangPid = myOtpMbox.self();

OtpMbox has two important methods: send and receive that implement the sending and receiving operation of an
Erlang mailbox:

myOtpMbox.send(myOtpErlangPid, myOtpErlangTuple);
OtpErlangObject myOtpErlangObject = myOtpMbox.receive();

JInterface provides many Erlang types to developers. These types are actually converted from normal Java types;
most widely used are:

OtpErlangPid, OtpErlangTuple, OtpErlangBoolean, OtpErlangString, OtpErlangAtom, OtpErlangFloat,
OtpErlangLong.

Now let’s create a new node with the JInterface that implements the counter server we have seen in some previous post:

import com.ericsson.otp.erlang.*;

public class CounterServer
{

	public static void main(String[] args) throws Exception

         {

	       OtpNode myNode = new OtpNode("server");

                OtpMbox myMbox = myNode.createMbox("counterserver");

                OtpErlangObject myObject;

                OtpErlangTuple myMsg;

                OtpErlangPid from;

                OtpErlangString command;

                Integer counter = 0;

	       OtpErlangAtom myAtom = new OtpErlangAtom("ok");

	       while(counter >= 0) try

                {

                        myObject = myMbox.receive();

                        myMsg = (OtpErlangTuple) myObject;

                        from = (OtpErlangPid) myMsg.elementAt(0);

                        command = (OtpErlangString) myMsg.elementAt(1);

                        // here you may want to check the value of command

                        OtpErlangObject[] reply = new OtpErlangObject[2];

                        reply[0] = myAtom;

                        reply[1] = new OtpErlangInt(counter);

                        OtpErlangTuple myTuple = new OtpErlangTuple(reply);

                        myMbox.send(from, myTuple);

                        counter++;

		} catch(OtpErlangExit e)

                  {

                        break;

                  }

        }

}

Now, let’s create an Erlang client that tries to connect to the Java node and get the state of the counter:

-module(client).

-export([count/0]).

count() ->

	{countserver, 'server@pegaso'} ! {self(), "count"},

	receive

		{ok, Counter} ->

			io:format("Counter is at value: ~p~n", [Counter])

	end.

JInterface is inside your Erlang distribution…so to compile the java code and execute it, you must pass the right path to the java compiler and virtual machine. You can find the path by typing code:get_path() in the Erlang shell, once you have it type (note that you must put your path):

pegaso:Desktop bellerofonte$ javac -classpath ".:/usr/local/lib/erlang/lib/jinterface-1.4.2/priv/OtpErlang.jar" \
CounterServer.java

Ok, now your code should be compiled, but it order to allow the nodes networking you must start a programm called epmd (first search if it is already running as I did in the following code):

pegaso:Desktop bellerofonte$ epmd&
pegaso:Desktop bellerofonte$ epmd: Tue Jan 5 17:43:01 2010: epmd running - daemon = 0

pegaso:Desktop bellerofonte$ ps ax | grep epmd

2996 s000 S 0:00.01 epmd

2998 s000 R+ 0:00.00 grep epmd

Now execute the Java code:

pegaso:Desktop bellerofonte$ java -classpath ".:/usr/local/lib/erlang/lib/jinterface-1.4.2/priv/OtpErlang.jar" \
CounterServer

You can search if there are some nodes running in your machine as follows:

pegaso:Desktop bellerofonte$ epmd -names
epmd: up and running on port 4369 with data:
name server at port 52436

Ok, since I just want to check whether the Java code (and messagge passing) is working or not I’m not going to use the Erlang module I wrote above, but I’m going to test the functionalities of the Java counter server from an Erlang shell:

pegaso:Desktop bellerofonte$ erl -sname client

Erlang (BEAM) emulator version 5.6.5 

Eshell V5.6.5 (abort with ^G)

(client@pegaso)1> net:ping('server@pegaso').
pong

(client@pegaso)2> flush().
Shell got {ok,0}
ok

(client@pegaso)3> {counterserver, 'server@pegaso'} ! {self(), "count"}.
{<0.37.0>,"count"}

(client@pegaso)4> flush(). 
Shell got {ok,1}
ok

(client@pegaso)5> {counterserver, 'server@pegaso'} ! {self(), "count"}.
{<0.37.0>,"count"}

(client@pegaso)6> flush().
Shell got {ok,2}
ok

Well, it seems working!
Stay tuned for more stuff!

About these ads
Categories: English, Erlang, Java Tags: , ,
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: