Very cool Stefan, thanks! I'm planning to write a clojure.compile/main in Clojure along the lines of what you came up with. I think the current Compile.java is sufficient for bootstrapping clojure.jar--with the "finally" fix you recommend.
Thanks, --Steve On Nov 27, 2008, at 11:29 AM, Stefan Bodewig <[EMAIL PROTECTED] > wrote: > On 2008-11-27, Stefan Bodewig <[EMAIL PROTECTED]> wrote: > >> OK, I skimmed through compile and RT and it seems as if you "just" >> needed to construct a proper URLClassLoader with the directories you >> need on the classpath, set this one as the context classloader and >> set >> *use-context-classloader* to true before you invoke compile. > > Yes, works. The attached patch ensures that clojure.compile.path > exists (it doesn't ensure it is a directory, should it?), sets up a > classloader that contains it and runs compile successfully when > invoked for a non-existant target directory. > > I haven't changed the handling of the source directories, but it would > probably only be a matter of adding them to the same classloader as > well. > > Stefan > > BTW, should Var.popThreadBindings(); in Compile be moved into the > finally block? > > > > > Index: src/jvm/clojure/lang/Compile.java > =================================================================== > --- src/jvm/clojure/lang/Compile.java (revision 1127) +++ src/jvm/ > clojure/lang/Compile.java (working copy) @@ -14,6 +14,9 @@ import > java.io.OutputStreamWriter; import java.io.PrintWriter; import > java.io.IOException; +import java.io.File; +import java.net.URL; > +import java.net.URLClassLoader; // Compiles libs and generates > class files stored within the directory // named by the Java System > property "clojure.compile.path". Arguments are @@ -41,9 +44,22 @@ > System.exit(1); } + File destdir = new File(path); + if (! > destdir.exists()) { + destdir.mkdirs(); + } + ClassLoader > currentContextLoader = + > Thread.currentThread().getContextClassLoader(); + URLClassLoader > loader = + new URLClassLoader(new URL[] {destdir.toURL()}, + > currentContextLoader); + try > { Var.pushThreadBindings(RT.map(compile_path, path)); + > Var.pushThreadBindings(RT.map(RT.USE_CONTEXT_CLASSLOADER, + > Boolean.TRUE)); + > Thread.currentThread().setContextClassLoader(loader); > out.write("Compiling " + count + " " + ((count == 1) > ? > "lib" : "libs") + @@ -57,6 +73,8 @@ } finally { + > Thread.currentThread() > + .setContextClassLoader(currentContextLoader); try { out.flush(); --~--~---------~--~----~------------~-------~--~----~ 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 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 -~----------~----~----~----~------~----~------~--~---