Re: Dynamically Loading Jar Strategy
Thanks, this clarifies why my initial tests setting the current class loader failed. On Thu, Dec 8, 2011 at 2:14 AM, Brent Millare brent.mill...@gmail.com wrote: To better understand what's going underneath, you're just calling the addURL method of the classloader. But since you might be evaluating this at the repl, there is an important point regarding the classloader. Everytime clojure evaluates a form, it will use a new classloader on that form, and the parent will be the classloader of the caller of the eval. So this means if you evaluate two forms consecutively, the first being the addURL, and the second, the command depending on the jar, the second will fail (unless you wrap both commands in a let). You need to ensure that the parent of the current classloader in the call to addURL is set. This way, all future evals will delegate to the classloader that knows about the jar. So in summary, the heart of the command should just be: (.addURL (.getContextClassLoader (Thread/currentThread)) (.toURL (.toURI file))) For runtime dependency management, pomegranate does this, and so does my library, dj https://github.com/bmillare/dj -- 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 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
Re: Dynamically Loading Jar Strategy
Correction, I forgot to add .getParent, the code should be (.addURL (.getParent (.getContextClassLoader (Thread/currentThread))) (.toURL (.toURI file))) -- 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
Dynamically Loading Jar Strategy
Hi, I have a use case where a daemon needs to read full namespaces from an external jar. I can successfuly access the namespace in the jar with tools.namespace/ find-namespaces-in-jarfile, then from the jarfile, selecting appropriate entries, coercing into readers and then loading with load- reader. This approach breaks as soon as the supplied jar does requires, since the jar is not on the classpath. I am a bit surprised that setting a classloader in the current thread with setContextClassLoader does not work, as my binding for *use-context-classloader* is the default: true. I could obviously supply a fixed directory that is always in the classpath but that would require having two configuration files, which I thought I could avoid. Is there a way around this, or am I stuck ? -- 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
Re: Dynamically Loading Jar Strategy
You can add jar to a classpath at runtime via the hack below. http://groups.google.com/group/clojure/browse_thread/thread/95ea6e918c430e/69c0d195defeeed3?lnk=gstq=classpath#69c0d195defeeed3 HTH On Dec 7, 10:26 am, Pierre-Yves Ritschard p...@spootnik.org wrote: Hi, I have a use case where a daemon needs to read full namespaces from an external jar. I can successfuly access the namespace in the jar with tools.namespace/ find-namespaces-in-jarfile, then from the jarfile, selecting appropriate entries, coercing into readers and then loading with load- reader. This approach breaks as soon as the supplied jar does requires, since the jar is not on the classpath. I am a bit surprised that setting a classloader in the current thread with setContextClassLoader does not work, as my binding for *use-context-classloader* is the default: true. I could obviously supply a fixed directory that is always in the classpath but that would require having two configuration files, which I thought I could avoid. Is there a way around this, or am I stuck ? -- 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
Re: Dynamically Loading Jar Strategy
I ended up doing that, all the other approaches fail for me. Thanks for the confirmation. On Wed, Dec 7, 2011 at 8:12 PM, vitalyper vitaly...@yahoo.com wrote: You can add jar to a classpath at runtime via the hack below. http://groups.google.com/group/clojure/browse_thread/thread/95ea6e918c430e/69c0d195defeeed3?lnk=gstq=classpath#69c0d195deeed3 HTH On Dec 7, 10:26 am, Pierre-Yves Ritschard p...@spootnik.org wrote: Hi, I have a use case where a daemon needs to read full namespaces from an external jar. I can successfuly access the namespace in the jar with tools.namespace/ find-namespaces-in-jarfile, then from the jarfile, selecting appropriate entries, coercing into readers and then loading with load- reader. This approach breaks as soon as the supplied jar does requires, since the jar is not on the classpath. I am a bit surprised that setting a classloader in the current thread with setContextClassLoader does not work, as my binding for *use-context-classloader* is the default: true. I could obviously supply a fixed directory that is always in the classpath but that would require having two configuration files, which I thought I could avoid. Is there a way around this, or am I stuck ? -- 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 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
Re: Dynamically Loading Jar Strategy
Also check out https://github.com/cemerick/pomegranate -S -- 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
Re: Dynamically Loading Jar Strategy
try something like https://github.com/hiredman/clojurebot/blob/master/src/clojurebot/plugin.clj On Wed, Dec 7, 2011 at 11:53 AM, Pierre-Yves Ritschard p...@spootnik.org wrote: I ended up doing that, all the other approaches fail for me. Thanks for the confirmation. On Wed, Dec 7, 2011 at 8:12 PM, vitalyper vitaly...@yahoo.com wrote: You can add jar to a classpath at runtime via the hack below. http://groups.google.com/group/clojure/browse_thread/thread/95ea6e918c430e/69c0d195defeeed3?lnk=gstq=classpath#69c0d195deeed3 HTH On Dec 7, 10:26 am, Pierre-Yves Ritschard p...@spootnik.org wrote: Hi, I have a use case where a daemon needs to read full namespaces from an external jar. I can successfuly access the namespace in the jar with tools.namespace/ find-namespaces-in-jarfile, then from the jarfile, selecting appropriate entries, coercing into readers and then loading with load- reader. This approach breaks as soon as the supplied jar does requires, since the jar is not on the classpath. I am a bit surprised that setting a classloader in the current thread with setContextClassLoader does not work, as my binding for *use-context-classloader* is the default: true. I could obviously supply a fixed directory that is always in the classpath but that would require having two configuration files, which I thought I could avoid. Is there a way around this, or am I stuck ? -- 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 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 -- And what is good, Phaedrus, And what is not good— Need we ask anyone to tell us these things? -- 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
Re: Dynamically Loading Jar Strategy
Thanks a lot for the good advice. Pomegranate is very nice and very useful for testing. As for your trick Kevin, certainly nicer that the reflection mess. On Wed, Dec 7, 2011 at 9:00 PM, Kevin Downey redc...@gmail.com wrote: try something like https://github.com/hiredman/clojurebot/blob/master/src/clojurebot/plugin.clj On Wed, Dec 7, 2011 at 11:53 AM, Pierre-Yves Ritschard p...@spootnik.org wrote: I ended up doing that, all the other approaches fail for me. Thanks for the confirmation. On Wed, Dec 7, 2011 at 8:12 PM, vitalyper vitaly...@yahoo.com wrote: You can add jar to a classpath at runtime via the hack below. http://groups.google.com/group/clojure/browse_thread/thread/95ea6e918c430e/69c0d195defeeed3?lnk=gstq=classpath#69c0d195deeed3 HTH On Dec 7, 10:26 am, Pierre-Yves Ritschard p...@spootnik.org wrote: Hi, I have a use case where a daemon needs to read full namespaces from an external jar. I can successfuly access the namespace in the jar with tools.namespace/ find-namespaces-in-jarfile, then from the jarfile, selecting appropriate entries, coercing into readers and then loading with load- reader. This approach breaks as soon as the supplied jar does requires, since the jar is not on the classpath. I am a bit surprised that setting a classloader in the current thread with setContextClassLoader does not work, as my binding for *use-context-classloader* is the default: true. I could obviously supply a fixed directory that is always in the classpath but that would require having two configuration files, which I thought I could avoid. Is there a way around this, or am I stuck ? -- 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 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 -- And what is good, Phaedrus, And what is not good— Need we ask anyone to tell us these things? -- 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 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
Re: Dynamically Loading Jar Strategy
To better understand what's going underneath, you're just calling the addURL method of the classloader. But since you might be evaluating this at the repl, there is an important point regarding the classloader. Everytime clojure evaluates a form, it will use a new classloader on that form, and the parent will be the classloader of the caller of the eval. So this means if you evaluate two forms consecutively, the first being the addURL, and the second, the command depending on the jar, the second will fail (unless you wrap both commands in a let). You need to ensure that the parent of the current classloader in the call to addURL is set. This way, all future evals will delegate to the classloader that knows about the jar. So in summary, the heart of the command should just be: (.addURL (.getContextClassLoader (Thread/currentThread)) (.toURL (.toURI file))) For runtime dependency management, pomegranate does this, and so does my library, dj https://github.com/bmillare/dj -- 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