HTC J より送信

----- Reply message -----
送信者: "Alex Fowler" <alex.murat...@gmail.com>
宛先: <clojure@googlegroups.com>
件名: [BUG?] loading Clojure source files from various data sources (classloading)
日付: 木, 5月 21日, 2015年 20:25
Hello!
I am developing a Java application where Clojure is used as a library. The 
application is required to load sources (including Clojure sources) from 
arbitrary locations in filesystem, internet and maybe a dozen other places. 
Hence I have developed corresponding classloaders for that, which properly 
implement the required ClassLoader methods.
Loading Clojure sources is realized via this approach:
Compiler.LOADER.alterRoot(getMyClassLoader(), ...);          // changing the 
LOADER to my chain of classloaders
IFn require = Clojure.var("clojure.core", "require");
require.invoke(Clojure.read("example.namespace"));
where the contents of the "example.namespace" are:
(ns example.namespace
(:require [other.example.namespace :as other])))
I have figured that the loading happens with RT.load() which delegates to 
RT.loadResourceScript(), so I just alter the Compiler.LOADER so that 
RT.baseLoader() returns my classloaders. And in my classloaders I simply have 
to override the getResourceAsStream and all works!  The namespace 
example.namespace starts loading ok. It successfully loads the whole 
clojure.core and then begins to process the first require - the 
other.example.namespace. And this is where something bad happens.
It appears to be that the (require) inside the ns form in the example.namespace 
uses not the RT.load() method, but Compiler.load()where on line 7210 the 
Compiler.LOADER, which by that moment points to the correct classloader created 
by me, gets replaced by RT.makeClassLoader()where the current RT.baseLoader() 
which is effectively Compiler.LOADER gets passed as the parent to the newly 
created DynamicClassLoader.
So I get Compiler.LOADER which I have set to the correct classloader, replaced 
by the DynamicClassLoader whose parent is my classloader. The problem is that 
DynamicClassLoader inherits from URLClassLoader that inherits from ClassLoader 
which, although accepts a parent classloader on its creation, does not delegate 
getResourceAsStream() in case of its personal failure to its parent! That 
results in that my classloader, although still present in the chain, never gets 
called and the (require) in the ns form of example.namespace fails to locate 
the required namespaces that *are* available at that data source.
The problem is that this behavior is hard-coded in Clojure and it looks like it 
is impossible to change that. Clojure forces us to use a classloader that 
inherits the getResourceAsStream() method from java.lang.ClassLoader which does 
not allow delegation of this request to parent classloader. This effectively 
prevents using Clojure as a library together with a plugin system because it 
renders Clojure incapable of working with sources that are fetched from 
elsewhere than the Java's URLClassLoader is capable of retrieving data from. It 
is impossible to load sources from a database, or some internet data source or 
an encrypted data source, or even another location in the filesystem. Wow!
We've went with Clojure and now are in the desperate need to resolve this 
peculiar phenomenon.. What could be a proposed solution for this situation?
Thank you.



-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to