Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Integrating Erlang and Java

5,016 views

Published on

Here are my slides from the Erlang eXchange 2008

Published in: Technology, News & Politics

Integrating Erlang and Java

  1. 1. Integrating Erlang and Java Dennis Byrne - ThoughtWorks [email_address] http://notdennisbyrne.blogspot.com/ © ThoughtWorks 2008
  2. 2. Overview <ul><li>Java vs. Erlang </li></ul><ul><li>Jinterface Intro </li></ul><ul><li>Erlang Data Types </li></ul><ul><li>Nodes </li></ul><ul><li>Message Passing </li></ul><ul><li>Process Registration </li></ul><ul><li>Linking </li></ul><ul><li>Trapping Exits </li></ul>© ThoughtWorks 2008
  3. 3. Java vs. Erlang <ul><li>Strongly typed </li></ul><ul><li>Object Oriented </li></ul><ul><li>Pass by Reference </li></ul><ul><li>Shared Memory </li></ul><ul><li>Mutable State </li></ul><ul><li>Nouns </li></ul><ul><li>Dynamically Typed </li></ul><ul><li>Functional Programming </li></ul><ul><li>Pass by Value </li></ul><ul><li>Non shared memory </li></ul><ul><li>Immutable State </li></ul><ul><li>Verbs </li></ul>© ThoughtWorks 2008 Both compiled to byte code
  4. 4. Introduction <ul><li>Created in Java 1.1 </li></ul><ul><li>Little more than 10,000 LoC </li></ul><ul><li>Primarily authored by Gordon Beaton </li></ul><ul><li>OTP_DIRlibjinterface-X.XprivOtpErlang.jar </li></ul><ul><li>Jinterface Nodes run in separate user space </li></ul><ul><li>Different than JRuby, Jython, Groovy, etc. </li></ul><ul><li>Speaks the wire protocol </li></ul>© ThoughtWorks 2008
  5. 5. Modeling Erlang Types <ul><li>OtpErlangObject </li></ul><ul><li>OtpErlangPid </li></ul><ul><li>OtpErlangRef </li></ul><ul><li>OtpErlangList </li></ul><ul><li>OtpErlangPort </li></ul><ul><li>OtpErlangBinary </li></ul><ul><li>OtpErlangBoolean </li></ul><ul><li>OtpErlangByte </li></ul><ul><li>OtpErlangTuple </li></ul><ul><li>OtpErlangString </li></ul><ul><li>OtpErlangFloat </li></ul><ul><li>OtpErlangAtom </li></ul>© ThoughtWorks 2008
  6. 6. Modeling Nodes <ul><li>One JVM, more than one node </li></ul><ul><li>Jinterface nodes are “hidden nodes” </li></ul><ul><li>Hidden Node </li></ul><ul><ul><li>$ erl –hidden </li></ul></ul><ul><ul><li>Non-transitive connections </li></ul></ul><ul><ul><li>Not returned by erlang:nodes/0 </li></ul></ul>© ThoughtWorks 2008
  7. 7. Modeling a Node, Long Names <ul><li>$ erl – name name </li></ul><ul><li>> ‘ [email_address] ’ = node() . </li></ul><ul><li>OtpNode node = new OtpNode(&quot;name@host.com&quot;); </li></ul><ul><li>assert &quot;name@host.com&quot;.equals( node.node() ); </li></ul>© ThoughtWorks 2008
  8. 8. Modeling a Node, Short Name <ul><li>$erl -sname name </li></ul><ul><li>> ‘ [email_address] ’ = node() . </li></ul><ul><li>OtpNode node = new OtpNode( “ name ” ); </li></ul><ul><li>assert “ [email_address] ” .equals( node.node() ); </li></ul>© ThoughtWorks 2008
  9. 9. Cookies, Command Line <ul><li>$ erl – name name – setcookie cookie </li></ul><ul><li>> cookie = erlang:get_cookie() . </li></ul><ul><li>OtpNode node = new OtpNode( “ name ” , “ cookie ” ); </li></ul><ul><li>assert &quot;cookie&quot;.equals( node.cookie() ); </li></ul>© ThoughtWorks 2008
  10. 10. Cookies, Programmatically <ul><li>$ erl – name name </li></ul><ul><li>> erlang:set_cookie(node(), cookie) </li></ul><ul><li>> cookie = erlang:get_cookie() . </li></ul><ul><li>OtpNode node = new OtpNode( “ name ” ); </li></ul><ul><li>node.setCookie(&quot;cookie&quot;) ; </li></ul><ul><li>assert “ cookie ” .equals( node.cookie() ); </li></ul>© ThoughtWorks 2008
  11. 11. net_adm:ping/0 <ul><li>$ erl </li></ul><ul><li>> pong = net_adm:ping(b@byrned) . </li></ul><ul><li>> pang = net_adm:ping(c@byrned). </li></ul><ul><li>OtpNode a = new OtpNode(&quot;a@byrned&quot;, &quot;z&quot;); </li></ul><ul><li>OtpNode b = new OtpNode(&quot;b@byrned&quot;, &quot;z&quot;); </li></ul><ul><li>OtpNode c = new OtpNode(&quot;c@byrned&quot;, &quot;notz&quot;); </li></ul><ul><li>assert a.ping(&quot;b&quot;, 20); </li></ul><ul><li>assert !a.ping(&quot;c&quot;, 20) & !a.ping(&quot;d&quot;, 20); </li></ul>© ThoughtWorks 2008
  12. 12. Local Status Changes <ul><li>OtpNode node = new OtpNode( “ node ” ); </li></ul><ul><li>node.registerStatusHandler( </li></ul><ul><li>new OtpNodeStatus() { </li></ul><ul><li> public void localStatus(String node, </li></ul><ul><li>boolean up, Object info) { </li></ul><ul><li>// local initialization </li></ul><ul><li>// or clean up logic </li></ul><ul><li> } </li></ul><ul><li>}); </li></ul>© ThoughtWorks 2008
  13. 13. Remote Status Changes, monitor_node/2 <ul><li>OtpNode node = new OtpNode( “ node ” ); </li></ul><ul><li>node.registerStatusHandler( </li></ul><ul><li>new OtpNodeStatus() { </li></ul><ul><li> public void remoteStatus(String node, boolean up, Object info) { </li></ul><ul><li>// peer node is up or down? </li></ul><ul><li> } </li></ul><ul><li>}); </li></ul>© ThoughtWorks 2008
  14. 14. Handling Connection Attempts <ul><li>OtpNode node = new OtpNode(&quot;a&quot;); </li></ul><ul><li>node.registerStatusHandler( </li></ul><ul><li>new OtpNodeStatus() { </li></ul><ul><li> public void connAttempt(String node, </li></ul><ul><li>boolean incoming, Object info) { </li></ul><ul><li>// handle failed connections </li></ul><ul><li> } </li></ul><ul><li>}); </li></ul>© ThoughtWorks 2008
  15. 15. Modeling Processes with OtpMbox <ul><li>$ erl – sname foo </li></ul><ul><li>> Pid = self() , Msg = 999. </li></ul><ul><li>> spawn ( fun() -> Pid ! Msg end ). </li></ul><ul><li>> Msg = receive Any -> Any end . </li></ul><ul><li>OtpNode node = new OtpNode(&quot;foo&quot;); </li></ul><ul><li>OtpMbox first = node.createMbox(); </li></ul><ul><li>OtpMbox second = node.createMbox() ; </li></ul><ul><li>OtpErlangInt msg = new OtpErlangInt(999); </li></ul><ul><li>second.send( first.self() , msg); </li></ul><ul><li>assert msg.equals( first.receive() ); </li></ul>© ThoughtWorks 2008
  16. 16. receive <ul><li>$ erl </li></ul><ul><li>> receive Any -> Any after 1000 -> true end. </li></ul><ul><li>OtpMbox mailBox = node.createMbox(); </li></ul><ul><li>mailBox.receive(1000); </li></ul>© ThoughtWorks 2008
  17. 17. Pass By Value <ul><li>OtpNode node = new OtpNode(&quot;value&quot;); </li></ul><ul><li>OtpMbox from = node.createMbox(); </li></ul><ul><li>OtpMbox to = node.createMbox(); </li></ul><ul><li>OtpErlangLong sent = new OtpErlangLong(9); </li></ul><ul><li>from.send(to.self(), sent); </li></ul><ul><li>Object received = to.receive(); </li></ul><ul><li>assert sent != received; </li></ul>© ThoughtWorks 2008
  18. 18. User Defined Classes <ul><li>OtpMbox to = node.createMbox(); </li></ul><ul><li>OtpMbox from = node.createMbox(); </li></ul><ul><li>Customer customer = new Customer(); </li></ul><ul><li>customer.name = &quot;Dennis&quot;; </li></ul><ul><li>from.send(to.self(), </li></ul><ul><li>new OtpErlangBinary(customer)); </li></ul><ul><li>OtpErlangBinary bin = (OtpErlangBinary) </li></ul><ul><li>to.receive(); </li></ul><ul><li>Customer object = (Customer)bin.getObject(); </li></ul><ul><li>assert &quot;Dennis&quot;.equals( object.name ); </li></ul>© ThoughtWorks 2008
  19. 19. Remote Execution <ul><li>OtpErlangObject[] call = new OtpErlangObject[] { </li></ul><ul><li>new OtpErlangAtom(&quot;call&quot;), </li></ul><ul><li>new OtpErlangAtom(&quot;erlang&quot;), /* mod */ </li></ul><ul><li>new OtpErlangAtom(&quot;node&quot;), /* fun */ </li></ul><ul><li>new OtpErlangList(), /* arg */ </li></ul><ul><li>new OtpErlangAtom(&quot;user&quot;) </li></ul><ul><li>}; </li></ul><ul><li>OtpErlangTuple msg = new OtpErlangTuple( </li></ul><ul><li>new OtpErlangObject[] { </li></ul><ul><li>mailBox.self(), </li></ul><ul><li>new OtpErlangTuple(call) </li></ul><ul><li>}); </li></ul>© ThoughtWorks 2008
  20. 20. Remote Execution <ul><li>mailBox.send(&quot;rex&quot;, &quot;d@byrned&quot;, msg); </li></ul><ul><li>OtpErlangTuple response = </li></ul><ul><li>(OtpErlangTuple) mailBox.receive(); </li></ul><ul><li>OtpErlangObject proc = response.elementAt(0); </li></ul><ul><li>assert &quot;rex&quot;.equals(proc.toString()); </li></ul><ul><li>OtpErlangObject from = response.elementAt(1); </li></ul><ul><li>assert &quot;d@byrned&quot;.equals(from.toString()); </li></ul>© ThoughtWorks 2008
  21. 21. register/2 <ul><li>$ erl </li></ul><ul><li>> register(first, self()). </li></ul><ul><li>> Msg = 999. </li></ul><ul><li>> spawn(fun() -> first ! Msg end). </li></ul><ul><li>Msg = receive Any -> Any end. </li></ul><ul><li>OtpMbox first = node.createMbox(); </li></ul><ul><li>OtpMbox second = node.createMbox(); </li></ul><ul><li>OtpErlangInt msg = new OtpErlangInt(999); </li></ul><ul><li>first.registerName(&quot;first&quot;); </li></ul><ul><li>second.send(&quot;first&quot;, msg); </li></ul><ul><li>assert msg.equals(first.receive()); </li></ul>© ThoughtWorks 2008
  22. 22. whereis/2 <ul><li>$ erl </li></ul><ul><li>> Pid = self(). </li></ul><ul><li>> register(w, Pid). </li></ul><ul><li>> spawn(fun() -> Pid = whereis(w) end). </li></ul><ul><li>OtpNode node = new OtpNode( “ whereis ” ); </li></ul><ul><li>OtpMbox first = node.createMbox( “ w ” ); </li></ul><ul><li>OtpMbox second = node.createMbox(); </li></ul><ul><li>assert first.self() == second.whereis( “ w ” ) ; </li></ul>© ThoughtWorks 2008
  23. 23. registered/0 <ul><li>> register(a, self()). </li></ul><ul><li>> F = fun() -> receive Any -> Any end end. </li></ul><ul><li>> register(b, spawn(F)). </li></ul><ul><li>> true = lists:member(a, registered() ). </li></ul><ul><li>> true = lists:member(b, registered() ). </li></ul><ul><li>OtpNode node = new OtpNode(&quot;node&quot;); </li></ul><ul><li>node.createMbox(&quot;a&quot;); </li></ul><ul><li>node.createMbox(&quot;b&quot;); </li></ul><ul><li>List names = Arrays. asList ( node.getNames() ); </li></ul><ul><li>assert names.contains(&quot;a&quot;); </li></ul><ul><li>assert names.contains(&quot;b&quot;); </li></ul>© ThoughtWorks 2008
  24. 24. Linking <ul><li>> process_flag(trap_exit, true). </li></ul><ul><li>> F = fun() -> </li></ul><ul><ul><li> receive after 200 -> exit(normal) end </li></ul></ul><ul><ul><li> end. </li></ul></ul><ul><li>> Pid = spawn_link (F). </li></ul><ul><li>OtpMbox first = node.createMbox(); </li></ul><ul><li>OtpMbox second = node.createMbox(); </li></ul><ul><li>first. link (second.self()); </li></ul><ul><li>second.close() ; </li></ul>© ThoughtWorks 2008
  25. 25. Trapping Exits <ul><li>{'EXIT', Pid, normal} = receive X -> X end. </li></ul><ul><li>try { </li></ul><ul><li>first.receive(); </li></ul><ul><li>}catch(OtpErlangExit e) { </li></ul><ul><li>assert second.self().equals(e.pid()); </li></ul><ul><li>assert &quot;normal&quot;.equals(e.getMessage()); </li></ul><ul><li>} </li></ul>© ThoughtWorks 2008
  26. 26. Unlinking <ul><li>> Pid = spawn_link(Fun). </li></ul><ul><li>> unlink(Pid). </li></ul><ul><li>> nil = receive X -> received </li></ul><ul><ul><ul><ul><li>after 2000 -> nil end. </li></ul></ul></ul></ul><ul><li>OtpMbox first = node.createMbox(); </li></ul><ul><li>OtpMbox second = node.createMbox(); </li></ul><ul><li>first.link(second.self()); </li></ul><ul><li>second.unlink(first.self()); </li></ul><ul><li>second.exit(&quot;normal&quot;); </li></ul><ul><li>assert null == first.receive(1); </li></ul>© ThoughtWorks 2008
  27. 27. Concurrent Programming <ul><li>Fast Context Switching </li></ul><ul><li>Fast Message Passing </li></ul><ul><li>Fast Process Spawning </li></ul>© ThoughtWorks 2008
  28. 28. Synchronization <ul><li>Sending and receiving messages </li></ul><ul><li>Mailbox creation </li></ul><ul><li>Linking and unlinking processes </li></ul><ul><li>Node creation </li></ul>© ThoughtWorks 2008
  29. 29. Thanks <ul><li>Dennis Byrne </li></ul><ul><li>[email_address] </li></ul><ul><li>http://notdennisbyrne.blogspot.com/ </li></ul>© ThoughtWorks 2008

×