Skip to content
Permalink
Browse files
Merge branch 'master' into truffle-head
  • Loading branch information
chrisseaton committed Dec 1, 2014
2 parents 302cc9c + b2b093a commit 5460e11a2c50aac8acaf2e9757d922f0527309c7
@@ -1,6 +1,9 @@
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
@@ -68,72 +71,95 @@ public IsolatedScriptingContainer( LocalContextScope scope,
boolean lazy )
{
super( scope, behavior, lazy );
boolean isContextClassLoader = true;
URL home = Thread.currentThread().getContextClassLoader().getResource( JRUBY_HOME_DIR.substring( 1 ) );
final String baseuri;
if ( home == null ) {
isContextClassLoader = false;
home = this.getClass().getClassLoader().getResource( JRUBY_HOME_DIR );
if ( home == null ) {
throw new RuntimeException( "BUG can not find " + JRUBY_HOME_DIR );
}
setClassLoader( this.getClass().getClassLoader() );
setHomeDirectory( "uri:" + home.toString().replaceFirst( JRUBYDIR + "$", "" ) );
baseuri = createUri(getClassLoader(), "/jruby/java.rb" );
}
else {
setHomeDirectory( "uri:classloader:" + JRUBY_HOME );
baseuri = "uri:classloader:/";
}

// clean up LOAD_PATH
getProvider().getRubyInstanceConfig().setLoadPaths(Arrays.asList(baseuri));
runScriptlet( "$LOAD_PATH.delete_if{|p| p =~ /jar$/ };"
// TODO NormalizedFile does too much - should leave uri: files as they are
+ "$LOAD_PATH.each{|p| p.sub!( /:\\/([^\\/])/,'://\\1' )}" );

if ( isContextClassLoader ) {
runScriptlet( "Gem::Specification.reset;"
+ "Gem::Specification.add_dir 'uri:classloader:" + JRUBY_HOME + "/lib/ruby/gems/shared';"
+ "Gem::Specification.add_dir 'uri:classloader:/';"
+ "$LOAD_PATH << 'uri:classloader:/'; $LOAD_PATH.inspect" );
}
else {
runScriptlet( "Gem::Specification.reset;"
+ "Gem::Specification.add_dir '" + getHomeDirectory() + "/lib/ruby/gems/shared'" );
addLoadPath( getClassLoader(), JRUBY_HOME_DIR );
addGemPath( getClassLoader(), JRUBY_HOME_DIR );
}
runScriptlet( "require 'rubygems/defaults/jruby';" // make sure we have the monkey patch Gem::Specification
+ "Gem::Specification.reset;"
+ "Gem::Specification.add_dir '" + getHomeDirectory() + "/lib/ruby/gems/shared';"
// if jruby-core and jruby-stdlib comes from the same osgi bundle, assume the embedded gems
// are in the same bundle
+ (getHomeDirectory().startsWith(baseuri) ? "Gem::Specification.add_dir '" + baseuri + "';" : "" ) );
}

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 classloader " + cl );
throw new RuntimeException( "reference " + ref + " not found on bundle " + cl );
}
return "uri:" + url.toString().replaceFirst( ref + "$", "" );
}

String uri = "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 + "$", "" );
}

String uri = "uri:" + url.toString().replaceFirst( ref + "$", "" );
private void addGemPath(String uri) {
runScriptlet( "Gem::Specification.add_dir '" + uri + "' unless Gem::Specification.dirs.member?( '" + uri + "' )" );
}

}
}
@@ -1575,7 +1575,17 @@ public LoadServiceResource getClassPathResource(ClassLoader classLoader, String
}
else {
debugLogTry("fileInClasspath", name);
loc = classLoader.getResource(name);
try
{
loc = classLoader.getResource(name);
}
// some classloaders can throw IllegalArgumentException here
// at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.getResource(BundleWiringImpl.java:2419) ~[org.apache.felix.framework-4.2.1.jar:na]
// at java.lang.ClassLoader.getResource(ClassLoader.java:1142) ~[na:1.7.0_65]
catch (IllegalArgumentException e)
{
loc = null;
}
}

if (loc != null) { // got it
@@ -15,7 +15,6 @@
import java.util.Set;

import jnr.posix.FileStat;
import jnr.posix.POSIX;

import org.jruby.util.io.ModeFlags;

@@ -95,7 +94,7 @@ public long length()
@Override
public boolean canRead()
{
return true;
return isFile();
}

@Override
@@ -128,8 +127,7 @@ public FileStat lstat() {

@Override
public JRubyFile hackyGetJRubyFile() {
new RuntimeException().printStackTrace();
return null;
return JRubyNonExistentFile.NOT_EXIST;
}

@Override
@@ -211,7 +209,15 @@ private static FileResource createRegularURI(String pathname) {
return new URLResource(URI + pathname, (URL)null, files);
}
try {
url.openStream().close();
InputStream is = url.openStream();
// no inputstream happens with knoplerfish OSGI and osgi tests from /maven/jruby-complete
if (is != null) {
is.close();
}
else {
// there is no input-stream from this url
url = null;
}
return new URLResource(URI + pathname, url, null);
}
catch (IOException e)
@@ -249,6 +255,9 @@ private static String[] listFilesFromInputStream(InputStream is) {
}
}
private static String[] listClassLoaderFiles(String pathname) {
if (pathname.endsWith(".rb") || pathname.endsWith(".class") || pathname.endsWith(".jar")) {
return null;
}
try
{
Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(pathname + "/.jrubydir");
@@ -273,9 +282,20 @@ private static String[] listClassLoaderFiles(String pathname) {
}

private static String[] listFiles(String pathname) {
if (pathname.endsWith(".rb") || pathname.endsWith(".class") || pathname.endsWith(".jar")) {
return null;
}
try
{
return listFilesFromInputStream(new URL(pathname.replace("file://", "file:/") + "/.jrubydir").openStream());
// TODO remove this replace
InputStream is = new URL(pathname.replace("file://", "file:/") + "/.jrubydir").openStream();
// no inputstream happens with knoplerfish OSGI and osgi tests from /maven/jruby-complete
if (is != null) {
return listFilesFromInputStream(is);
}
else {
return null;
}
}
catch (IOException e)
{
@@ -58,7 +58,7 @@
execute 'setup other osgi frameworks', :phase => 'pre-integration-test' do |ctx|
require 'fileutils'
source = File.join( ctx.basedir.to_pathname, 'src', 'templates', 'osgi_many_bundles_with_embedded_gems' )
[ 'equinox-3.6', 'equinox-3.7', 'felix-3.2', 'felix-4.4' ].each do |m|
[ 'knoplerfish', 'equinox-3.6', 'equinox-3.7', 'felix-3.2', 'felix-4.4' ].each do |m|
target = File.join( ctx.basedir.to_pathname, 'src', 'it', 'osgi_many_bundles_with_embedded_gems_' + m )
FileUtils.rm_rf( target )
FileUtils.cp_r( source, target )
@@ -82,7 +82,7 @@ public void testJRubyCreate() throws Exception {

IsolatedScriptingContainer jruby = new IsolatedScriptingContainer();
jruby.addLoadPath( Scripts.class.getClassLoader() );
jruby.addGemPath( Gems.class.getClassLoader() );
jruby.addBundleToGemPath( FrameworkUtil.getBundle( Gems.class ) );

// run a script from LOAD_PATH
String hello = (String) jruby.runScriptlet( "require 'hello'; Hello.say" );
@@ -26,7 +26,7 @@ end

properties( 'tesla.dump.pom' => 'pom.xml',
'tesla.dump.readonly' => true,
'jruby.plugins.version' => '1.0.7-SNAPSHOT',
'jruby.plugins.version' => '1.0.7',
# we share the already installed gems
'gem.home' => '${jruby.home}/lib/ruby/gems/shared',
# need jruby_home but not jruby.home as name otherwise
@@ -39,7 +39,7 @@ freezing to) a specific jruby-complete jar version.</description>
<properties>
<tesla.dump.readonly>true</tesla.dump.readonly>
<gem.home>${jruby.home}/lib/ruby/gems/shared</gem.home>
<jruby.plugins.version>1.0.7-SNAPSHOT</jruby.plugins.version>
<jruby.plugins.version>1.0.7</jruby.plugins.version>
<tesla.dump.pom>pom.xml</tesla.dump.pom>
<project.build.sourceEncoding>utf-8</project.build.sourceEncoding>
<jruby_home>${basedir}/../../</jruby_home>
@@ -31,7 +31,7 @@

execute 'setup other osgi frameworks', :phase => 'pre-integration-test' do |ctx|
source = File.join( ctx.basedir.to_pathname, 'src', 'templates', 'osgi_all_inclusive' )
[ 'equinox-3.6', 'equinox-3.7', 'felix-3.2', 'felix-4.4'].each do |m|
[ 'knoplerfish', 'equinox-3.6', 'equinox-3.7', 'felix-3.2', 'felix-4.4'].each do |m|
target = File.join( ctx.basedir.to_pathname, 'src', 'it', 'osgi_all_inclusive_' + m )
FileUtils.rm_rf( target )
FileUtils.cp_r( source, target )
2 pom.rb
@@ -78,7 +78,7 @@
'base.java.version' => '1.7',
'tesla.dump.readonly' => 'true',
'rspec-mocks.version' => '2.14.1',
'jruby.plugins.version' => '1.0.7-SNAPSHOT',
'jruby.plugins.version' => '1.0.7',
'invoker.skip' => 'true',
'json.version' => '1.8.0',
'version.jruby' => '${project.version}',
@@ -132,7 +132,7 @@
<base.java.version>1.7</base.java.version>
<tesla.dump.readonly>true</tesla.dump.readonly>
<rspec-mocks.version>2.14.1</rspec-mocks.version>
<jruby.plugins.version>1.0.7-SNAPSHOT</jruby.plugins.version>
<jruby.plugins.version>1.0.7</jruby.plugins.version>
<json.version>1.8.0</json.version>
<invoker.skip>true</invoker.skip>
<power_assert.version>0.1.4</power_assert.version>
@@ -1,5 +1,7 @@
class MSpecScript

set :target, File.dirname(__FILE__) + '/spec-wrapper'

set :language, [
"spec/ruby/language"
]

0 comments on commit 5460e11

Please sign in to comment.