科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件Erlang与JAVA交互操作

Erlang与JAVA交互操作

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

我们要用 java 实现的原始 erlang 程序如下,没错,就是巨简单的 echo ,我们的目标是要把它用 java 来改写,不仅写服务端,也要写客户端。

作者: 来源:LUPA开源社区【原创】 2008年6月12日

关键字: Erlang java Linux

  • 评论
  • 分享微博
  • 分享邮件

试了一下传说中的 JInterface ,使用 OtpErlang.jar 的整个过程其实非常简单,似乎比 JMS 的程序都简单。

  首先,我们要用 java 实现的原始 erlang 程序如下,没错,就是巨简单的 echo ,我们的目标是要把它用 java 来改写,不仅写服务端,也要写客户端。

  -module(echo_client).

  -export([run/0]).

  run()->

  Msg= "Hello Echo!",

  {echo, abc@merlin} ! {self(), Msg},

  io:format("send ~p ~n", [Msg]),

  receive

  Res->

  io:format("received ~p ~n", [Res])

  end.

  -module(echo_server).

  -export([start/0]).

  start()->

  register(echo, self()),

  io:format("echo start~n", []),

  loop().

  loop()->

  receive

  {Pid, Msg} ->

  io:format("received ~p from ~p~n", [Msg, Pid]),

  Pid! Msg

  Any->

  io:format("received ~p ~n", [Any])

  end,

  loop().

  写得并不严密,用了一堆硬编码,主要是个示例,就那么个意思,大家将就着看。

  先说一下 JInterface 的一些基本概念。JInterface 的目的是:为 Java 提供一个包,使得 Java 程序在外部可以看起来就像一个标准的 Erlang Node 能以标准的 Erlang 方式与其他的节点进行通讯。它包装了 Erlang 节点之间分布式的通讯协议,编码解码,以及基本的 Erlang 操作,也就是 pid register send receive link unlink 等等,朴实无华。不过,作为两个语言之间的接口包,有了这些基本功能也就足够了。

  根据 Erlang 的目录惯例, JInterface 的 Jar 在 ERLANG_HOME/lib/jinterface-x.x/priv 目录下,名字为 OtpErlang.jar 。注意,必须使用和你当前 Erlang 版本下的包,否则出了什么妖怪问题,别来问我,就算是问我,我也不知道该怎么办。:D 之前一直有一个误解,想当然的以为 JInterface 会用 JNI 什么的来实现,而自从碰过一次以后,对 JNI 这种“难以掌控”的东西总觉得有点畏难,所以,迟迟都没有动手,没想到,竟是纯 Java 实现的一个包。用起来方便,部署起来也漂亮。爽!

  闲话休提,直接上代码得了。先是 Client 的代码。

  packagecom.test.erlang

  import java.io.IOException

  import com.ericsson.otp.erlang.*;

  public classErlangEchoClient{

  public staticvoidmain(String[]args)throwsIOException{

  String v= System.getProperties().getProperty("OtpConnection.trace")

  System.out.println("OtpConnection.trace="+v)

  OtpNode self= newOtpNode("bcd", "123")

  System.out.println("node:"+self.node())

  System.out.println("cookie:"+self.cookie())

  if (self.ping("abc", 2000)){

  System.out.println("remote is up")

  } else{

  System.out.println("remote is not up")

  return

  }

  String text= "Hi there"

  OtpMbox mbox= self.createMbox()

  OtpErlangObject[] msg= newOtpErlangObject[2]

  msg[0]= mbox.self()

  msg[1]= new OtpErlangString(text)

  OtpErlangTuple tuple= newOtpErlangTuple(msg)

  mbox.send("echo", "abc", tuple)

  System.out.println("send:"+text)

  try{

  OtpErlangObject reply= mbox.receive()

  System.out.println("receive[raw]:"+reply)

  if (replyinstanceofOtpErlangString){

  OtpErlangString text2= (OtpErlangString)reply

  System.out.println("receive[text]:"+text2)

  }

  } catch (Exceptione){

  System.out.println(""+ e)

  }

  }

  }

  packagecom.test.erlang

  import java.io.IOException

  import com.ericsson.otp.erlang.*;

  public classErlangEchoServer{

  public staticvoidmain(String[]args)throwsIOException{

  String v= System.getProperties().getProperty("OtpConnection.trace")

  System.out.println("OtpConnection.trace="+v)

  OtpNode self= newOtpNode("server1", "123")

  System.out.println("node:"+self.node())

  System.out.println("cookie:"+self.cookie())

  OtpMbox mbox= self.createMbox("echo")

  String[] names= self.getNames()

  for(int i=0i<names.lengthi++)System.out.println("name:"+names[i])

  while (true){

  try{

  OtpErlangObject request= mbox.receive()

  System.out.println("receive[raw]:"+request)

  if (requestinstanceofOtpErlangTuple){

  OtpErlangTuple t= (OtpErlangTuple)request

  OtpErlangPid pid= (OtpErlangPid)(t.elementAt(0))

  OtpErlangString text= (OtpErlangString)(t.elementAt(1))

  System.out.println("receive[text]:"+text)

  OtpErlangString response= text

  mbox.send(pid, response)

  }

  } catch (Exceptione){

  System.out.println(""+ e)

  }

  }

  }

  }

  这里有几个需要提示的地方。

  1. OtpErlang.jar 里面会访问系统变量 OtpConnection.trace 当它不为 0 时会显示链底层的 debug 信息。在调试时,这个设置就像照妖镜,有啥妖怪问题,都给照出来了。

  2. setcookie 很重要。我这里是明确指定 123 作为 cookie ,如果这个 cookie 不匹配(比如,最好用: erl -setcookie 123 来启动)两端就死活也连不上,尤其是当你没有把上面的 trace 打开的时候,那你就去找去吧。

  3. epmd 是 erlang 通讯机制的基础。也就是说,运行的时候,至少需要有一个 epmd 在运行(实际上也只会有一个)。比如说 java client 调用 erlang server ,erlang client 调 java server ,erlang client 调 erlang server 都很正常的不会有问题。而如果你要 java client 调 java server 的时候,最好先确认一下系统中有 epmd 正在运行。否则就会很邪。而启动一个 epmd 的超简单方法就是打开一个 erlang 的 console ,什么也不干都行。

  扩充话提:Java Node 是 Hidden Node,一般启动的 Erlang 程序都运行在非 hidden node 模式下。具体 Hidden Node 的区别超出了本日志的范围,大家自己啃文档吧(其实是我也没看得很透彻,就不误导大家了,哈哈)。

  再来个体外话,有了 JInterface 就等于在 Java 和 Erlang 的世界之间架起了一座桥梁。通过这个桥梁能干吗呢?这个问题留给你自己去想。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章