wiki:JavaFfi/RuntimeClass

Version 4 (modified by Alessiostalla, 8 years ago) (diff)

--

Defining Java classes in Lisp (aka runtime-class)

Rationale

Contrary to most other Lisp implementation, ABCL is deeply intertwined with its hosting platform, the JVM. It is an important design goal for ABCL not only to coexist with Java and other languages, but to actually interoperate with them at a deep level. This includes providing components to be consumed by foreign libraries, such as callbacks, event listeners, configuration objects, et cetera.

Generally, when possible, it's advisable to use interfaces rather than concrete classes for that purpose (see Implementing Java interfaces in Lisp). However, not all foreign libraries are properly designed; and sometimes a concrete class is needed for valid reasons (e.g. to inherit important functionality). The "runtime-class" functionality presented here addresses those use cases.

History

ABCL used to have a form of runtime-class functionality in its early days. It was implemented using the popular ASM library. At one point, though, it was disabled in order to eliminate the need for external dependencies. It stayed disabled for quite a long time - enough for getting affected by bit rot with a high probability.

Between late 2011 and early 2012, part of the functionality was resurrected by Alessio Stalla, this time completely in Lisp with no external dependencies. This was made possible by ABCL's class file writer, an internal library coded some time earlier by Erik Huelsmann to better separate concerns in the compiler. The class file writer was slightly extended in order to make it generate Java 1.5 annotation metadata.

The API has been inspired by the original, but has been changed in some places.

The define-java-class macro

This functionality is not yet implemented. The java:define-java-class macro is the high-level entry point to the runtime-class functionality. It takes a specification of a Java class and expands into code for generating such a class at runtime. If the macro is expanded as part of file compilation, it (optionally?) generates the class at compile-time, dumps it to a file, and expands into code for loading the class from that file.

The jnew-runtime-class function

The java:jnew-runtime-class is the lower-level entry point to the runtime-class functionality. It takes a specification of a Java class and generates the bytecode for it, optionally saving it to a file (not yet implemented) and (not yet optionally) loading it into the current JVM.