Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

integrate with JRuby #3

Open
mkristian opened this issue Aug 13, 2015 · 2 comments
Open

integrate with JRuby #3

mkristian opened this issue Aug 13, 2015 · 2 comments

Comments

@mkristian
Copy link
Contributor

the current approach is to install the gem into a some directory by setting GEM_HOME
and setting GEM_PATH and add GEM_HOME/bin to the PATH before executing JRuby

to integrate it directly with JRuby there are two steps:

  • tell JRuby which .gem files to "install"
  • how to use the "installed" .gem files

the second one first:

how to use "installed" .gem files

via the filesystem

that is how MRI works

via the classloader

having the a ./specifications and ./gems directory inside your
classloader is where JRuby will look for "installed" gems

you also can add another classloader to JRuby with 9.0.1.0 this can be
done via the RubyInstanceConfig or via the ScriptingContainer
API. this will take care of the ./specifications and ./gems to be
added for rubygems to find them.

having a JemsClassloader and add it to JRuby is straight forward if
this classloader has following properties:

  • URL(classloader.getResource("some/path/somewhere").toString()).openStream()```
    needs to work, i.e. the classloader needs to have its own protocol
    handler os similar.
    
  • classloader.getResource("some/path/somewhere/.jrubydir") needs
    to be the directory listing of some/path/somewhere the same as ls -1 some/path/somewhere > .jrubydir would produce.

for older JRuby this can be done as well but is a bit more then just calling
a single method addClassLoader

extend the LibrarySearcher and add JemsResource to it

adding a new pseudo protocol uri:jems:/ to JRuby is more or less
straight forward.

for this to implement some class/interface (let's call it Jems) like this is needed

InputStream getFileResource( String path );
List<String> getDirectoryListing( String path );

compare this to the remarks about the classloader above :)

this Jems instance needs to be attached to the JRuby runtime as
different runtimes can have different sets of jems.

tell JRuby to "install" jems

Jems.install( 'my-1.2.3.gem' )

installed via filesystem

the ./specifications needs to be added: Gem:::Specification.add_dir( new_gemspecs_directory )

installed via JemsClassloader

the ./specifications needs to be added:
Gem:::Specification.add_dir( 'uri:' + uri_to_gemspecs_directory )

which addClassLoader is doing.

installed via JemsResource

the ./specifications needs to be added:
Gem:::Specification.add_dir( 'uri:jems/specifications' )

can be done where
Gem:::Specification.add_dir( 'uri:classloader:/specifications' )
is currently added: rubygems/defaults/jruby.rb

bootstrappig

currently installing of gems is done "before" jruby is used. either
installed the gems via gem install my or via bundler or embedded
the gems into jar.

putting the Jems.install into my application is wrong. a compromise is
to have some kind of setup

require 'jems/setup'

which just knows where to look for gem-files and installs them. this
actually is quite nice since it also can tell rubygems that those gems
are already activated which would bypass rubygems altogether.

@rtyler
Copy link
Member

rtyler commented Aug 13, 2015

@mkristian I'm not sure I understand the "tell JRuby to 'install' gems" section. I don't understand what this would be used for if we've got the classloader implemented

@mkristian
Copy link
Contributor Author

even if there is a classloader how does this classloader get to know which gems to "install" ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants