Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 3c0289352e4e^
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 53f542a088c5
Choose a head ref
  • 2 commits
  • 10 files changed
  • 1 contributor

Commits on Oct 7, 2014

  1. [build] make sure we have jruby-core artifact with noasm classifier i…

    …nstalled for subsequent tests
    mkristian committed Oct 7, 2014
    Copy the full SHA
    3c02893 View commit details
  2. redefine uri:classloader: meaning to be the parent classloader of run…

    …time.getJRubyClassLoader
    
    this allows to set JRubyHome to uri:classloader:/META-INF/jruby.home for all situations where
    there is a jruby.home packed inside a jar.
    
    fixes problem with loadService and knoplerfish OSGi
    mkristian committed Oct 7, 2014
    Copy the full SHA
    53f542a View commit details
35 changes: 35 additions & 0 deletions core/pom.xml
Original file line number Diff line number Diff line change
@@ -686,6 +686,41 @@
</plugins>
</build>
</profile>
<profile>
<id>osgi</id>
<build>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<id>pack jruby-noasm.jar</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>noasm</shadedClassifierName>
<artifactSet>
<includes>
<include>com.github.jnr:jnr-ffi</include>
<include>org.ow2.asm:*</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>org.objectweb</pattern>
<shadedPattern>org.jruby.org.objectweb</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>dist</id>
<build>
51 changes: 18 additions & 33 deletions core/src/main/java/org/jruby/embed/IsolatedScriptingContainer.java
Original file line number Diff line number Diff line change
@@ -2,6 +2,8 @@

import java.net.URL;

import org.jruby.util.cli.Options;

/**
* the IsolatedScriptingContainer detects the whether it is used with
* a Thread.currentThread.contextClassLoader (J2EE) or with the classloader
@@ -40,7 +42,6 @@ public class IsolatedScriptingContainer extends ScriptingContainer {

private static final String JRUBYDIR = "/.jrubydir";
private static final String JRUBY_HOME = "/META-INF/jruby.home";
private static final String JRUBY_HOME_DIR = JRUBY_HOME + JRUBYDIR;

public IsolatedScriptingContainer()
{
@@ -67,41 +68,25 @@ public IsolatedScriptingContainer( LocalContextScope scope,
LocalVariableBehavior behavior,
boolean lazy )
{
super( scope, behavior, lazy );
boolean isContextClassLoader = true;
URL home = Thread.currentThread().getContextClassLoader().getResource( JRUBY_HOME_DIR.substring( 1 ) );
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 + "$", "" ) );
}
else {
setHomeDirectory( "uri:classloader:" + JRUBY_HOME );
}
super(scope, behavior, lazy);

// clean up LOAD_PATH
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' )}" );
// get the right classloader
ClassLoader cl = this.getClass().getClassLoader();
if (cl == null) cl = Thread.currentThread().getContextClassLoader();
setClassLoader( cl );

// set the right jruby home
setHomeDirectory( "uri:classloader:" + JRUBY_HOME );

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 );
}
// clean up LOAD_PATH
runScriptlet( "$LOAD_PATH.delete_if{|p| p =~ /jar$/ }" );

// setup the isolated GEM_PATH, i.e. without $HOME/.gem/**
runScriptlet("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 );
}
Original file line number Diff line number Diff line change
@@ -274,7 +274,7 @@ private void loadJar(Ruby runtime, boolean wrap) {
}
else if (location.startsWith(URLResource.URI)){
url = null;
runtime.getJRubyClassLoader().addURLNoIndex(URLResource.getResourceURL(location));
runtime.getJRubyClassLoader().addURLNoIndex(URLResource.getResourceURL(runtime, location));
}
else {
File f = new File(location);
8 changes: 6 additions & 2 deletions core/src/main/java/org/jruby/util/JRubyFile.java
Original file line number Diff line number Diff line change
@@ -64,10 +64,14 @@ public static FileResource createResource(ThreadContext context, String pathname
}

public static FileResource createResource(Ruby runtime, String pathname) {
return createResource(runtime.getPosix(), runtime.getCurrentDirectory(), pathname);
return createResource(runtime.getPosix(), runtime, runtime.getCurrentDirectory(), pathname);
}

public static FileResource createResource(POSIX posix, String cwd, String pathname) {
return createResource(posix, null, cwd, pathname);
}

public static FileResource createResource(POSIX posix, Ruby runtime, String cwd, String pathname) {
FileResource emptyResource = EmptyFileResource.create(pathname);
if (emptyResource != null) return emptyResource;

@@ -80,7 +84,7 @@ public static FileResource createResource(POSIX posix, String cwd, String pathna
if (pathname.startsWith("classpath:")) return ClasspathResource.create(pathname);

// replace is needed for maven/jruby-complete/src/it/app_using_classpath_uri to work
if (pathname.startsWith("uri:")) return URLResource.create(pathname.replace("classpath:/", ""));
if (pathname.startsWith("uri:")) return URLResource.create(runtime, pathname.replace("classpath:/", ""));

if (pathname.startsWith("file:")) {
pathname = pathname.substring(5);
72 changes: 43 additions & 29 deletions core/src/main/java/org/jruby/util/URLResource.java
Original file line number Diff line number Diff line change
@@ -13,8 +13,8 @@
import java.util.Set;

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

import org.jruby.Ruby;
import org.jruby.util.io.ChannelDescriptor;
import org.jruby.util.io.ModeFlags;

@@ -32,19 +32,21 @@ public class URLResource implements FileResource {
private final String pathname;

private final JarFileStat fileStat;
private final ClassLoader cl;

URLResource(String uri, URL url, String[] files) {
this(uri, url, null, files);
this(uri, url, null, null, files);
}

URLResource(String uri, String pathname, String[] files) {
this(uri, null, pathname, files);
URLResource(String uri, ClassLoader cl, String pathname, String[] files) {
this(uri, null, cl, pathname, files);
}

private URLResource(String uri, URL url, String pathname, String[] files) {
private URLResource(String uri, URL url, ClassLoader cl, String pathname, String[] files) {
this.uri = uri;
this.list = files;
this.url = url;
this.cl = cl;
this.pathname = pathname;
this.fileStat = new JarFileStat(this);
}
@@ -94,7 +96,7 @@ public long length()
@Override
public boolean canRead()
{
return true;
return exists();
}

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

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

@Override
@@ -137,7 +138,7 @@ public InputStream openInputStream()
try
{
if (pathname != null) {
return Thread.currentThread().getContextClassLoader().getResourceAsStream(pathname);
return cl.getResourceAsStream(pathname);
}
return url.openStream();
}
@@ -155,33 +156,31 @@ public ChannelDescriptor openDescriptor(ModeFlags flags, int perm) throws Resour
return new ChannelDescriptor(openInputStream(), flags);
}

public static FileResource createClassloaderURI(String pathname) {
public static FileResource createClassloaderURI(Ruby runtime, String pathname) {
// retrieve the classloader from the runtime if available otherwise mimic how the runtime got its classloader
ClassLoader cl = runtime != null ? runtime.getJRubyClassLoader().getParent() : URLResource.class.getClassLoader();
if (cl == null ) {
cl = Thread.currentThread().getContextClassLoader();
}
if (pathname.startsWith("/")) {
pathname = pathname.substring(1);
}
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(pathname);
if (is != null) {
try
{
is.close();
}
// need Exception here due to strange NPE in some cases
catch (Exception e) {}
}
String[] files = listClassLoaderFiles(pathname);
URL url = cl.getResource(pathname);
String[] files = listClassLoaderFiles(cl, pathname);
return new URLResource(URI_CLASSLOADER + pathname,
is == null ? null : pathname,
cl,
url == null ? null : pathname,
files);
}

public static FileResource create(String pathname)
public static FileResource create(Ruby runtime, String pathname)
{
if (!pathname.startsWith(URI)) {
return null;
}
pathname = pathname.substring(URI.length());
if (pathname.startsWith(CLASSLOADER)) {
return createClassloaderURI(pathname.substring(CLASSLOADER.length()));
return createClassloaderURI(runtime, pathname.substring(CLASSLOADER.length()));
}
return createRegularURI(pathname);
}
@@ -208,7 +207,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)
@@ -245,10 +252,10 @@ private static String[] listFilesFromInputStream(InputStream is) {
}
}
}
private static String[] listClassLoaderFiles(String pathname) {
private static String[] listClassLoaderFiles(ClassLoader cl, String pathname) {
try
{
Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(pathname + "/.jrubydir");
Enumeration<URL> urls = cl.getResources(pathname + "/.jrubydir");
if (!urls.hasMoreElements()) {
return null;
}
@@ -272,18 +279,25 @@ private static String[] listClassLoaderFiles(String pathname) {
private static String[] listFiles(String pathname) {
try
{
return listFilesFromInputStream(new URL(pathname.replace("file://", "file:/") + "/.jrubydir").openStream());
InputStream is = new URL(pathname + "/.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)
{
return null;
}
}

public static URL getResourceURL(String location)
public static URL getResourceURL(Ruby runtime, String location)
{
if (location.startsWith(URI + CLASSLOADER)){
return Thread.currentThread().getContextClassLoader().getResource(location.substring(URI_CLASSLOADER.length()));
return runtime.getJRubyClassLoader().getParent().getResource(location.substring(URI_CLASSLOADER.length()));
}
try
{
2 changes: 1 addition & 1 deletion maven/jruby-complete/pom.rb
Original file line number Diff line number Diff line change
@@ -53,7 +53,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.cp_r( source, target )
File.open( File.join( target, 'invoker.properties' ), 'w' ) do |f|
Original file line number Diff line number Diff line change
@@ -106,7 +106,7 @@ public void testJRubyCreate() throws Exception {

String gemPath = (String) jruby.runScriptlet( "Gem::Specification.dirs.inspect" );
gemPath = gemPath.replaceAll( "bundle[^:]*://[^/]*", "bundle:/" );
assertEquals( gemPath, "[\"uri:bundle://specifications\", \"uri:bundle://specifications\", \"uri:bundle://META-INF/jruby.home/lib/ruby/gems/shared/specifications\"]" );
assertEquals( gemPath, "[\"uri:bundle://specifications\", \"uri:classloader:/specifications\", \"uri:classloader:/META-INF/jruby.home/lib/ruby/gems/shared/specifications\"]" );

jruby.runScriptlet( "require 'jar-dependencies'; require 'krypt'" );
list = (String) jruby.runScriptlet( "Gem.loaded_specs.keys.inspect" );
Loading