diff --git a/core/src/main/java/org/jruby/RubyClass.java b/core/src/main/java/org/jruby/RubyClass.java index cd4ff4531fd..e873665786d 100644 --- a/core/src/main/java/org/jruby/RubyClass.java +++ b/core/src/main/java/org/jruby/RubyClass.java @@ -144,23 +144,32 @@ public void setAllocator(ObjectAllocator allocator) { * Set a reflective allocator that calls a no-arg constructor on the given * class. * - * @param cls The class on which to call the default constructor to allocate + * @param clazz The class on which to call the default constructor to allocate */ @SuppressWarnings("unchecked") - public void setClassAllocator(final Class> cls) { + public void setClassAllocator(final Class> clazz) { + final Constructor> constructor; + try { + constructor = clazz.getConstructor(); + } catch (NoSuchMethodException nsme) { + throw new RuntimeException(nsme); + } + this.allocator = (runtime, klazz) -> { try { - RubyBasicObject object = (RubyBasicObject)cls.getConstructor().newInstance(); + RubyBasicObject object = (RubyBasicObject) constructor.newInstance(); object.setMetaClass(klazz); return object; - } catch (InstantiationException | InvocationTargetException ie) { - throw runtime.newTypeError("could not allocate " + cls + " with default constructor:\n" + ie); - } catch (IllegalAccessException | NoSuchMethodException iae) { - throw runtime.newSecurityError("could not allocate " + cls + " due to inaccessible default constructor:\n" + iae); + } catch (InvocationTargetException e) { + throw newTypeError(runtime, "could not allocate " + clazz + " with default constructor:\n" + e.getTargetException(), e); + } catch (InstantiationException e) { + throw newTypeError(runtime, "could not allocate " + clazz + " with default constructor:\n" + e, e); + } catch (IllegalAccessException e) { + throw runtime.newSecurityError("could not allocate " + clazz + " due to inaccessible default constructor:\n" + e); } }; - this.reifiedClass = (Class extends Reified>) cls; + this.reifiedClass = (Class extends Reified>) clazz; } /** @@ -171,25 +180,26 @@ public void setClassAllocator(final Class> cls) { */ @SuppressWarnings("unchecked") public void setRubyClassAllocator(final Class extends IRubyObject> clazz) { + final Constructor extends IRubyObject> constructor; try { - final Constructor extends IRubyObject> constructor = clazz.getConstructor(Ruby.class, RubyClass.class); - - this.allocator = (runtime, klazz) -> { - try { - return constructor.newInstance(runtime, klazz); - } catch (InvocationTargetException ite) { - throw runtime.newTypeError("could not allocate " + clazz + " with (Ruby, RubyClass) constructor:\n" + ite); - } catch (InstantiationException ie) { - throw runtime.newTypeError("could not allocate " + clazz + " with (Ruby, RubyClass) constructor:\n" + ie); - } catch (IllegalAccessException iae) { - throw runtime.newSecurityError("could not allocate " + clazz + " due to inaccessible (Ruby, RubyClass) constructor:\n" + iae); - } - }; - - this.reifiedClass = (Class extends Reified>) clazz; + constructor = clazz.getConstructor(Ruby.class, RubyClass.class); } catch (NoSuchMethodException nsme) { throw new RuntimeException(nsme); } + + this.allocator = (runtime, klazz) -> { + try { + return constructor.newInstance(runtime, klazz); + } catch (InvocationTargetException e) { + throw newTypeError(runtime, "could not allocate " + clazz + " with (Ruby, RubyClass) constructor:\n" + e.getTargetException(), e); + } catch (InstantiationException e) { + throw newTypeError(runtime, "could not allocate " + clazz + " with (Ruby, RubyClass) constructor:\n" + e, e); + } catch (IllegalAccessException e) { + throw runtime.newSecurityError("could not allocate " + clazz + " due to inaccessible (Ruby, RubyClass) constructor:\n" + e); + } + }; + + this.reifiedClass = (Class extends Reified>) clazz; } /** @@ -203,23 +213,30 @@ public void setRubyClassAllocator(final Class extends IRubyObject> clazz) { *
Note: Used with new concrete extension.
*/ public void setRubyStaticAllocator(final Class> clazz) { + final Method method; try { - final Method method = clazz.getDeclaredMethod("__allocate__", Ruby.class, RubyClass.class); - - this.allocator = (runtime, klazz) -> { - try { - return (IRubyObject) method.invoke(null, runtime, klazz); - } catch (InvocationTargetException ite) { - throw runtime.newTypeError("could not allocate " + clazz + " with (Ruby, RubyClass) constructor:\n" + ite); - } catch (IllegalAccessException iae) { - throw runtime.newSecurityError("could not allocate " + clazz + " due to inaccessible (Ruby, RubyClass) constructor:\n" + iae); - } - }; - - this.reifiedClass = (Class extends Reified>) clazz; + method = clazz.getDeclaredMethod("__allocate__", Ruby.class, RubyClass.class); } catch (NoSuchMethodException nsme) { throw new RuntimeException(nsme); } + + this.allocator = (runtime, klazz) -> { + try { + return (IRubyObject) method.invoke(null, runtime, klazz); + } catch (InvocationTargetException e) { + throw newTypeError(runtime, "could not allocate " + clazz + " with (Ruby, RubyClass) method:\n" + e.getTargetException(), e); + } catch (IllegalAccessException e) { + throw runtime.newSecurityError("could not allocate " + clazz + " due to inaccessible (Ruby, RubyClass) method:\n" + e); + } + }; + + this.reifiedClass = (Class extends Reified>) clazz; + } + + private static RaiseException newTypeError(final Ruby runtime, final String msg, final Exception e) { + RaiseException error = runtime.newTypeError(msg); + error.initCause(e); + return error; } @JRubyMethod(name = "allocate") @@ -936,22 +953,14 @@ public IRubyObject newInstance(ThreadContext context, IRubyObject[] args, Block * */ @Override - public IRubyObject initialize(ThreadContext context, Block block) { - return initialize19(context, block); - } - - public IRubyObject initialize(ThreadContext context, IRubyObject superObject, Block block) { - return initialize19(context, superObject, block); - } - @JRubyMethod(name = "initialize", visibility = PRIVATE) - public IRubyObject initialize19(ThreadContext context, Block block) { + public IRubyObject initialize(ThreadContext context, Block block) { checkNotInitialized(); return initializeCommon(context, runtime.getObject(), block); } @JRubyMethod(name = "initialize", visibility = PRIVATE) - public IRubyObject initialize19(ThreadContext context, IRubyObject superObject, Block block) { + public IRubyObject initialize(ThreadContext context, IRubyObject superObject, Block block) { checkNotInitialized(); checkInheritable(superObject); return initializeCommon(context, (RubyClass) superObject, block); @@ -2899,6 +2908,16 @@ public VariableAccessorField getObjectGroupAccessorField() { return variableTableManager.getObjectGroupAccessorField(); } + @Deprecated + public IRubyObject initialize19(ThreadContext context, Block block) { + return initialize(context, block); + } + + @Deprecated + public IRubyObject initialize19(ThreadContext context, IRubyObject superObject, Block block) { + return initialize(context, superObject, block); + } + @Deprecated public IRubyObject invokeFrom(ThreadContext context, CallType callType, IRubyObject caller, IRubyObject self, String name, Block block) { diff --git a/core/src/main/java/org/jruby/RubyDir.java b/core/src/main/java/org/jruby/RubyDir.java index 475908429a0..46155ab5dc5 100644 --- a/core/src/main/java/org/jruby/RubyDir.java +++ b/core/src/main/java/org/jruby/RubyDir.java @@ -85,8 +85,6 @@ public class RubyDir extends RubyObject implements Closeable { private boolean isOpen = true; private Encoding encoding; - private static final Pattern PROTOCOL_PATTERN = Pattern.compile("^(uri|jar|file|classpath):([^:]*:)?//?.*"); - public RubyDir(Ruby runtime, RubyClass type) { super(runtime, type); } @@ -103,13 +101,13 @@ public static RubyClass createDirClass(Ruby runtime) { return dirClass; } - private final void checkDir() { + private void checkDir() { checkDirIgnoreClosed(); if (!isOpen) throw getRuntime().newIOError("closed directory"); } - private final void checkDirIgnoreClosed() { + private void checkDirIgnoreClosed() { testFrozen("Dir"); // update snapshot (if changed) : if (snapshot == null || dir.exists() && dir.lastModified() > lastModified) { diff --git a/core/src/main/java/org/jruby/java/invokers/ConstructorInvoker.java b/core/src/main/java/org/jruby/java/invokers/ConstructorInvoker.java index 404391f611c..7517c9674db 100644 --- a/core/src/main/java/org/jruby/java/invokers/ConstructorInvoker.java +++ b/core/src/main/java/org/jruby/java/invokers/ConstructorInvoker.java @@ -213,7 +213,7 @@ public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule claz return call(context, self, clazz, name, arg0, arg1, arg2); } - private void setAndCacheProxyObject(ThreadContext context, RubyModule clazz, JavaProxy proxy, Object object) { + private static void setAndCacheProxyObject(ThreadContext context, RubyModule clazz, JavaProxy proxy, Object object) { proxy.setObject(object); if (Java.OBJECT_PROXY_CACHE || clazz.getCacheProxy()) { diff --git a/core/src/main/java/org/jruby/java/invokers/RubyToJavaInvoker.java b/core/src/main/java/org/jruby/java/invokers/RubyToJavaInvoker.java index fe55b38eadd..75ffc575774 100644 --- a/core/src/main/java/org/jruby/java/invokers/RubyToJavaInvoker.java +++ b/core/src/main/java/org/jruby/java/invokers/RubyToJavaInvoker.java @@ -161,7 +161,7 @@ void initialize() { } if (varArgs != null /* && varargsMethods.size() > 0 */) { - varargsCallables = (T[]) varArgs.toArray(createCallableArray(varArgs.size())); + varargsCallables = varArgs.toArray(createCallableArray(varArgs.size())); } // NOTE: tested (4, false); with opt_for_space: false but does not // seem to give the promised ~10% improvement in map's speed ... @@ -341,7 +341,7 @@ private static Object convertVarArgumentsOnly(final Class> varArrayType, } static JavaProxy castJavaProxy(final IRubyObject self) { - assert self instanceof JavaProxy : "Java methods can only be invoked on Java objects"; + assert self instanceof JavaProxy : "Java methods can only be invoked on Java objects; got: " + self; return (JavaProxy) self; } diff --git a/core/src/main/java/org/jruby/java/proxies/JavaProxy.java b/core/src/main/java/org/jruby/java/proxies/JavaProxy.java index 78daa90c74a..3709ae35b14 100644 --- a/core/src/main/java/org/jruby/java/proxies/JavaProxy.java +++ b/core/src/main/java/org/jruby/java/proxies/JavaProxy.java @@ -6,10 +6,12 @@ import java.io.ObjectOutputStream; import java.io.Serializable; import java.lang.reflect.Array; +import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.text.MessageFormat; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; @@ -29,10 +31,12 @@ import org.jruby.anno.JRubyMethod; import org.jruby.common.IRubyWarnings; import org.jruby.exceptions.RaiseException; +import org.jruby.java.invokers.ConstructorInvoker; import org.jruby.java.invokers.InstanceFieldGetter; import org.jruby.java.invokers.InstanceFieldSetter; import org.jruby.java.invokers.InstanceMethodInvoker; import org.jruby.java.invokers.MethodInvoker; +import org.jruby.java.invokers.RubyToJavaInvoker; import org.jruby.java.invokers.StaticFieldGetter; import org.jruby.java.invokers.StaticFieldSetter; import org.jruby.java.invokers.StaticMethodInvoker; @@ -655,7 +659,7 @@ public static IRubyObject java_send(ThreadContext context, IRubyObject recv, IRu checkArgSizeMismatch(runtime, 1, argTypesAry); - Class argTypeClass = (Class) argTypesAry.eltInternal(0).toJava(Class.class); + Class argTypeClass = argTypesAry.eltInternal(0).toJava(Class.class); JavaMethod method = new JavaMethod(runtime, getMethodFromClass(context, recv, name, argTypeClass)); return method.invokeStaticDirect(context, arg0.toJava(argTypeClass)); @@ -696,29 +700,37 @@ public static IRubyObject java_alias(ThreadContext context, IRubyObject clazz, I } @JRubyMethod(meta = true, visibility = Visibility.PRIVATE) - public static IRubyObject java_alias(ThreadContext context, IRubyObject clazz, IRubyObject newName, IRubyObject rubyName, IRubyObject argTypes) { + public static IRubyObject java_alias(ThreadContext context, IRubyObject klass, IRubyObject newName, IRubyObject rubyName, IRubyObject argTypes) { final Ruby runtime = context.runtime; - if ( ! ( clazz instanceof RubyModule ) ) { - throw runtime.newTypeError(clazz, runtime.getModule()); + if ( ! ( klass instanceof RubyModule ) ) { + throw runtime.newTypeError(klass, runtime.getModule()); } - final RubyModule proxyClass = (RubyModule) clazz; + final RubyModule proxyClass = (RubyModule) klass; String name = rubyName.asJavaString(); String newNameStr = newName.asJavaString(); - RubyArray argTypesAry = argTypes.convertToArray(); - Class>[] argTypesClasses = (Class[]) argTypesAry.toArray(new Class[argTypesAry.size()]); - - final Method method = getMethodFromClass(context, clazz, name, argTypesClasses); - final MethodInvoker invoker; - - if ( Modifier.isStatic( method.getModifiers() ) ) { - invoker = new StaticMethodInvoker(proxyClass.getMetaClass(), () -> arrayOf(method), newNameStr); - // add alias to meta - proxyClass.getSingletonClass().addMethod(newNameStr, invoker); - } - else { - invoker = new InstanceMethodInvoker(proxyClass, () -> arrayOf(method), newNameStr); - proxyClass.addMethod(newNameStr, invoker); + Class>[] argTypesClasses = (Class[]) argTypes.convertToArray().toArray(ClassUtils.EMPTY_CLASS_ARRAY); + + final Class> clazz = JavaUtil.getJavaClass(proxyClass); + final RubyToJavaInvoker invoker; + switch (name) { + case "