jruby/jruby — pull request #1872 by mkristian (2014-07-30 09:24:44+00:00)
Title: introduce uri: pseudo protocol

the idea of the uri: pseudo protocol is to extend the classpath: to any possible classloader. since classloader have actually only one method for JRuby to use "classloader.getResource" it needs directory listing info embedded into the jars like jruby-stdlib.jar #1823 ONLY with those directory info default gems and regular gems will work. so jruby-stdlib.jar just adds those listings. they are not used unless you use the uri: protocol. there is no automatism which use those uri: protocol, i.e. those directory listing do not effect any existing JRuby application.

for testing I copied ALL test for classpath: to have also one for uri: as well.

to show what can be done there is test case:
https://github.com/jruby/jruby/tree/test-uri-protocol/maven/jruby/src/it/osgi_many_bundles_with_embedded_gems
here JRuby itself is one classloader, there is bundle/jar which has embedded gems which live in a second classloader and there is a third bundle/jar which contains some ruby scripts and has yet another classloader.

the example sets up the ScriptingContainer very carefully to have ONLY uri: protocol inside the JRUBY_HOME, $LOAD_PATH and GEM_PATH/GEM_HOME to keep the application isolated from the environment (having things like this in mind: https://github.com/jruby/warbler/issues/263). the setup happens here: https://github.com/jruby/jruby/blob/test-uri-protocol/maven/jruby/src/it/osgi_many_bundles_with_embedded_gems/app/src/test/java/org/jruby/embed/osgi/test/JRubyOsgiEmbedTest.java#L78

it also removes all those references to jar files inside $LOAD_PATH which are copied from the java,class.path or so. once you add classpath: or the uri: to the $LOAD_PATH all those "automatisms" regarding the LOAD_PATH are not needed anymore. the classloader which loads jruby takes care of this.

this is also meant to replace the current OSGi pieces since we are not able to determine the state of those: #1866

the same setup of ScriptingContainer would be helpful to uniform the j2ee setup, since the current situation with its automatisms make things differ a lot depending on the servlet container used. a setup which is the same for all servlet environments will greatly improve the current support situation (which is quite a difficult one). in #1865 I talked about the classpath: protocol but the uri: protocol with its directory support for generic classloaders is the better choice. warbler can easily support adding extra directory info to the embedded gems of the warfile. and those warfile will work on more j2ee containers then the current setup warbler produces.

using the same approach for osgi and j2ee will be also helpful on the support side

having an extended ScriptingContainer which helps to set it up with uri: protocol only should be possible:
* find out whether you run via Thread.currentThread.contextClassLoader or an OSGi classloader and setup $LOAD_PATH, JRUBY_HOME and GEM_PATH/GEM_HOME respectively
* add convenient methods to add a classloader to LOAD_PATH or GEM_PATH

I might add another osgi test case using jruby-complete jar which is already an OSGi bundle which will add another "classloader/bundle" to the setup.

cc @kares @codefinger @ajuckel @ratnikov