Authors: Lars-Ake Fredlund (lfredlund@fi.upm.es).
JavaErlang is a library that attempts to facilitate the communication between Java and Erlang nodes, implemented as an additional layer on top of the JInterface Java interface. The library makes heavy use of the Java reflection capability, provided in the package java.lang.reflect.The primary functionality is that the library can automatically generate an Erlang module, from a Java class, containing functions corresponding to the constructors and methods of the Java class, and functions for accessing and modifying the attributes of the Java class.
An example:
{ok,NodeId} = java:start_node(), java:acquire_class(NodeId,'java.lang.Integer'), Int10 = java_lang_Integer:'Integer'(NodeId,10), String10 = java_lang_Integer:toString(Int10).
The above code starts a Java node, and establishes a connection to it. Then, the Java Integer class is translated into the Erlang module 'java_lang_Integer'. Next, a Java integer storing the value 10 is created, and finally a Java string representing "10" is returned.
Alternatively, the above piece of code can be written
more symbolically using calls to the java module as follows:
{ok,NodeId} = java:start_node(), Int10 = java:new(NodeId,'java.lang.Integer',[10]), String10 = java:call(Int10,toString,[]).Note that there is no need to call acquire_class to translate the Java class to an Erlang module, as this is taken care of automatically by the java:new (and java:call) functions.
To make your Java classes (and Jar files) visible to the library
the option add_to_java_classpath
should be provided to
java:start_node/1
. An example:
{ok,NodeId} = java:start_node([{add_to_java_classpath,["classes"]}]).This adds the directory
classes
to the classpath of the started Java interpreter
The JavaErlang interface automatically maps each Java Class accessed
to an Erlang module, compiles the Erlang module, and loads it.
Although not strictly needed to use the interface,
it can be helpful to know that e.g.
a Java class n1.n2.n3.c
will translated to
an Erlang module n1_n2_n3_c
.
The Erlang modules automatically generated from Java classes,
are by default stored in the
directory java_sources
and compiled modules are stored
in java_sources/ebin
. The locations of these directories
can be changed using the function start_node/1
.
After changing Java implementation, for instance, it
is a good idea to clean up or remove these directories.
null
,
the Java boolean values true and false are represented as the
corresponding atoms true
and false
,
and integer-like types and floating-point-like types are
represented as normal Erlang integers and floats. Arrays are
constructed using the normal Erlang syntax for lists and strings.
Values can be explicitely type cast using the notation
{Type,Value}
. For example, {short,5}
, {char,$a}
,
{{array,char,1},"Hello World"}
.
Java one-dimensional arrays can also be constructed
using the funcion java:list_to_array/3
.
Examples:> {ok,NodeId} = java:start_node(). {ok,9231} > False = java:new(NodeId,'java.lang.Boolean',[false]). {object,0,9231} > HelloWorldString = java:new(NodeId,'java.lang.String',[java:list_to_array(NodeId,"Hello World!",char)]). {object,2,9231} > Zero = java:new(NodeId,'java.lang.Integer',[0]). {object,3,9232} > java:call(Zero,intValue,[]). 0 > java:string_to_list(java:new(NodeId,'java.lang.String',[{{array,char,1},"Hello World"}])). "Hello World" > java:string_to_list(java:new(NodeId,'java.lang.String',["Hello World"])). "Hello World"
> {ok,NodeId} = java:start_node(). {ok,9231} > Zero = java:new(NodeId,'java.lang.Integer',[0]). {object,3,9232} > java:call(Zero,equals,[0]). true > java:call(Zero,equals,[2]). false > java:call(Zero,equals,[0.0]). false
Primitive values returned from a method are represented as normal Erlang values, whereas objects are returned as objects.
> {ok,N} = java:start_node(). {ok,923} > Zero = java:new(N,'java.lang.Integer',[0]). {object,3,923} > java:call(Zero,intValue,[]). 0Since intValue returnes an int, a primitive type, the library lets the corresponding Erlang function return an Erlang integer.
{ok,NodeId} = java:start_node(), try java:new(NodeId,'hola',[]) catch {java_exception,Exc} -> io:format("Exception is of type ~p~n",[java:getClassName(Exc)]), java:print_stacktrace(Exc) end.
The option java_exception_as_value
(which can be passed
as an argument to java:start_node/1
) determines whether Java exceptions are
indeed returned as exceptions (the default), as shown in code excerpt above,
or whether they are returned as Erlang values (when the option is set
to true).
An object of class "c" can be
created by calling java:new(c,Args)
,
where Args
is the list
of arguments of the constructor.
{ok,NodeId} = java:start_node(), I2 = java:new(NodeId,'java.lang.Integer',[2]).Alternatively, the Erlang module corresponding to a Java class provides functions to directly call the constructor. An example:
{ok,NodeId} = java:start_node(), java:acquire_class(NodeId,'java.lang.Integer'), I2 = java_lang_Integer:'Integer'(NodeId,2).
A public method "m" of a Java object "o" of class "c" can be
called using the function call
java:call(o,m,Args)
(or java:get_static(c,m,Args)
if it is
a static, i.e., class method) where Args
is the list
of arguments of the method.
{ok,NodeId} = java:start_node(), I2 = java:new(NodeId,'java.lang.Integer',[2]), I2b = java:new(NodeId,'java.lang.Integer',[2]), true = java:call(I2,equals,[I2b]).
This code excerpt creates two Java Integers (of value 2),
and checks that the method equals
returns true.
{ok,NodeId} = java:start_node(), I2 = java:new(NodeId,'java.lang.Integer',[2]), I2b = java:new(NodeId,'java.lang.Integer',[2]), true = 'java_lang_Integer':equals(I2,[I2b]).
A public field "f" of a Java object "o" of class "c" can be
accessed using the function call
java:get(o,f)
(or java:get_static(c,f)
if it is a class field).
Similarly, the call java:set(o,f,v)
is used to assign the value
v
to the field (and java:set_static(o,f,v)
is used
for class fields).
{ok,NodeId} = java:start_node(), Err = java:get_static(NodeId,'java.lang.System',err), java:call(Err,println,[{int,2}]).
This code excerpt retrieves the Java standard error stream from
the field err
in java.lang.System
, and prints
the integer 2.
Alternatively, the Erlang module corresponding to a Java class
provides the functions get_f
and set_f
for accessing and
modifying a field f
; these functions can be called directly
from Erlang code.
Currently only the public methods and fields of Java classes
are accessible. It is likely that in the future we will
provide an option to permit calling methods that are
protected
, i.e., methods callable only from inside a Java package.
java_timeout
will be thrown.
Note that timeouts can be set on a per-process, per-call basis, using
the function set_timeout/1
.
reset/0
function.
Generated by EDoc, Oct 26 2011, 10:30:20.