[armedbear-devel] ABCL packaging ASDF system in jars (was Re: Disabling "built-in" output translation)

Alessio Stalla alessiostalla at gmail.com
Tue May 17 21:29:47 UTC 2011


On Tue, May 17, 2011 at 10:52 PM, Mark Evenson <evenson at panix.com> wrote:
> On 5/17/11 10:24 PM, Alessio Stalla wrote:
> […]
>>
>> a. CLASSPATH (the listing of directories and jar files where to look
>> for classes) is not a runtime concept; it's only a variable
>> (environment variable or command line switch) used to init the JVM's
>> default class loader. Once the JVM is started, CLASSPATH doesn't make
>> any more sense.
>> b. At runtime there's a hierarchy of class loaders, that, without
>> going too much in detail, define a sort of limited virtual filesystem.
>> Resources in that filesystem might come from plain files, from
>> contents of jars, from the network, from memory... So,
>> classpath:foo.jar!/bar does not make much sense: the fact that bar
>> comes from foo.jar is no longer important (and possibly not even known
>> anymore) inside the virtual filesystem. This is not just theory, I can
>> cite at least two examples: ABCL's very own functions compiled at
>> runtime and loaded from memory, and anything running on JBoss>= 5,
>> where applications are loaded with a classloader that does not expose
>> jar files in any way. So, I would suggest simply
>> classpath:/foo/bar/baz and leave it to the classloader to go and find
>> /foo/bar/baz. This is precisely how the Spring framework does it, for
>> example[1]. What you lose is the ability to enumerate the contents of
>> the "file system": you can only ask for a resource by name and get
>> back a stream if it exists. But I don't think we currently need the
>> capability to enumerate.
>
> So, if I understand you, 'classpath:/foo/bar/baz' just means find the entry
> '/foo/bar/baz' relative to something within the classpath?

No, not exactly. "/foo/bar/baz" is an absolute path, so it's not
relative to something *within* the classloader search path; but it
*is* relative to the actual classloader. I oversimplified; there's not
a unique "virtual file system" (VFS) but a tree of them, and the root
is the classloader you consider. A classloader is the aggregation of
one or more sources (e.g. jars). Within ABCL, typically the
classloader is the one that loaded ABCL, i.e. you don't have to worry
about it and you can pretend there's a single VFS. It only becomes a
problem in a scenario where ABCL is a library shared among several
different applications (running on the same JVM): then, you would
typically have to use each application's class loader.
Relative paths are also possible; for example, you might want to load
a FASL that is "next to" another one.

> What happens if
> there are multiple classpath entries that satisfy this requirement, i.e.
> foobar.jar and barfoo.jar both contain '/foo/bar/baz'?   Doesn't a "first
> one wins" strategy create ambiguity?

Yes, it does. There is a way to detect the ambiguity and get a list of
all the resources with a given name [1]; we could decide to forbid
that situation and signal an error (when loading Lisp code). For
reference, it's not how things typically work in Java: the possibility
of ambiguity is accepted, and while it is a source of bugs, it's also
voluntarily exploited in certain scenarios to override classes without
touching the containing jars. Granted, with a dynamic language, that
becomes pretty much irrelevant. That said, my main points are:
 - you can't expect to always being able to detect which jar a
resource comes from (or if it comes from a jar at all)
 - even if you could determine the jar, you could only check it
afterwards, i.e. it's not "find jar, then look for resource" but "find
resources, then choose the one from the right jar". Otherwise, the
classpath: prefix is misleading. But then, what does "the right jar"
mean if you're no longer using absolute paths? Suppose you have
classpath:my.jar!/foo. What if the classloader knows both foo from
/home/alessio/my.jar and foo from /usr/lib/my.jar? Which one is the
right one?

[1] http://download.oracle.com/javase/1.4.2/docs/api/java/lang/ClassLoader.html#getResources%28java.lang.String%29

Alessio




More information about the armedbear-devel mailing list