wiki:JavaFfi

Version 5 (modified by astalla, 13 years ago) (diff)

--

Java Foreign Function Interface

This page describes the API offered by ABCL to call arbitrary Java code. Unless otherwise noted, all the symbols are exported from the JAVA package, which is used by CL-USER.

The basics

The core API is based on Java reflection. Some operators come in two flavors: a concise one that leaves some things to be computed by ABCL at runtime, and a more efficient and verbose one, which is mostly a direct translation of the Java reflection API.

Definitions

  • Java class designator: either a string denoting the fully qualified name of a Java class, such as "java.lang.String", or a Java class metaobject, that is, an instance of java.lang.Class, for example as returned by the function jclass.
  • Java method designator: in the context of Java method invocations, either a Java method metaobject (an instance of java.lang.reflect.Method), or a string representing the name of the method, for example "toString".

Function JCALL, JCALL-RAW

Syntax:

jcall method instance &rest args => object

jcall-raw method instance &rest args => a JAVA-OBJECT

Arguments and Values:

method -- a Java method designator, that is, either a Java method metaobject (an instance of java.lang.reflect.Method), or a string representing the name of the method, for example "toString".

instance -- the receiver object target of the method call. If the method is static, this argument is ignored and can be NIL.

args -- the arguments passed to the method.

Description:

Reflectively calls a method and returns the result of the call. If method is a string, ABCL dynamically examines the class of instance to search for the most specific applicable method with that name, following Java overload resolution rules. If method is a Java method metaobject, it is called directly.

jcall translates the result to a Lisp object if possible. jcall-raw performs no translation and always returns the original Java object.

Examples:

(jcall "toString" T) => "COMMON-LISP:T"
(jcall-raw "toString" T) => #<java.lang.String COMMON-LISP:T {21B42F}>
(jcall "compareTo" 12 24) => -1 ;;Resolves the method at runtime: inefficient but concise
(jcall (jmethod "java.lang.Comparable" "compareTo" "java.lang.Object") 12 24) => -1 ;;Same as above, but avoiding dynamic method resolution

Function JCLASS

Syntax:

jclass name-or-class-ref &optional class-loader => a Java class metaobject

Arguments and Values:

name-or-class-ref -- a Java class designator (see Definitions).

class-loader -- the classloader to use to resolve the class. Refer to the section Class resolution and loading.

Description:

Returns a reference to the Java class designated by name-or-class-ref. If the class-loader parameter is passed, the class is resolved with respect to the given ClassLoader?.

Examples:

(jclass "java.util.LinkedList") => #<java.lang.Class class java.util.LinkedList {11B50A1}>

Function JSTATIC, JSTATIC-RAW

Syntax:

jstatic method class &rest args => object

jstatic-raw method class &rest args => JAVA-OBJECT

Arguments and Values:

method -- a Java method designator.

class -- a Java class metaobject.

args -- the arguments passed to the method.

Description:

Reflectively calls a static method and returns the result of the call. (jstatic method class args) is equivalent to (jcall (jmethod class method) nil args) when method is a string, and to (jcall method nil args) when method is a Java method metaobject (class is thus ignored in that case). Similarly for the -raw variants.

jstatic translates the result to a Lisp object if possible. jstatic-raw performs no translation and always returns the original Java object.

Examples:

(jstatic "getRuntime" "java.lang.Runtime") => #<java.lang.Runtime java.lang.Runtime@1ef3212 {C07527}>
(jstatic-raw "getRuntime" "java.lang.Runtime") => #<java.lang.Runtime java.lang.Runtime@1ef3212 {156D7C8}>
(jstatic "getRuntime" (jclass "java.lang.Runtime")) => #<java.lang.Runtime java.lang.Runtime@1ef3212 {C8E4DE}>
(jstatic (jmethod "java.lang.Runtime" "getRuntime") nil) => #<java.lang.Runtime java.lang.Runtime@1ef3212 {129DF8A}>

Class resolution and loading

TODO

High-level constructs

TODO

CLOS integration

TODO

A quick "cheat sheet":

(This is a very rough draft thrown together from an email by Alessio Stalla to the mailing list. It will be gradually superseded by the documentation above.)

(jclass <class name>)
gives you a Java class
(jmethod <java class> <method names> <&rest argument types>)
gives you a method
(jconstructor <java class> <&rest argument types>)
a constructor
(jnew <constructor> <&rest arguments>)
instantiates a new Java object
(jcall <method> <object> <&rest arguments>)
calls a method
jstatic
to access static fields and methods.
jfield
to access fields.
jproperty-value and (setf jproperty-value)
access "properties" following the Java Bean convention (setXXX and getXXX).

That's almost all; there is some more advanced stuff (e.g. manipulating Java arrays).

You can find most or all of this stuff inside Java.java. It's not documented but quite readable.

For example code that uses the Java FFI API, see the examples.

(The rest of the page is taken from the symbols and comments in Java.java. Still needs a lot of work, obviously.)

register-java-exception exception-name condition-symbol => T or NIL

Registers the Java Throwable exception-name as the condition designated by condition-symbol.

unregister-java-exception exception-name => T or NIL

Unregisters the Java Throwable exception-name previously registered by register-java-exception.

jfield` class-ref-or-field field-or-instance &optional instance value jfield-raw class-ref-or-field field-or-instance &optional instance value

Retrieve or modify a field in a Java class or instance.

Supported argument patterns:

class-ref field-name
Retrieve the value of a static field.
class-ref field-name instance-ref
Retrieve the value of a class field of the instance.
class-ref field-name primitive-value
Store primitive-value in a static field.
class-ref field-name instance-ref value
Store value in a class field of the instance.
class-ref field-name nil value
Store value in a static field (when value may be confused with an instance-ref).
field-name instance
Retrieve the value of a field of instance. The class is derived from instance.
field-name instance value
Store value in a field of instance. The class is derived from instance.

jconstructor class-ref &rest parameter-class-refs => constructor-ref

Returns a reference to the Java constructor of class-ref with the given parameter-class-refs.

jmethod class-ref method-name &rest parameter-class-refs => method-ref

Returns a reference to the Java method method-name of class-ref with the given parameter-class-refs.

jstatic method-ref class-ref &rest args => result jstatic-raw method-ref class-ref &rest args result

jnew constructor &rest args => object

Invokes the Java constructor constructor with the arguments args

jnew-array element-type &rest dimensions => array-object

Creates a new Java array of type element-type, with the given dimensions.

jarray-ref java-array &rest indices => object

Dereference the Java array java-array using the given indices, coercing the result into a Lisp type, if possible.

jarray-ref-raw java-array &rest indices => object

Dereference the Java array java-array using the given indices. Does not attempt to coerce the result into a Lisp type.

jarray-set java-array new-value &rest indices => new-value

jcall method-ref instance &rest args => result jcall-raw method-ref instance &rest args => result

jcall calls makeLispObject() to convert the result to an appropriate Lisp type. jcall-raw does no type conversion. The result of the call is simply wrapped in a JavaObject?. (This is true for all the -raw variants.)

make-immediate-object object &optional type => object

java-object-p object => T or NIL

Returns T if object is an instance of JavaObject? (as opposed to a Lisp object).

jobject-lisp-value java-object => lisp-object

Returns the Lisp object corresponding to (wrapping?) the JavaObject?. I.e. return JavaObject.getInstance(arg.javaInstance(), true);

jcoerce object intended-class => java-object

Attempts to coerce object into a JavaObject? of class intended-class. Raises a type-error if no conversion is possible.

%jget-property-value java-object property-name

Use jproperty-value instead.

%jset-property-value java-object property-name value

Use (setf jproperty-value) instead.

jrun-exception-protected closure