Dynamically Loading Jar Strategy

2011-12-07 Thread Pierre-Yves Ritschard
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

2011-12-07 Thread vitalyper
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

2011-12-07 Thread Pierre-Yves Ritschard
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

2011-12-07 Thread Stuart Sierra
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

2011-12-07 Thread Kevin Downey
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

2011-12-07 Thread Pierre-Yves Ritschard
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

2011-12-07 Thread Brent Millare
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

2011-12-08 Thread Pierre-Yves Ritschard
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

2011-12-08 Thread Brent Millare
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