Gargoyle is an Emacs module
Gargoyle is a module to embed a Java VM in a running Emacs instance. It is facilitated by Emacs 25 dynamic modules.
A bridge to Java is provided.
Here is a simple demonstration of the Emacs API.
;; create a new list
(let ((my-list (gg-new 'java.util.ArrayList)))
;; Java methods start with /
(/add my-list "some string")
(/add my-list 42)
;; prints "There are 2 elements in the list"
(message "There are %d elements in the list" (/size my-list))
;; prints a string representation of the list: [some string, 42]
(message "%s" (gg-toString my-list)))
The JVM instance can be controlled as described below.
- =gg-java-start=
Start the JVM. Gargoyle supports one global instance of a running JVM. The JVM cannot be started more than once per process.
- =gg-java-stop=
Stop the JVM.
- =gg-java-running=
Query whether the JVM is running.
- =gg-jni-version=
Query the JNI version supported in the JVM.
Class access and object creation are the basic “entry points” for an application.
- =gg-find-class= class-name
Find a class given it’s fully qualified name.
- =gg-new= class-name-or-object &rest ctor-args
Create a new instance of the given class using the passed args to match a constructor method.
- =gg-get-field= object field-name
Retrieve the value of the named field of the given object.
- Example: Creating new Java objects:
;; create a new instance of Object
(let ((obj-class (gg-find-class 'java.lang.Object)))
(gg-new obj-class))
;; create a new ArrayList with an initial capacity of 10
(let ((arraylist-class (gg-find-class 'java.util.ArrayList)))
(gg-new arraylist-class 10))
- =gg-objectp= object
Return t if object is a Java object.
- =gg-arrayp= object
Return t if object is a Java array.
- =gg-toString= object
Obtain the string representation of the given object as a Lisp string.
There are several indicators:
- The
load-suffixes
variable will contain “.so”. - The
build-files
variable will contain “emacs-module.so”.
Note that Emacs must be built with the --enable-modules
option to
enable this feature.
Either your Emacs doesn’t support dynamic modules or
gargoyle-dm.so
is not reachable via load-path
.
“Cannot load file /…/gargoyle-dm.so: libjvm.so: cannot open shared object file: No such file or directory”
It is assumed that the gargoyle-dm.so
is reachable via
load-path
.
If the shared library cannot be loaded into the Emacs runtime,
verify that the Java libraries are in LD_LIBRARY_PATH
:
% ldd gargoyle-dm.so linux-vdso.so.1 (0x00007ffd641f7000) libjvm.so => not found libjsig.so => not found % export LD_LIBRARY_PATH=$JAVA_HOME/jre/lib/amd64/server % ldd gargoyle-dm.so linux-vdso.so.1 (0x00007ffd081f0000) libjvm.so => $JAVA_HOME/jre/lib/amd64/server/libjvm.so (0x00007f719055b000) libjsig.so => $JAVA_HOME/jre/lib/amd64/server/libjsig.so (0x00007f7190358000) libm.so.6 => /usr/lib/libm.so.6 (0x00007f7190021000) libdl.so.2 => /usr/lib/libdl.so.2 (0x00007f718fe1c000) libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007f718fbff000) libc.so.6 => /usr/lib/libc.so.6 (0x00007f718f85e000) /usr/lib64/ld-linux-x86-64.so.2 (0x00005598ec170000)
Running cask
in a shell doesn’t work properly when the
INSIDE_EMACS
environment variable is set. You can unset it.
You will also have to unset EMACS
as it will override the value
in the Makefile
.
- The
modules/mod-test/
subdirectory in the Emacs source tree has an example of writing a dynamic module. - emacs-module.h
- Java Invocation API
- JNI Reference
- JVM TI
- Add aliases for most common classes (Thread, Class, List, etc)
- Could run through most of the JDK or include a customizable list