1

Is it possible to make an rpc:call from erlang to java, using JInterface?

If yes, what should the Module argument in the call function set to?

call(Node, Module, Function, Args) -> Res | {badrpc, Reason}

What I got working was this (simple message send, see code below):

> {javambox, server@javaapp} ! {self(), greet, <<"Hello man">>}.
> flush().
Shell got {bye,10000}

But not an rpc call. Here was my attempt:

> rpc:call(server@javaapp, javambox, greet, <<"Hello man">>, 1000).
{badrpc,timeout}

Full Java Code

MyInterface.java:

import com.ericsson.otp.erlang.*;

import java.lang.reflect.InvocationTargetException;

public class MyInterface {

    OtpErlangPid from = null;
    OtpMbox myOtpMbox = null;

    public static void main(String[] args) {
        MyInterface i = new MyInterface();
    }

    public MyInterface() {
        setupMBox();
    }
    private void setupMBox() {
        System.out.println("Setting up mbox");
        try {
            // server@java-app??
            OtpNode myOtpNode = new OtpNode("server");
            myOtpNode.setCookie("secret");

            myOtpMbox = myOtpNode.createMbox("javambox");
            System.out.println("System ready to accept messages.");
            System.out.println("Hostname is:");
            System.out.println(java.net.InetAddress.getLocalHost().getHostName() );
            System.out.println("List of known names:");
            System.out.println(String.join(" , ", myOtpNode.getNames()));
            System.out.println("Secret cookie is:");
            System.out.println(myOtpNode.cookie());

            while (true) {
                OtpErlangTuple tuple = (OtpErlangTuple) myOtpMbox.receive();
                System.out.println("GOT MESAGE!");

                from = (OtpErlangPid) tuple.elementAt(0);
                OtpErlangAtom dispatch = (OtpErlangAtom) tuple.elementAt(1);

                if (dispatch.toString().equals("settext")) {

                    final OtpErlangBinary message = (OtpErlangBinary) tuple.elementAt(2);

                    System.out.println("Setting text to: " + new String(message.binaryValue()));
                } else if (dispatch.toString().equals("greet")) {
                    final OtpErlangBinary message = (OtpErlangBinary) tuple.elementAt(2);
                    // Send reply
                    OtpErlangAtom myAtom = new OtpErlangAtom("bye");
                    OtpErlangObject[] reply = new OtpErlangObject[2];
                    reply[0] = myAtom;
                    reply[1] = new OtpErlangInt(10000);
                    OtpErlangTuple myTuple = new OtpErlangTuple(reply);
                    myOtpMbox.send(from, myTuple);
                    System.out.println("Greet got, bye!");

                } else{
                    System.out.println("Got unexpected message....");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Java Node Output

Setting up mbox
System ready to accept messages.
Hostname is:
javaapp
List of known names:
javambox
Secret cookie is:
secret
GOT MESAGE!
Greet got, bye!
Andriy Drozdyuk
  • 58,435
  • 50
  • 171
  • 272

1 Answers1

1

The Java side has no concept of modules, so you can use whatever name in the RPC. Check the sources to see how the call is encoded as a message, and don't forget to send an answer back. I find it easier to reason about simple messages, but maybe you don't want to care if the remote node is erlang or java. Hope this helps.

Vlad Dumitrescu
  • 931
  • 5
  • 11
  • Hm... tried `rpc:call(server@javaapp, blah, greet, <<"Hello man">>, 500).` and `rpc:call(server@javaapp, blah, javambox, <<"Hello man">>, 500).` without luck. Which sources did you mean? JInterface? I think JInterface just somehow doesn't respond to rpc... Strange, here they say you should establish connection first: http://erlang.org/doc/apps/jinterface/jinterface_users_guide.html#id62790 – Andriy Drozdyuk Jun 29 '17 at 15:56
  • I don't have access to my PC right now, but I mean you check the source of the rpc module to see how the request and the answer are encoded. Then in java receive the message, decode it and answer it. You probably want to run the receiver loop in a thread. – Vlad Dumitrescu Jun 29 '17 at 18:51