[…]
Is there an elegant way to have ABCL load Lisp code from a JAR file in the Java CLASSPATH?
[…]
- If resolution of "foo.jar" fails on the filesystem, iterate through
the CLASSPATH to match the name.
I don't agree on point 2. Ideally I would like to keep the two points distinct, i.e. cook up another pseudo-pathname - say, "classpath:/a/b/foo.abcl" - specifically for classpath resources. The reason is that I see two very distinct usages of this functionality:
- (classpath) is what applications would normally use: just ensure
that resources are in the classpath, ignore where they are physically located;
- (explicit jar path) would normally be used by ABCL itself in order
to correctly resolve relative paths, load internal stuff, and similar.
I accept that there is a conceptual difference between a java CLASSPATH and an explicit reference to a jar which.
Being more strict, I suppose we could say that translated into Lisp a Java CLASSPATH is a proper list of pathnames which may either be references to JAR files or directories.
Thus CLASSPATH="/a/b/foo.jar:bar.jar:baz"
would be translated into Lisp (using the "jar:" syntax as specified in java.net.JarUrlConnection): (#p"jar:file:/a/b/foo.jar!/" #p"jar:file:bar.jar!/" #p"baz/")
Since one can access arbitrary resources from the CLASSPATH, I would propose we declare that a PATHNAME NAMESTRING beginning with "classpath:" refers to an item that should be resolved via the CLASSPATH. I think I can include wildcards here in the implementation (but I have to think through more fully through this) so
(truename #p"classpath:jar:file:*/foo.jar!/") for the previous CLASSPATH would return #p"classpath:jar:file:/a/b/foo.jar!/"
And (truename #p"classpath:baz/foo.text") if there were a directory "baz/" on the local filesystem under "/a/b/c" would return #p"classpath:/a/b/c/baz/foo.text"
Another subtlety to consider later is that JAR manifests [can apparently modify the classpath for sources loaded from that JAR][1]. Not sure what this would mean at the moment.
[1]: http://en.wikipedia.org/wiki/Classpath_%28Java%29#Setting_the_path_in_a_Mani...
I'd also like to think through the ramifications of packaging Lisp applications via ASDF definitions in JAR files. It would be nice for one ASDF system needing another one could have some mechanism to specify this relationship without knowing the exact JAR that this dependency entails. But since such dependencies are currently specified by symbolic links in a directory which won't work with JARs, we probably need to extend ASDF in some manner. It would be nice to crib some Java implementation, but I don't know anything that is standardized. Managing CLASSPATH dependencies in Java is a generally considered weakness. Java 7 was supposed to help with this via superpackages and/or modules, but that is in an uncertain future.