Skip to content

A library for Erlang/Java Interoperability via Erlang's rpc module

License

Notifications You must be signed in to change notification settings

joedevivo/gen_java

Repository files navigation

gen_java

A library for Erlang/Java Interoperability via Erlang's rpc module

This project generates two artifacts:

  • a .jar file that includes all you need to build your own java project that can respond to erlang's rpc:call/4 function
  • an erlang dependency that provides a gen_java server that you can implement via parse transform.

Java Face

Here's what you need to know on the java side of things

If you want to expose a java method to erlang, it needs to be public, static and have argument and return types from the OTP JInterface library.

For reference, the JInterface package reference can be found here

Maven

You should be able to pull from Maven Central pretty soon with this:

<dependency>
    <groupId>com.devivo</groupId>
    <artifactId>gen_java</artifactId>
    <version>0.1.0</version>
</dependency>

Erlang

Configure gen_java in your sys.config

{gen_java, [
    {modules, [
        {my_module, [
            {jar, "/path/to/jar/file.jar"},
            %% Default thread count is 10.
            %% this is how big the java thread pool is
            {thread_count, 10}
        ]}
    ]}
]}

Create your my_module

-module(my_module).

-compile({parse_transform, gen_java_parse_transform}).

Start your gen_java server

On your own

Start gen_java with my_module:start_link() or my_module:start(). Those functions are free with the parse transform, so don't worry about it.

Or from a supervisor

{my_module,
    {my_module, start_link, []},
    permanent, 5000, worker, [my_module]},

Optional: Init Hollaback

Don't call it a callback, 'cause it's not a behaviour. You can add an init/1 hollaback to your module to do some initialization of your JVM node. The only trick is that you have to use rpc:call/4 since the gen_server isn't started yet.

-spec init(atom()) -> ok.
init(Nodename) ->
    rpc:call(Nodename, 'com.yourcompany.package', 'init', [<<SomeState>>]).

Call Java Methods!

my_module:call('com.whatever.package.Class', 'methodName', ['arg', <<"other arg">>]) will return the value you want!

Worried about waiting forever? There's a call/4 that allows you to specify a timeout.

Optional: Add a convenience wrapper function

-spec method_name(atom(), binary()) -> my_return_type() | gen_java:badrpc().
method_name(Atom, Binary) ->
    call('com.whatever.package.Class', 'methodName', [Atom, Binary]).

my_module:call/3 will have the same dialyzer return type as rpc:call/4

For fun, We provide gen_java:badrpc() for you to use in addition to your expected return type. This will let you just append | gen_java:badrpc() to your spec and then fuggedaboudit.

easy peasy

Provided Java Functions:

%% @doc java.lang.System.getProperties()
-spec system_properties() -> [{atom(), binary()}].
java:system_properties/0

%% @doc java.lang.System.getenv()
-spec system_env() -> [{binary(), binary()}].
java:system_env/0

%% @doc command line $JAVA_OPTS. (e.g. -Xmx512m)
-spec input_arguments() -> binary().
java:input_arguments/0

About

A library for Erlang/Java Interoperability via Erlang's rpc module

Resources

License

Stars

Watchers

Forks

Packages

No packages published