Tuesday, September 15, 2009

Loading FASLs from JAR files

Currently ABCL is a pretty decent decent Common Lisp that runs on the JVM, but we have really not started to add the necessary features which cater to making that "special" relationship easier. One of this rough sports involves how one packages ABCL applications for distribution. Since JAR files are currently the natural base unit for the distribution of JVM packages, it would make sense if one could load ABCL FASLs from JAR files. Indeed, this is an often requested feature on the armedbear-develop mailing list. Right after we published abcl-0.16.0, one of the first features to hit the trunk was the ability to load FASLs from JAR files, which we would like to explain a little bit about here.

N.B. you'll need to build ABCL from SVN trunk to use this feature.

ABCL has long had an extension to the semantics of Common Lisp PATHNAME that allowed one to specify entries of JAR files. Typing the following at an ABCL REPL:

CL-USER> (defvar *jar-entry* #p"jar:file:/home/evenson/foo.jar!/bar.abcl")

would create a reference in *JAR-ENTRY* to a PATHNAME that contained a reference in the path of the JAR in the DEVICE field, with the reminder of the PATHNAME referring to the actual JAR entry. I think these semantics were used from J to load extension functions, but they were currently unused in the ABCL codebase.

Now, *JAR* has the following parts:

CL-USER> (pathname-device *jar-entry*)


CL-USER> (pathname-name *jar-entry*)


Note that DEVICE is actually a reference to another PATHNAME at this point.

What we added in commit 12141 was the ability to load the FASL

CL-USER> (load *jar-entry*)

which would load the code compiled into the 'bar.abcl' FASL that was packed into the JAR. The ".abcl" extension is not strictly necessary: we check for entries ending in "*.abcl" and "*.lisp" for you in the same way LOAD works on the filesystem

What doesn't work yet is MERGE-PATHNAME with these special PATHNAMES. And looking for the JAR file on the current CLASSPATH. With these sort of conveniences it will be possible to include ASDF packaged systems in the JAR easily. Stay tuned!

1 comment:

  1. An update: ABCL-1.0.0 shipped with a full implementation of the ability to load its fasls from a jar file. One uses the [jar-pathname][1] syntax to specify the argument to load so for if the file '/home/user/some.jar' contained a fasl named 'example.abcl', it would be loaded via

    CL-USER> (load "jar:file://home/user/some.jar!/example.abcl")

    [1]: http://trac.common-lisp.net/armedbear/browser/trunk/abcl/doc/design/pathnames/jar-pathnames.markdown