undefined method `__ruby_object' for interface implementation #1184

Closed
headius opened this Issue Oct 29, 2013 · 2 comments

3 participants

@headius
JRuby Team member

Original bug: https://jira.codehaus.org/browse/JRUBY-7150
Filed by @donv

I could use some help in figuring this out. Any help is greatly appreciated.

When unregistering a previously registered LocationListener we get the exception listed below. The code for the application is in the Ruboto GPS tutorial: https://github.com/ruboto/ruboto/wiki/Tutorial%3A-get-current-gps-position

I am not sure wether this is a regression or not. The example was originally written a long time ago, and I think it worked fine then :)

W/System.err(10698): org.jruby.exceptions.RaiseException: (NoMethodError) undefined method `__ruby_object' for #<MyLocationListener:0x42e6cc00>
W/System.err(10698):    at dalvik.system.VMStack.getThreadStackTrace(Native Method)
W/System.err(10698):    at java.lang.Thread.getStackTrace(java/lang/Thread.java:591)
W/System.err(10698):    at org.jruby.runtime.backtrace.TraceType$Gather.getBacktraceData(org/jruby/runtime/backtrace/TraceType.java:171)
W/System.err(10698):    at org.jruby.runtime.backtrace.TraceType.getBacktrace(org/jruby/runtime/backtrace/TraceType.java:39)
W/System.err(10698):    at org.jruby.RubyException.prepareBacktrace(org/jruby/RubyException.java:215)
W/System.err(10698):    at org.jruby.exceptions.RaiseException.preRaise(org/jruby/exceptions/RaiseException.java:214)
W/System.err(10698):    at org.jruby.exceptions.RaiseException.preRaise(org/jruby/exceptions/RaiseException.java:195)
W/System.err(10698):    at org.jruby.exceptions.RaiseException.<init>(org/jruby/exceptions/RaiseException.java:141)
W/System.err(10698):    at org.jruby.exceptions.RaiseException.<init>(org/jruby/exceptions/RaiseException.java:74)
W/System.err(10698):    at org.jruby.RubyKernel.methodMissingDirect(org/jruby/RubyKernel.java:272)
W/System.err(10698):    at org.jruby.RubyBasicObject.method_missing19(org/jruby/RubyBasicObject.java:1652)
W/System.err(10698):    at org.jruby.internal.runtime.methods.DynamicMethod.call(org/jruby/internal/runtime/methods/DynamicMethod.java:208)
W/System.err(10698):    at org.jruby.internal.runtime.methods.AliasMethod.call(org/jruby/internal/runtime/methods/AliasMethod.java:86)
W/System.err(10698):    at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(org/jruby/runtime/callsite/CachingCallSite.java:336)
W/System.err(10698):    at org.jruby.runtime.callsite.CachingCallSite.callBlock(org/jruby/runtime/callsite/CachingCallSite.java:179)
W/System.err(10698):    at org.jruby.runtime.callsite.CachingCallSite.call(org/jruby/runtime/callsite/CachingCallSite.java:183)
W/System.err(10698):    at org.jruby.ast.FCallSpecialArgBlockPassNode.interpret(org/jruby/ast/FCallSpecialArgBlockPassNode.java:38)
W/System.err(10698):    at org.jruby.ast.NewlineNode.interpret(org/jruby/ast/NewlineNode.java:105)
W/System.err(10698):    at org.jruby.ast.BlockNode.interpret(org/jruby/ast/BlockNode.java:71)
W/System.err(10698):    at org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(org/jruby/evaluator/ASTInterpreter.java:75)
W/System.err(10698):    at org.jruby.internal.runtime.methods.InterpretedMethod.call(org/jruby/internal/runtime/methods/InterpretedMethod.java:112)
W/System.err(10698):    at org.jruby.javasupport.util.RuntimeHelpers$MethodMissingMethod.call(org/jruby/javasupport/util/RuntimeHelpers.java:445)
W/System.err(10698):    at org.jruby.javasupport.util.RuntimeHelpers.callMethodMissing(org/jruby/javasupport/util/RuntimeHelpers.java:372)
W/System.err(10698):    at org.jruby.RubyClass.finvoke(org/jruby/RubyClass.java:720)
W/System.err(10698):    at org.jruby.javasupport.util.RuntimeHelpers.invoke(org/jruby/javasupport/util/RuntimeHelpers.java:505)
W/System.err(10698):    at org.jruby.javasupport.Java$7.invoke(org/jruby/javasupport/Java.java:1228)
W/System.err(10698):    at $Proxy0.__ruby_object(Native Method)
W/System.err(10698):    at org.jruby.javasupport.JavaUtil.trySimpleConversions(org/jruby/javasupport/JavaUtil.java:475)
W/System.err(10698):    at org.jruby.javasupport.JavaUtil.convertJavaToUsableRubyObject(org/jruby/javasupport/JavaUtil.java:161)
W/System.err(10698):    at org.jruby.javasupport.JavaUtil.convertJavaArrayToRuby(org/jruby/javasupport/JavaUtil.java:95)
W/System.err(10698):    at org.jruby.javasupport.Java$7.invoke(org/jruby/javasupport/Java.java:1226)
W/System.err(10698):    at $Proxy0.equals(Native Method)
W/System.err(10698):    at java.util.HashMap.remove(java/util/HashMap.java:626)
W/System.err(10698):    at android.location.LocationManager.removeUpdates(android/location/LocationManager.java:1012)
W/System.err(10698):    at java.lang.reflect.Method.invokeNative(Native Method)
W/System.err(10698):    at java.lang.reflect.Method.invoke(java/lang/reflect/Method.java:511)
W/System.err(10698):    at org.jruby.javasupport.JavaMethod.invokeDirectWithExceptionHandling(org/jruby/javasupport/JavaMethod.java:455)
W/System.err(10698):    at org.jruby.javasupport.JavaMethod.invokeDirect(org/jruby/javasupport/JavaMethod.java:316)
W/System.err(10698):    at org.jruby.java.invokers.InstanceMethodInvoker.call(org/jruby/java/invokers/InstanceMethodInvoker.java:61)
W/System.err(10698):    at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(org/jruby/runtime/callsite/CachingCallSite.java:326)
W/System.err(10698):    at org.jruby.runtime.callsite.CachingCallSite.call(org/jruby/runtime/callsite/CachingCallSite.java:170)
W/System.err(10698):    at org.jruby.ast.CallOneArgNode.interpret(org/jruby/ast/CallOneArgNode.java:57)
W/System.err(10698):    at org.jruby.ast.NewlineNode.interpret(org/jruby/ast/NewlineNode.java:105)
W/System.err(10698):    at org.jruby.ast.BlockNode.interpret(org/jruby/ast/BlockNode.java:71)
W/System.err(10698):    at org.jruby.ast.RescueNode.executeBody(org/jruby/ast/RescueNode.java:224)
W/System.err(10698):    at org.jruby.ast.RescueNode.interpret(org/jruby/ast/RescueNode.java:119)
W/System.err(10698):    at org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(org/jruby/evaluator/ASTInterpreter.java:75)
W/System.err(10698):    at org.jruby.internal.runtime.methods.InterpretedMethod.call(org/jruby/internal/runtime/methods/InterpretedMethod.java:139)
W/System.err(10698):    at org.jruby.RubyClass.finvoke(org/jruby/RubyClass.java:674)
W/System.err(10698):    at org.jruby.javasupport.util.RuntimeHelpers.invoke(org/jruby/javasupport/util/RuntimeHelpers.java:493)
W/System.err(10698):    at org.jruby.embed.internal.EmbedRubyObjectAdapterImpl.callEachType(org/jruby/embed/internal/EmbedRubyObjectAdapterImpl.java:351)
W/System.err(10698):    at org.jruby.embed.internal.EmbedRubyObjectAdapterImpl.call(org/jruby/embed/internal/EmbedRubyObjectAdapterImpl.java:306)
W/System.err(10698):    at org.jruby.embed.internal.EmbedRubyObjectAdapterImpl.runRubyMethod(org/jruby/embed/internal/EmbedRubyObjectAdapterImpl.java:276)
W/System.err(10698):    at org.jruby.embed.ScriptingContainer.runRubyMethod(org/jruby/embed/ScriptingContainer.java:1546)
W/System.err(10698):    at java.lang.reflect.Method.invokeNative(Native Method)
W/System.err(10698):    at java.lang.reflect.Method.invoke(java/lang/reflect/Method.java:511)
W/System.err(10698):    at org.ruboto.JRubyAdapter.runRubyMethod(org/ruboto/JRubyAdapter.java:148)
W/System.err(10698):    at org.ruboto.RubotoActivity.onPause(org/ruboto/RubotoActivity.java:1143)
W/System.err(10698):    at org.ruboto.EntryPointActivity.onPause(org/ruboto/EntryPointActivity.java:88)
W/System.err(10698):    at android.app.Activity.performPause(android/app/Activity.java:5304)
W/System.err(10698):    at android.app.Instrumentation.callActivityOnPause(android/app/Instrumentation.java:1229)
W/System.err(10698):    at android.app.ActivityThread.performPauseActivity(android/app/ActivityThread.java:2866)
W/System.err(10698):    at android.app.ActivityThread.performPauseActivity(android/app/ActivityThread.java:2835)
W/System.err(10698):    at android.app.ActivityThread.handlePauseActivity(android/app/ActivityThread.java:2813)
W/System.err(10698):    at android.app.ActivityThread.access$800(android/app/ActivityThread.java:140)
W/System.err(10698):    at android.app.ActivityThread$H.handleMessage(android/app/ActivityThread.java:1244)
W/System.err(10698):    at android.os.Handler.dispatchMessage(android/os/Handler.java:99)
W/System.err(10698):    at android.os.Looper.loop(android/os/Looper.java:137)
W/System.err(10698):    at android.app.ActivityThread.main(android/app/ActivityThread.java:4898)
W/System.err(10698):    at java.lang.reflect.Method.invokeNative(Native Method)
W/System.err(10698):    at java.lang.reflect.Method.invoke(java/lang/reflect/Method.java:511)
W/System.err(10698):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(com/android/internal/os/ZygoteInit.java:1006)
W/System.err(10698):    at com.android.internal.os.ZygoteInit.main(com/android/internal/os/ZygoteInit.java:773)
W/System.err(10698):    at dalvik.system.NativeStart.main(Native Method)
@headius
JRuby Team member

Comment by @donv:

Calls to hasCode, equals, and __ruby_object are being forwarded to the Ruby class, while I think they should be handled by the proxy.

Comment by @headius:

Ok...looks like the logic involved with defining __ruby_object does so to have a reference to the real "self" that goes with a proxy type, and the call that fails is coming from JavaUtils.trySimpleConversions attempting to call that method.
trySimpleConversions would only call this method if the incoming object is not an IRubyObject instance. I'm not sure what code path leads to this particular scenario.
I notice in the implementation of MyLocationListener, you do not directly implement the interface. Is there a reason for that? Is there some other code I should look at to see how the failing type is defined?

Comment by @donv

Thanks for looking into this.
The call comes from the Android framework checking if the object exists in a HashMap. "equals" is called with an arbitrary other object in the HashMap, so we have no control over that.
We do not directly implement the interface (using "include" i presume) since we did not detect that it made any difference. Should we do that? Will it make a difference?
The complete example is included in the link given above.

@donv
JRuby Team member

Hi @headius @enebo !

I think I have found the problem, and I have at least one part of the solution. In org.jruby.javasupport.Java lines starting at 1207 "==" is used to test for methodName. Changing this to ".equals" fixes the immediate problem.

I addition to this, I think the "WTF" is right. We should call toString, hashCode and equals on the Ruby object, not the class. I can change it if you agree.

@jrubyci jrubyci pushed a commit that referenced this issue Dec 30, 2013
@donv donv * Closes #1184 undefined method `__ruby_object' for interface impleme…
…ntation

* Use #equals instead of == to compare the method name String objects since == will return false if the String objects have the same content, but are different instances.
9ca8c3f
@jrubyci jrubyci pushed a commit that closed this issue Dec 30, 2013
@donv donv * Closes #1184 undefined method `__ruby_object' for interface impleme…
…ntation

* Use #equals instead of == to compare the method name String objects since == will return false if the String objects have the same content, but are different instances.
3cb3621
@jrubyci jrubyci closed this in 3cb3621 Dec 30, 2013
@enebo enebo modified the milestone: JRuby 1.7.10, JRuby 1.7.11 Feb 24, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment