Using a separate classloader for a block

I am looking to see how plausible it is to execute a block within a
child Classloader. A list of Jars would be passed to the ClassLoader to
load for the execution of the block. The problem I have is telling the
JRuby runtime to use the new classloader instead of the default. What I
have now is a bit of a hack, it manually uses a custom class loader.
The call to create(string class) uses it for constructing an instance.

An example of what I am attempting now:

 email = LockJar::ClassLoader.new( 'tmp/IsolateJarfile.lock'

).isolate do
email = create( ‘org.apache.commons.mail.SimpleEmail’ )
email.setSubject( ‘test subject’ )
email
end

 email.getSubject().should eql 'test subject'

This works, the SimpleEmail is created in the child ClassLoader. The
default JRuby classpath is not changed. The call to create(
‘org.apache.commons.mail.SimpleEmail’ ) is ugly. Ideally
'org.apache.commons.mail.SimpleEmail.new could be called and the JRuby
runtime would pull from the custom class loader instead of the default
JRuby classloader. I tried changing
Thread.currentThread().setContextClassLoader during the block execution,
but that did not work. I snooped around the JRuby source some, but could
not figure out a good way to hook into the ClassLoader. Any help or
advice is appreciated.

The simple custom classloader:


Ruby to load jars in isolation:
https://github.com/mguymon/lock_jar/blob/class_loader/lib/lock_jar/class_loader.rb
The green spec:
https://github.com/mguymon/lock_jar/blob/class_loader/spec/lock_jar/class_loader_spec.rb

thanks,
Michael

Hi Michael,

On 25.09.2012 16:22, Michael Guymon wrote:

I am looking to see how plausible it is to execute a block within a
child Classloader.

I’ve also been playing around with a JRuby/Maven integration and found
it necessary to run some JRuby code in an alternate classloader.

My solution is rather inelegant: I instantiate a whole new JRuby
runtime
and then use it as a regular Java object using the JRuby embed API. I
pass Ruby objects into it by Marshal.dump’ing them them to Java strings
and then Marshal.load’ing them inside the sub-JRuby, if that makes
sense.

Example here:
https://github.com/pmahoney/mini_aether/blob/master/lib/mini_aether.rb

See the #with_ruby_container and #resolve methods. The sub-JRuby loads
a
.rb file (mini_aether/resolver) which is then free to load JARs that
won’t
contaminate the original JRuby runtime.

Hope that helps.


Patrick M.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs