All Manuals > LispWorks® User Guide and Reference Manual > 39 The LW-JI Package

setup-deliver-dynamic-library-for-java Function

Summary

Prepare for delivery of a dynamic library that can be loaded by Java.

Package

lw-ji

Signature

setup-deliver-dynamic-library-for-java &key init-java function asynchronous => result

Arguments
init-java
Boolean, default t.
function
A function designator for a function of no arguments.
asynchronous
Boolean, default nil.
Values
result
Always t.
Description

The function setup-deliver-dynamic-library-for-java prepares the LispWorks internal state for delivering (using deliver) a dynamic library that can be loaded from Java and use the Java interface.

setup-deliver-dynamic-library-for-java should be called just before calling deliver. It causes the call to deliver to produce a dynamic library even if the call to deliver is not given any keywords that indicate it should produce a dynamic library. When the delivered image is loaded into Java by System.loadLibrary or System.load (or the underlying Runtime methods), the host Java virtual machine is remembered by LispWorks and can be retrieved by calling get-host-java-virtual-machine, and if init-java is non-nil (the default) the Java interface is automatically initialized by a call to init-java-interface. Finally, if function is non-nil, it is then called with no arguments.

The initialization of the Java interface and calling of function are done after the rest of the initialization of LispWorks. In particular, they occur after the deliver startup function (the first argument of deliver) has returned. If the deliver startup function does not return, the Java initialization does not occur.

asynchronous controls whether the initialization is asynchronous from the Java point of view. When asynchronous is false (the default), the Java method that loads Lisp waits until Lisp has finished initialization, initialized the Java interface and function (if non-nil) has been called and returned. When asynchronous is true, the loading method returns immediately and LispWorks initializes asynchronously.

In the asynchronous case, calls from Java to Lisp (using methods in the com.lispworks.LispCalls class) may happen before Lisp is ready. Such calls are blocked until Lisp is ready, or 50 seconds have passed. If Lisp is not ready within 50 seconds, you will get an exception. It is possible to check if Lisp is ready by using com.lispworks.LispCalls.waitForInitialization.

There is a minimal example of delivering LispWorks for Java in:

(example-edit-file "java/lisp-as-dll/README.txt")
Notes

function is intended for performing Java-specific initialization after the Java interface has been initialized, including any initialization that requires the Java interface (which therefore cannot be done by the deliver startup function).

setup-deliver-dynamic-library-for-java works by setting up and exporting the C symbol JNI_OnLoad, which the loading methods in Java invoke. If you want to export your own JNI_OnLoad, you must not use setup-deliver-dynamic-library-for-java.

The function get-host-java-virtual-machine can be used to get the host Java virtual machine. In the synchronous case (the default), get-host-java-virtual-machine returns nil when called from the deliver startup function (first argument to deliver), because Lisp did not receive the Java virtual machine yet. In the asynchronous case, get-host-java-virtual-machine returns the virtual machine from the beginning.

A non-Java program can also load a dynamic library that was created by delivering with setup-deliver-dynamic-library-for-java. In this case, the Java interface is not initialized automatically, function is not called, and get-host-java-virtual-machine returns nil. get-host-java-virtual-machine can be used as predicate to tell whether the loading was done from a Java program or not.

If you want initialization that happens only when loaded by Java but not otherwise and you need this to happen before the Java interface is initialized, the easiest approach is to pass nil for init-java and pass, as function, a function that does your initialization and before calling init-java-interface. For example:

(setup-deliver-dynamic-library-for-java
 :init-java nil
 :function #'(lambda ()
               (my-java-pre-inits)
               (init-java-interface)
               (my-java-post-inits)))

If init-java is nil, you cannot use the Java interface until you call init-java-interface, as in the example above. The call to init-java-interface in this case can happen much later than the initialization, but note that calls from Java to Lisp that happen without checking if Lisp is ready will hang, and get an exception after 50 seconds.

In the asynchronous case with nil for init-java, init-java-interface can be called from the deliver startup function or later.

setup-deliver-dynamic-library-for-java modifies the way that init-java-interface looks for the virtual machine. In particular, you can call init-java-interface without specifying the Java virtual machine as in the example above, and init-java-interface will use get-host-java-virtual-machine to find it.

When init-java is true (the default), you can use setup-java-interface-callbacks to set some of the callbacks that in other situations you would pass to init-java-interface. setup-java-interface-callbacks should be called inside function, so they happen after the initialization of the Java interface.

LispWorks dynamic libraries that were delivered without using setup-deliver-dynamic-library-for-java can be loaded into Java, but to use the Java interface init-java-interface must be called with the Java virtual machine. It requires some expertise to pass the virtual machine to Lisp.

See also

init-java-interface
get-host-java-virtual-machine
setup-java-interface-callbacks
15.7 Loading a LispWorks dynamic library into Java


LispWorks® User Guide and Reference Manual - 01 Dec 2021 19:30:46