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: bd34f0f1c9bc
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: bf9d0b054eca
Choose a head ref
  • 3 commits
  • 10 files changed
  • 1 contributor

Commits on Apr 7, 2016

  1. Copy the full SHA
    dfd979c View commit details
  2. Copy the full SHA
    2ab22c2 View commit details
  3. 3
    Copy the full SHA
    bf9d0b0 View commit details
14 changes: 10 additions & 4 deletions core/src/main/java/org/jruby/RubyInstanceConfig.java
Original file line number Diff line number Diff line change
@@ -35,10 +35,10 @@
import org.jruby.runtime.backtrace.TraceType;
import org.jruby.runtime.load.LoadService;
import org.jruby.runtime.profile.builtin.ProfileOutput;
import org.jruby.util.ClassLoaderGetResourses;
import org.jruby.util.ClassesLoader;
import org.jruby.util.ClasspathLauncher;
import org.jruby.util.FileResource;
import org.jruby.util.GetResources;
import org.jruby.util.Loader;
import org.jruby.util.InputStreamMarkCursor;
import org.jruby.util.JRubyFile;
import org.jruby.util.KCode;
@@ -700,6 +700,11 @@ public List<String> getExtraGemPaths() {
return extraGemPaths;
}

private final List<Loader> extraLoaders = new LinkedList<>();
public List<Loader> getExtraLoaders() {
return extraLoaders;
}

/**
* adds a given ClassLoader to jruby. i.e. adds the root of
* the classloader to the LOAD_PATH so embedded ruby scripts
@@ -716,7 +721,7 @@ public List<String> getExtraGemPaths() {
* @param loader
*/
public void addLoader(ClassLoader loader) {
addLoader(new ClassLoaderGetResourses(loader));
addLoader(new ClassesLoader(loader));
}

/**
@@ -727,13 +732,14 @@ public void addLoader(ClassLoader loader) {
* method to do so.
* @param bundle
*/
public void addLoader(GetResources bundle) {
public void addLoader(Loader bundle) {
// loader can be a ClassLoader or an Bundle from OSGi
UriLikePathHelper helper = new UriLikePathHelper(bundle);
String uri = helper.getUriLikePath();
if (uri != null) extraLoadPaths.add(uri);
uri = helper.getUriLikeGemPath();
if (uri != null) extraGemPaths.add(uri);
extraLoaders.add(bundle);
}

public String[] getArgv() {
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package org.jruby.embed;

import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.LinkedList;

import org.jruby.util.ClassLoaderGetResourses;
import org.jruby.util.ClassesLoader;
import org.jruby.util.UriLikePathHelper;

/**
@@ -58,7 +57,7 @@ public IsolatedScriptingContainer( LocalContextScope scope,
setLoadPaths(loadPaths);

// set the right jruby home
UriLikePathHelper uriPath = new UriLikePathHelper(new ClassLoaderGetResourses(getClassLoader()));
UriLikePathHelper uriPath = new UriLikePathHelper(new ClassesLoader(getClassLoader()));
URL url = uriPath.getResource("/.jrubydir");
if (url != null){
setCurrentDirectory( URI_CLASSLOADER );
Original file line number Diff line number Diff line change
@@ -8,7 +8,8 @@
import org.jruby.embed.LocalContextScope;
import org.jruby.embed.LocalVariableBehavior;

import org.jruby.util.GetResources;
import org.jruby.embed.osgi.internal.BundleWiringOSGiClassLoaderAdapter;
import org.jruby.util.Loader;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
@@ -133,7 +134,8 @@ public void addBundleToGemPath(String symbolicName) {
addBundleToGemPath(toBundle(symbolicName));
}

static class BundleGetResources implements GetResources {
static class BundleGetResources implements Loader
{

private final Bundle bundle;

@@ -150,5 +152,15 @@ public URL getResource(String path) {
public Enumeration<URL> getResources(String path) throws IOException {
return bundle.getResources(path);
}

@Override
public Class<?> loadClass(final String name) throws ClassNotFoundException {
return bundle.loadClass(name);
}

@Override
public ClassLoader getClassLoader() {
return new BundleWiringOSGiClassLoaderAdapter().getClassLoader(bundle);
}
}
}
60 changes: 60 additions & 0 deletions core/src/main/java/org/jruby/java/codegen/MultiClassLoader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package org.jruby.java.codegen;

import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;

public class MultiClassLoader
extends ClassLoader
{

private List<ClassLoader> classLoaders = new LinkedList<>();

public MultiClassLoader(ClassLoader parent) {
super(parent);
}

public void addClassLoader(ClassLoader loader) {
classLoaders.add(loader);
}

protected Class<?> findClass(String name) throws ClassNotFoundException {
String path = name.replace('.', '/') + ".class";
for (ClassLoader classLoader : classLoaders) {
URL resource = classLoader.getResource(path);
if (resource != null) {
return classLoader.loadClass(name);
}
}
return super.findClass(name);
}

protected URL findResource(String name) {
for (ClassLoader classLoader : classLoaders) {
URL resource = classLoader.getResource(name);
if (resource != null) {
return resource;
}
}
return super.findResource(name);
}

protected Enumeration<URL> findResources(String name) throws IOException {
Vector<URL> vector = new Vector<URL>();
for (ClassLoader classLoader : classLoaders) {
Enumeration<URL> enumeration = classLoader.getResources(name);
while (enumeration.hasMoreElements()) {
vector.add(enumeration.nextElement());
}
}
Enumeration<URL> enumeration = super.findResources(name);
while (enumeration.hasMoreElements()) {
vector.add(enumeration.nextElement());
}
return vector.elements();
}

}
47 changes: 39 additions & 8 deletions core/src/main/java/org/jruby/java/codegen/RealClassGenerator.java
Original file line number Diff line number Diff line change
@@ -37,6 +37,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.jruby.Ruby;
import org.jruby.RubyBasicObject;
import org.jruby.RubyClass;
@@ -54,6 +55,8 @@
import org.jruby.util.ClassDefiningClassLoader;
import org.jruby.util.ClassDefiningJRubyClassLoader;
import static org.jruby.util.CodegenUtils.*;

import org.jruby.util.Loader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.Type;
@@ -112,7 +115,9 @@ public static Class createRealImplClass(Class superClass, Class[] interfaces, Ru
Map<String, List<Method>> simpleToAll = buildSimpleToAllMap(interfaces, superTypeNames);

Class newClass = defineRealImplClass(ruby, name, superClass, superTypeNames, simpleToAll);

if (!newClass.isAssignableFrom(interfaces[0])) {
new RuntimeException(newClass.getInterfaces()[0].getClassLoader() + " " + interfaces[0].getClassLoader());
}
return newClass;
}

@@ -280,7 +285,7 @@ private static void defineOldStyleBody(SkinnyMethodAdapter mv, final String path
mv.ldc(eachName);
}
mv.invokevirtual(p(RuntimeCache.class), "searchWithCache",
sig(DynamicMethod.class, params(IRubyObject.class, int.class, String.class, nameSet.size())));
sig(DynamicMethod.class, params(IRubyObject.class, int.class, String.class, nameSet.size())));

// get current context
mv.aload(rubyIndex);
@@ -471,21 +476,47 @@ public static Class defineRealImplClass(final Ruby runtime, final String name,
// end class
cw.visitEnd();

// create the class
// first try to find the class
Class newClass = null;
for(Loader loader : runtime.getInstanceConfig().getExtraLoaders()) {
try {
newClass = loader.loadClass(name);
break;
}
catch(ClassNotFoundException ignored) {
}
}

final ClassDefiningJRubyClassLoader loader;
if (superClass.getClassLoader() instanceof ClassDefiningJRubyClassLoader) {
loader = new ClassDefiningJRubyClassLoader(superClass.getClassLoader());
} else {
loader = new ClassDefiningJRubyClassLoader(runtime.getJRubyClassLoader());
}

Class newClass;
try {
newClass = loader.loadClass(name);
if (newClass == null) {
try {
newClass = loader.loadClass(name);
}
catch (ClassNotFoundException ignored) {
}
}
catch (ClassNotFoundException ex) {

// create the class
if (newClass == null) {
final byte[] bytecode = cw.toByteArray();
newClass = loader.defineClass(name, bytecode);
MultiClassLoader multiClassLoader = new MultiClassLoader(superClass.getClassLoader());
for(Loader cLoader : runtime.getInstanceConfig().getExtraLoaders()) {
multiClassLoader.addClassLoader(cLoader.getClassLoader());
}
try {
newClass = new ClassDefiningJRubyClassLoader(multiClassLoader).defineClass(name, bytecode);
}
catch(Error ignored) {
}
if (newClass == null) {
newClass = loader.defineClass(name, bytecode);
}
if ( DEBUG ) writeClassFile(name, bytecode);
}

8 changes: 8 additions & 0 deletions core/src/main/java/org/jruby/javasupport/JavaSupportImpl.java
Original file line number Diff line number Diff line change
@@ -46,6 +46,7 @@
import org.jruby.RubyModule;
import org.jruby.exceptions.RaiseException;
import org.jruby.exceptions.Unrescuable;
import org.jruby.util.Loader;
import org.jruby.util.collections.ClassValue;
import org.jruby.javasupport.binding.AssignedName;
import org.jruby.javasupport.proxy.JavaProxyClass;
@@ -147,6 +148,13 @@ public Class loadJavaClass(String className) throws ClassNotFoundException {
Class primitiveClass;
if ((primitiveClass = JavaUtil.PRIMITIVE_CLASSES.get(className)) == null) {
if (!Ruby.isSecurityRestricted()) {
for(Loader loader : runtime.getInstanceConfig().getExtraLoaders()) {
try {
return loader.loadClass(className);
}
catch(ClassNotFoundException ignored) {
}
}
return Class.forName(className, true, runtime.getJRubyClassLoader());
}
return Class.forName(className);
Original file line number Diff line number Diff line change
@@ -4,11 +4,11 @@
import java.net.URL;
import java.util.Enumeration;

public class ClassLoaderGetResourses implements GetResources {
public class ClassesLoader implements Loader {

private final ClassLoader loader;

public ClassLoaderGetResourses(ClassLoader loader) {
public ClassesLoader(ClassLoader loader) {
this.loader = loader;
}

@@ -21,4 +21,14 @@ public URL getResource(String path) {
public Enumeration<URL> getResources(String path) throws IOException {
return loader.getResources(path);
}

@Override
public Class<?> loadClass(final String name) throws ClassNotFoundException {
return this.loader.loadClass(name);
}

@Override
public ClassLoader getClassLoader() {
return this.loader;
}
}
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/util/JRubyClassLoader.java
Original file line number Diff line number Diff line change
@@ -84,7 +84,7 @@ private File getTempDir() {
public void addURL(URL url) {
// if we have such embedded jar within a jar, we copy it to temp file and use the
// the temp file with the super URLClassLoader
if ( url.toString().contains( "!/" )) {
if ( url.toString().contains( "!/" ) || !url.getProtocol().equals("file")) {
InputStream in = null; OutputStream out = null;
try {
File f = File.createTempFile("jruby", new File(url.getFile()).getName(), getTempDir());
Original file line number Diff line number Diff line change
@@ -7,9 +7,14 @@
/**
* Created by cmeier on 7/30/15.
*/
public interface GetResources {
public interface Loader
{

URL getResource(String path);// throws IOException;

Enumeration<URL> getResources(String path) throws IOException;

Class<?> loadClass(String name) throws ClassNotFoundException;

ClassLoader getClassLoader();
}
4 changes: 2 additions & 2 deletions core/src/main/java/org/jruby/util/UriLikePathHelper.java
Original file line number Diff line number Diff line change
@@ -30,9 +30,9 @@

public class UriLikePathHelper {

private final GetResources loader;
private final Loader loader;

public UriLikePathHelper(GetResources loader) {
public UriLikePathHelper(Loader loader) {
this.loader = loader;
}