Useful macro for the Java foreign interface
I meant to send the macro below some time ago, after I started to use the java foreign interface.
The java-callers is just a helper function.
I have found the macro quite useful to avoid redundancies in the code and collects java class methods.
See the 2 examples below.
See below:
(use-package :lw-ji)
#-JVM (progn
(init-java-interface :jvm-library-path *jdk-9.0.4.jdk* :java-class-path *java-class-paths*)
(push :JVM *features*))
(init-java-interface :jvm-library-path *jdk-9.0.4.jdk* :java-class-path *java-class-paths*)
(push :JVM *features*))
(defmethod java-callers ((java-callers list))
(mapcar #'(lambda (caller-spec)
(if (stringp caller-spec)
(list (intern (string-upcase caller-spec)) caller-spec)
caller-spec))
java-callers))
(defmacro java-interface (class-definitions constructor callers)
(let ((constructor-symbol (intern (string-upcase constructor)))
(java-callers (java-callers callers)))
`(progn (import-java-class-definitions ,class-definitions)
(when ,constructor
(define-java-constructor ,constructor-symbol ,class-definitions))
(when ',callers
(define-java-callers ,class-definitions
,@java-callers)))))
(mapcar #'(lambda (caller-spec)
(if (stringp caller-spec)
(list (intern (string-upcase caller-spec)) caller-spec)
caller-spec))
java-callers))
(defmacro java-interface (class-definitions constructor callers)
(let ((constructor-symbol (intern (string-upcase constructor)))
(java-callers (java-callers callers)))
`(progn (import-java-class-definitions ,class-definitions)
(when ,constructor
(define-java-constructor ,constructor-symbol ,class-definitions))
(when ',callers
(define-java-callers ,class-definitions
,@java-callers)))))
;; some examples.
;; Assuming init-java-interface has been called with the various paths to java sources.
;; A class with a constructor and methods.
(java-interface "org.apache.activemq.ActiveMQConnectionFactory"
"ActiveMQConnectionFactory"
("getClientID"
"setClientID"
))
"ActiveMQConnectionFactory"
("getClientID"
"setClientID"
))
;; A change to the method name “close” so that it does not conflict with an existing lisp function.
(java-interface "javax.jms.Connection"
nil
("start"
"stop"
"createSession"
(closeconnection "close")))
nil
("start"
"stop"
"createSession"
(closeconnection "close")))