CL+J is a JNI based interface to a Java Virtual Machine through CFFI. It targets safe, exact and complete access to Java from Common Lisp with as high integration as possible of the Java and CL respective runtime environments (especially at the condition/exception level).
CL+J uses a set of reader dispatch-macros to simplify the Java code interface. In CL+J the traditional "Hello World!" becomes:
(#_System.out.println (jstr "Hello World!"))
Printing the list of System properties to the Java standard output stream is simply:
(#_list (#_System.getProperties) #?System.out)
The current version of CL+J is 0.4.
You can download it from here: cl+j-0.4.tar.gz
CL+J 0.4 works fully on MKCL on any platforms supported by MKCL (Linux/x86 (32bits), Linux/x86_64 (64 bits), Windows XP (Win32) or later, Windows 7 (Win64) or later) with either Java 6, 7 or 8.
Further CL implementations will be tested in turns subsequently.
Co-existence with such an elaborate set of foreign code as a full Java Virtual Machine certainly is, constitutes pretty much the ultimate acid test for a Common Lisp Foreign Function Interface subsystem. Only a few Common Lisp environments can meet such a challenge. Here is a non-exhaustive list of CL systems known to work with CL+J 0.3, in decreasing order of reliability:
ManKai Common Lisp (MKCL): CL+J 0.3 works fully on MKCL on any platforms supported by MKCL (Linux/x86 (32bits), Linux/x86_64 (64 bits), Windows XP (Win32), Windows 7 (Win64)). No special JVM option is required on any of the widely available JVMs such as Oracle's HotSpot, IcedTea or IBM's JVM. MKCL is the reference platform for the development and debugging of CL+J.
Clozure Common Lisp (CCL): CL+J 0.3 works on CCL for Linux/x86 or Linux/x86_64 if IBM's JVM is used with option -Xrs but will crash during JVM initialization without that option or if Oracle's HotSpot or IcedTea is used. CL+J 0.3 seems to work fully on CCL for Windows XP (Win32) or Windows 7 (Win64) with any of the widely available JVMs (Oracle's HotSpot, IBM's JVM) and this without any special JVM option. CL+J 0.3 may work on CCL for some the other platforms supported by CCL (such as Mac OS X, Solaris, ...). Note that on CCL the reader macro #_ is replaced by #] since the former is already used by CCL for its foreign function interface.
ECL: CL+J 0.3 should work on ECL for Linux (32 bits or 64 bits) as long as the foreign code (JVM included) behaves strictly according to ECL's requirements on Unix signal masks. Such a compliance on the part of the foreign code is not very likely. CL+J 0.3 should most probably (but this has not been tried) work fully on ECL for Windows XP (Win32) or Windows 7 (Win64) with any of the widely available JVMs (Oracle's HotSpot, IBM's JVM) and this without any special JVM option.
Steel Bank Common Lisp (SBCL): CL+J 0.3 does NOT work reliably on SBCL for Linux/x86 or Linux/x86_64 due to SBCL's inability to handle Unix signals properly in the presence of foreign threads. The problem is clearly observable under SLIME since SLIME generates a fairly intense signal activity through timers. In such a context SBCL crashes into its low level debugger LDB claiming memory corruption within 20 to 30 minutes of even unattended use. On Windows XP (Win32) SBCL is still considered "experimental" and does not build with thread support by default, CL+J 0.3 may work on it but has not been tried. A port of SBCL on Win64 does not seem to exist officially yet (2012/07/22) but is in progress according to the SBCL web site.
CFFI 0.10.6 which in turn requires:
alexandria (2008-08-02 or later)
You need to specify the location of your JRE like this:
(defvar cl-user:*jre-home* "/some/path/leading/to/your/jre")
or tell the exact location of your JVM shared library like this (would end in jvm.dll on MS-Windows):
(defvar cl-user:*jvm-path* "/some/path/to/your/libjvm.so")
You should also provide some options to be read at JVM creation time with something like this:
(defvar cl-user:*jvm-options* '("-Djava.class.path=/your/path/to/cl_j.jar:/and/maybe/some/other.jar"))
or, if you need more options to be passed during initialization of the JVM:
(defvar cl-user:*jvm-options* '("-Djava.class.path=/your/path/to/cl_j.jar:/and/maybe/some/other.jar" "-Xrs"))
Now that the context is set, you can ask ASDF to compile and load CL+J this way:
(asdf:oos 'asdf:load-op :cl+j)
You are then ready to initialize the Java VM by calling:
At this point Java is fully accessible.
Proper documentation of the CL+J public interface has yet to be written. In the meantime you could have a look at the code in the demos directory.
Currently the small programs in the demos directory should be loaded from a package that uses package "CL+J" like this:
CL-USER> (use-package :cl+j)
CL-USER> (load "demos/hello_swing.lisp")
Document the public interface of CL+J.
2017-01-08: CL+J 0.4 released
2012-07-22: CL+J 0.3 released.
2011-06-01: CL+J 0.2 released.
2009-03-19: CL+J 0.1 released.