Version 2 (modified by Mark Evenson, 11 years ago) (diff)


To implement Java interfaces in Lisp, the simplest function is

(defun jinterface-implementation (interface &rest method-names-and-defs)
  "Creates and returns an implementation of a Java interface with
   methods calling Lisp closures as given in METHOD-NAMES-AND-DEFS.

   INTERFACE is either a Java interface or a string naming one.

   METHOD-NAMES-AND-DEFS is an alternating list of method names
   (strings) and method definitions (closures).

   For missing methods, a dummy implementation is provided that
   returns nothing or null depending on whether the return type is
   void or not. This is for convenience only, and a warning is issued
   for each undefined method."

Thus, for the Java interface compiled into a Java class, and on the current classspath (see JAVA:ADD-TO-CLASSPATH see the BankAccount? example in the 'java-interfaces'.

A more full featured API can be found via the generic function JAVA:JMAKE-PROXY as follows:

(defgeneric jmake-proxy (interface implementation &optional lisp-this)
  Returns a proxy Java object implementing the provided interface(s) using methods implemented in  
  Lisp - typically closures, but implementations are free to provide other mechanisms. You can pass
  an optional 'lisp-this' object that will be passed to the implementing methods as their first
  argument. If you don't provide this object, NIL will be used. The second argument of the
  Lisp methods is the name of the Java method being implemented. This has the implication that
  overloaded methods are merged, so you have to manually discriminate them if you want to. 
  The remaining arguments are java-objects wrapping the method's parameters."

The four implementations of this method have the follow signatures:

(defmethod jmake-proxy (interface invocation-handler &optional lisp-this)
  "Basic implementation that directly uses an invocation handler."
  [ …]
(defmethod jmake-proxy (interface (implementation function) &optional lisp-this)
  "Implements a Java interface forwarding method calls to a Lisp function."
(defmethod jmake-proxy (interface (implementation package) &optional lisp-this)
  "Implements a Java interface mapping Java method names to symbols in a given package. 
   javaMethodName is mapped to a JAVA-METHOD-NAME symbol. An error is signaled if no
   such symbol exists in the package, or if the symbol exists but does not name a function."
(defmethod jmake-proxy (interface (implementation hash-table) &optional lisp-this)
  "Implements a Java interface using closures in an hash-table keyed by Java method name."