From Erlang / Elixir to Java and back. Adventure for 20 minutes

  • Tutorial

Hi all!


When you have to communicate from the Erlang / Elixir world with Java and back, there are not too many options. All abandoned jinterface and the new library encon , a basic example of the use of which is presented under the cat.


Add dependencies


Add a Encondependency to the JVMapplication:


Maven :


<dependencies>
  ...
  <dependency><groupId>io.appulse.encon</groupId><artifactId>encon</artifactId><version>1.6.4</version></dependency>
  ...
</dependencies>

Gradle :


dependencies {
  compile'io.appulse.encon:encon:1.6.4'
}

NOTE: if there is such a need (for example, the project is on Ant), then dependencies in the form of jar files can be found on GitHub, in the releases section .

Run Erlang node


import io.appulse.encon.Node;
import io.appulse.encon.Nodes;
import io.appulse.encon.config.NodeConfig;
// Создание конфига ноды.// Больше деталей - см. проект encon-config
NodeConfig config = NodeConfig.builder()
    // true - для локальных нод,// false (по умолчанию) - доступных извне
    .shortName(true)
    .cookie("secret")
    .build();
// Созадние, регистрация в EPMD и запуск сервера новой Erlang ноды
Node node = Nodes.singleNode("echo-node", config);

NOTE: in order for the example above to work, you must either start the daemon EPMDor its Java implementation .

Create Mailbox


Mailbox, it is a process in Erlang terminology:


import io.appulse.encon.mailbox.Mailbox;
Mailbox mailbox = node.mailbox()
    .name("popa") // опционально
    .build();

Connection to nodes


NOTE: You can initiate a connection from Erlang / Elixir or Java by automatically sending a message using the plugin format {Имя, Нода}or by PID (if there is one).

You can start communication between the nodes by sending a ping message from the side of Erlang through net_adm:ping/1:


(erlang@localhost)1> net_adm:ping('java@localhost').
pong(erlang@localhost)2>

It is also possible to send a message to {Name, Node}where Nodethe view atom is 'java@localhost', and Namethis is the PID or registered name of the mailbox that exists on the Java side.


(erlang@localhost)1> {my_process, 'java@localhost'} ! hello.
hello(erlang@localhost)2>

If the mailbox exists on the Java side, then it will receive a message.


We send the message from Java


There is a whole family of sendmethods Mailboxthat deliver:


  • send ( ErlangPid , ErlangTerm ) - sends a message to a remote or local PID ;
  • send ( String , ErlangTerm ) - sends the term to the local mailbox by its name of the same node;
  • send ( String , String , ErlangTerm ) - sends a message to a remote / local node and mailbox by its name.

Let's try, open the Erlang-shell and register it with the name ... 'shell':


(erlang@localhost)1> erlang:register(shell, self()).
true(erlang@localhost)2>

Now, we can send a message from Java (the connection with the node will be established automatically):


importstatic io.appulse.encon.terms.Erlang.atom;
mailbox.send("erlang@localhost", "shell", atom("hello"));

We return to Erlang and read the received message:


(erlang@localhost) 1> flush().
Shell got hello
ok(erlang@localhost) 2>

Receiving messages in java


To receive an incoming message, you must use one of the Mailboxmethods: receive()or receive(timeout, timeUnit), which can wait indefinitely for a new message or a fixed amount of time.


import io.appulse.encon.Node;
import io.appulse.encon.Nodes;
import io.appulse.encon.config.NodeConfig;
import io.appulse.encon.connection.regular.Message;
import io.appulse.encon.mailbox.Mailbox;
publicclassMain{
  publicstaticvoidmain(String[] args){
    NodeConfig config = NodeConfig.builder()
        .shortName(true)
        .build();
    Node node = Nodes.singleNode("java@localhost", config);
    Mailbox mailbox = node.mailbox()
        .name("my_process")
        .build();
    Message message = mailbox.receive();
    System.out.println("Incoming message: " + message.getBody().asText());
  }
}

Start the Erlang node and send a message:


$> erl -sname erlang@localhost
...
(erlang@localhost)1> {my_process, 'java@localhost'} ! hello.

Conclusion


These and many other examples can be viewed on the project website and / or on the GitHub page .


Also popular now: