All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jruby.embed.IsolatedScriptingContainer Maven / Gradle / Ivy

There is a newer version: 9.4.9.0
Show newest version
package org.jruby.embed;

import java.net.URL;
import java.util.Arrays;

import org.osgi.framework.Bundle;

/**
 * the IsolatedScriptingContainer detects the whether it is used with
 * a Thread.currentThread.contextClassLoader (J2EE) or with the classloader
 * which loaded IsolatedScriptingContainer.class (OSGi case)
 * 
 * the setup of LOAD_PATH and GEM_PATH and JRUBY_HOME uses ONLY uri: or uri:classloader:
 * protocol paths. i.e. everything lives within one or more classloaders - no jars added from
 * jave.class.path or similar "magics"
 *
 * the root of the "main" classloader is add to LOAD_PATH and GEM_PATH.
 *
 * in the OSGi case there are helper methods to add ClassLoaders to the LOAD_PATH or GEM_PATH
 * 
 * a typical setup for the ContextClassLoader case and OSGi case looks likes this:
 * 
  • LOAD_PATH == [ "uri:classloader:/META-INF/jruby.home/lib/ruby/1.9/site_ruby", * "uri:classloader:/META-INF/jruby.home/lib/ruby/shared", * "uri:classloader:/META-INF/jruby.home/lib/ruby/1.9", * "uri:classloader:" ]
  • *
  • Gem::Specification.dirs == [ "uri:classloader:/specifications", "uri:classloader:/META-INF/jruby.home/lib/ruby/gems/shared/specifications" ] * here very resource is loaded via Thread.currentTHread.getContextClassLoader().getResourceAsStream(...) * * new URL( uri ).openStream(), i.e. new URL(classloader.getResource().toString()).openStream() has to work for * those classloaders. felix, knoplerfish and equinox OSGi framework do work. * * NOTE: Gem.path is base for determine the Gem::Specification.dirs and Gem::Specification.dirs is * used to find gemspec files of the installed gems. */ public class IsolatedScriptingContainer extends ScriptingContainer { private static final String JRUBYDIR = "/.jrubydir"; private static final String JRUBY_HOME = "/META-INF/jruby.home"; public IsolatedScriptingContainer() { this(LocalContextScope.SINGLETON); } public IsolatedScriptingContainer( LocalContextScope scope, LocalVariableBehavior behavior ) { this(scope, behavior, true); } public IsolatedScriptingContainer( LocalContextScope scope ) { this(scope, LocalVariableBehavior.TRANSIENT); } public IsolatedScriptingContainer( LocalVariableBehavior behavior ) { this(LocalContextScope.SINGLETON, behavior); } public IsolatedScriptingContainer( LocalContextScope scope, LocalVariableBehavior behavior, boolean lazy ) { super(scope, behavior, lazy); // get the right classloader ClassLoader cl = this.getClass().getClassLoader(); if (cl == null) cl = Thread.currentThread().getContextClassLoader(); setClassLoader( cl ); setLoadPaths( Arrays.asList( "uri:classloader:" ) ); // set the right jruby home setHomeDirectory( "uri:classloader:" + JRUBY_HOME ); // setup the isolated GEM_PATH, i.e. without $HOME/.gem/** runScriptlet("require 'rubygems/defaults/jruby';" + "Gem::Specification.reset;" + "Gem::Specification.add_dir 'uri:classloader:" + JRUBY_HOME + "/lib/ruby/gems/shared';" + "Gem::Specification.add_dir 'uri:classloader:';"); } public void addLoadPath( ClassLoader cl ) { addLoadPath( cl, JRUBYDIR ); } public void addLoadPath( ClassLoader cl, String ref ) { addLoadPath(createUri(cl, ref)); } public void addBundleToLoadPath( Bundle cl ) { addBundleToLoadPath( cl, JRUBYDIR ); } public void addBundleToLoadPath( Bundle cl, String ref ) { addLoadPath(createUriFromBundle(cl, ref)); } private String createUriFromBundle( Bundle cl, String ref) { URL url = cl.getResource( ref ); if ( url == null && ref.startsWith( "/" ) ) { url = cl.getResource( ref.substring( 1 ) ); } if ( url == null ) { throw new RuntimeException( "reference " + ref + " not found on bundle " + cl ); } return "uri:" + url.toString().replaceFirst( ref + "$", "" ); } private void addLoadPath(String uri) { runScriptlet( "$LOAD_PATH << '" + uri + "' unless $LOAD_PATH.member?( '" + uri + "' )" ); } public void addBundleToGemPath( Bundle cl ) { addBundleToGemPath( cl, "/specifications" + JRUBYDIR ); } public void addBundleToGemPath( Bundle cl, String ref ) { addGemPath(createUriFromBundle(cl, ref)); } public void addGemPath( ClassLoader cl ) { addGemPath( cl, "/specifications" + JRUBYDIR ); } public void addGemPath( ClassLoader cl, String ref ) { addGemPath(createUri(cl, ref)); } private String createUri(ClassLoader cl, String ref) { URL url = cl.getResource( ref ); if ( url == null && ref.startsWith( "/" ) ) { url = cl.getResource( ref.substring( 1 ) ); } if ( url == null ) { throw new RuntimeException( "reference " + ref + " not found on classloader " + cl ); } return "uri:" + url.toString().replaceFirst( ref + "$", "" ); } private void addGemPath(String uri) { runScriptlet( "Gem::Specification.add_dir '" + uri + "' unless Gem::Specification.dirs.member?( '" + uri + "' )" ); } }




  • © 2015 - 2025 Weber Informatics LLC | Privacy Policy