$> erl -name foo@foo.bar
그렇게 하면 epmd가 자동으로 듭니다. 그래야 나중에 Java가 붙을 때 Java 프로그램의 node 이름이 해당 epmd에 등록 되기 때문에, 반드시 이렇게 해 주어야 합니다.
Erlang과 Java 프로그램의 연동은 서로 메시지를 주고 받는 과정을 통해서 이루어집니다. 따라서 연동을 하려면 Java 프로그램과 연동할 Erlang 프로세스가 떠 있어야 합니다. 다음의 간단한 프로그램 예제를 봅시다. 이 파일을 ets_java_frontend.erl로 저장하고 컴파일 해 둡니다.
-module(ets_java_frontend).
-export([start/0, shutdown/0, show/0, rpc/1]).
start() ->
LoopPid = spawn(fun loop/0),
register(ets_server, LoopPid).
shutdown() ->
Pid = whereis(ets_server),
Pid ! quit.
show() ->
Pid = whereis(ets_server),
Pid ! show.
rpc(T) ->
Pid = whereis(ets_server),
Pid ! T.
loop() ->
EtsHandle = ets:new(test, [set]),
loop(EtsHandle).
loop(Handle) ->
receive
show ->
List = ets:tab2list(Handle),
io:format("~p~n", [List]),
loop(Handle);
quit ->
{ok, terminated};
{tuple, T} ->
io:format("msg is received ~p~n", [T]),
ets:insert(Handle, T),
loop(Handle);
true ->
io:format("unprocessable msg is received~n"),
loop(Handle)
end.
이 Erlang 프로그램은 {tuple, T} 형태의 메시지를 받으면 T (투플입니다)를 ets에 저장하는 프로그램입니다. spawn해서 프로세스를 생성할 때 해당 프로세스의 Pid를 register() 호출을 통해 등록하고 있는데, Java쪽에서 이 Erlang 프로그램에 메시지를 보낼 때 register()할 때 전달한 프로세스 이름(위의 경우에는 ets_server)을 통해 해당 프로세스의 mbox에 메시지를 전달하므로, register()를 반드시 호출해 프로세스 이름을 등록해 두어야 합니다.
이렇게 하면 Java 프로그램 안에서 Erlang 프로세스에 메시지를 전달할 수 있는데요. 공짜로 되는 것은 아니고 (당연하겠죠?) Erlang 패키지에 포함되어 있는 JInterface라는 라이브러리를 통하여야 합니다. Windows라면 해당 라이브러리는 C:/Program Files/erl5.7.2/lib/jinterface-1.5.1/priv에 있고, Unix라면 아마 /usr/lib/erlang/ 아래 어딘가에 해당 jar가 있을 겁니다. ^^;
잡소리는 집어치우고 해당 프로그램 예제를 간단하게 훑어보면...
import java.io.IOException;
import com.ericsson.otp.erlang.*;
public class ETP {
private String node;
private OtpNode self;
private OtpMbox mbox;
/**
* create ETP instance.
* @param name name of the erlang server node.
* @throws IOException
*/
public ETP(String node) throws IOException {
this.node = node;
try {
this.self = new OtpNode("java_erl_bjlee");
} catch ( IOException e ) {
System.err.println("cannot create ETP instance.");
e.printStackTrace();
throw e;
}
this.mbox = self.createMbox("etp_java_client");
}
private OtpErlangTuple createMessage(OtpErlangTuple tuple) {
OtpErlangObject[] aTerm = new OtpErlangObject[2];
aTerm[0] = new OtpErlangAtom("tuple");
aTerm[1] = tuple;
OtpErlangTuple msg = new OtpErlangTuple( aTerm );
return msg;
}
private void send(OtpErlangTuple msg) {
mbox.send("ets_server", this.node, msg);
}
public boolean put(String key, String value) {
OtpErlangObject[] aTuple = new OtpErlangObject[2];
aTuple[0] = new OtpErlangAtom(key);
aTuple[1] = new OtpErlangAtom(value);
OtpErlangTuple tuple = new OtpErlangTuple(aTuple);
OtpErlangTuple msg = createMessage(tuple);
send(msg);
return true;
}
}
this.node에는 통신할 Erlang 노드의 이름이 들어갑니다. 이 페이지 맨 위에서처럼 했다면 foo가 들어가야겠군요. 먼저 OtpNode를 생성하구요. (이름을 주어야 합니다. Java 프로그램은 별개의 Erlang 노드인 것처럼 동작하거든요.) 그 다음에 message 송수신에 사용될 mbox를 만듭니다.
그 다음에는 이제 메시지를 보내 Erlang 프로그램이 원하는 작업을 하도록 만들면 됩니다. put 메소드의 코드를 보시면 되겠습니다. mbox.send() 함수가 최종적으로 호출되는데, 이 때 첫 번째 인자로는 통신할 erlang 프로세스의 registered name이 들어가고, 두 번째 인자로는 해당 프로세스가 돌고 있는 Erlang node, 그리고 세 번째 인자로는 실제로 전송할 메시지가 들어갑니다.
이제 Main 클래스를 다음과 같이 작성하고 돌려보면...
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
ETP etp;
try {
etp = new ETP("foo");
} catch (IOException e) {
e.printStackTrace();
return;
}
etp.put("test1", "value1");
etp.put("test2", "value2");
System.out.println("finished");
}
}
참. 돌리기 전에 erl 셸에서 ets_java_frontend:start()를 먼저 실행해주어야 합니다. ㅎㅎ 어쨌든 실행하고 위의 Java 프로그램을 돌려보면... erl 쪽 화면에 메시지들이 찍히면서 ets에 내가 전송한 투플들이 저장됩니다. 저장이 잘 되었는지는 erl 셸에서 ets_java_frontend:show()를 실행하여 확인할 수 있습니다.
소중한 의견, 감사합니다. ^^
감사합니다, 좋은 정보 얻어가네요 ^^
2009.12.24 10:28 [ ADDR : EDIT/ DEL : REPLY ]