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=gst&q=classpath#69c0d195defeeed3 HTH On Dec 7, 10:26 am, Pierre-Yves Ritschard 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 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=gst&q=classpath#69c0d195deeed3 > > HTH > > On Dec 7, 10:26 am, Pierre-Yves Ritschard 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 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 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=gst&q=classpath#69c0d195deeed3 >> >> HTH >> >> On Dec 7, 10:26 am, Pierre-Yves Ritschard 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 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 > 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 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=gst&q=classpath#69c0d195deeed3 >>> >>> HTH >>> >>> On Dec 7, 10:26 am, Pierre-Yves Ritschard 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
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 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