make resource loading suitable for arbitrary protocols/classloaders #1841

Closed
mkristian opened this Issue Jul 21, 2014 · 4 comments

3 participants

@mkristian
JRuby Team member

some classloaders come with their own protocol handlers. i.e. classloader.getResource delivers an URI with a classloader specific protocol. typical example is WEBSphere application and OSGi

having a uri like hufflepuf:/my/applicaiton/something.rb should just work with require and load (assuming the classloader I use is associated with the hufflepuf protocol)

having this in place I can even have embedded gems inside that classloader and together with #1823 these gems will work. or just add the root of the classloader-uri to LOAD_PATH

well, http:// does not work and probably should never work.

that and #1823 is probably the only missing piece to get OSGi to work properly (not with OSGIScriptingContainer) with the regular ScriptingContainer where I just setup the GEM_PATH to point into the root of my bundle-classloader and setup the LOAD_PATH in the same manner.

currently OSGi with embedded gems work only if you copy the "lib" directory of the gem into the root of your bundle, but that is very limited since there are several gems which expects the gem to be extracted and load any needed resource-files from the exploded gem. or other gems to gem 'multi-json', '> 1.0.3' which does only work with the respective gem got activated by rubygems. other gems like backport needs directory globs to work for their "intelligent" require.

adding directory info to the classloader and allow any uri-protocol to work with load and require is the base to get all those "fancy" classloaders to work. or better say it the other way around: get classloaders to work and not only URLClassloaders !!

@mkristian
JRuby Team member

the current example works by using the classpath: protocol

a7d900e#diff-c5eb4ad5fb6d4e25f1a6dcc0e8663ad9R79

not even though it is an OSGi bundle the testcase uses a out of the box ScriptingContainer ! this bundle is setup to include JRuby, all its ruby scripts and embed all the gems it needs.

the moment I want to modularize things, i.e. use the OSGi jruby-complete, have bundle A using ruby scripts from bundle B, then you need to setup the LOAD_PATH and GEM_PATH with something else then classpath: since all three life in their own classloader. and actuall the only thing needed it the LoadService to work with such an uri:

a7d900e#diff-c5eb4ad5fb6d4e25f1a6dcc0e8663ad9R78

the uri looks like this: bundle://13.0:1/
the 13 is the number of the bundle - the rest I do not know. but other frameworks might use other protocol handlers like websphere uses 'wsjar:'

finding a resource of directory can result in null - as far I know websphere behaves like this. but having an "extra" file with directory info in the same directory (#1823) would allow to find the root uri in such cases as well.

so the idea is to get this OSGi example closer to
https://github.com/jruby/jruby/tree/a7d900eaa889bc9873484e0f18545d884547a3e2/maven/jruby/src/it/many_jars_with_embedded_gems
where you have many jars with embedded gems.

so once you can have many bundles with embedded gems we add have some "helper" which eases the registration of a bundle to LOAD_PATH and GEM_PATH

@ratnikov

This should be supported by the FileResource framework by having a special URLResource that can load things from a generic URLConnection.

@mkristian
JRuby Team member
@mkristian
JRuby Team member

final fix via 50fda57

embedded gems still needs to put on load_path manually since the directory glob support is missing. a testcase utilizing more then one bundle with ruby scripts and embedded gems is still coming soon.

@mkristian mkristian closed this Jul 26, 2014
@enebo enebo added this to the Invalid or Duplicate milestone Aug 27, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment