On Tue, Dec 20, 2011 at 6:35 PM, Sean Corfield <[email protected]> wrote:
> On Tue, Dec 20, 2011 at 1:04 PM, Aaron Cohen <[email protected]> wrote:
>> The classloader that loaded RT is the one that is used by the loadLibrary
>> call in RT.loadLibrary.
>>
>> If you call System/loadLibrary from a clojure form, it will be an instance
>> of DynamicClassLoader that loads the library. This does not work.
>
> Ugh! This is why I hate class loaders... :(

If you ask me, it's quite poor design for System/loadLibrary's
behavior to depend on where it is in the source code, rather than
solely on its arguments. It should have had a two-argument overload
that takes an explicit classloader and the one argument form should
have used the system's "normal" classloader, or some sensible default.

It's clearly broken-ish behavior for foo(x); to behave differently
from bar(x); when bar's body is simply foo(x);. When foo behaves in
such a manner, bar looks referentially transparent but isn't. It
violates least surprise and makes program behavior difficult to reason
about, even beyond the difficulties one can have if foo merely has or
accepts side effects.

Making matters worse, the call-site-dependent behavior of loadLibrary
that's been described is *undocumented*. The 1.6.0 Javadocs make no
mention of classloaders at all in either the System.loadLibrary or
Runtime.loadLibrary method documentation.

Unfortunately, this questionable design choice on Sun's part is long
since impossible to fix without breaking a lot of existing code, where
by "a lot" I mean "a metric shitload", since all the hibernate,
spring, etc. frameworks would probably plotz, and that's just for
starters.

The best thing Oracle could do with that mess moving forward, in my
opinion, besides documenting all of this in the javadocs(!), would be
to deprecate the one-argument loadLibrary methods and add
non-deprecated two-argument overloads that take a ClassLoader
parameter, which if null is treated as some sensible default choice,
such as the one that loaded the class with the public static void main
(char[] args) method that was the entry point at JVM startup. The
one-argument method's behavior would be preserved for backwards
compatibility. As for loading the native chunks of specific individual
Java classes, where the one-argument method's behavior is also
desirable, I'd suggest that static{
System/loadLibrary("native_code.dll"); } get a sugared syntax (which
won't trigger deprecation warnings) such as static native
"native_code.dll"; in the section with the package and import
declarations (observe that the suggested syntax is currently a syntax
error, and requires adding no keywords, so it wouldn't disturb
backward compatibility). The simplest implementation of the
null-ClassLoader case for the new method would be just to call the
one-argument form, as that would use the classloader that loaded
Runtime, which is probably the one wanted in most circumstances other
than loading native parts of a specific class.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to