New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Overriding "respond_to?" in java fails to be recognized #7154
Comments
Moving description of the issue originally captured in protocolbuffers/protobuf#9668 here. JRuby Version: 9.3.3.0 Given a JRuby class defined in Java e.g. import org.jruby.anno.JRubyMethod;
import org.jruby.anno.JRubyClass;
import org.jruby.RubyObject;
import org.jruby.Ruby;
import org.jruby.RubyClass;
import org.jruby.RubyModule;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.Block;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.load.BasicLibraryService;
public class RespondToJavaService implements BasicLibraryService {
@Override
public boolean basicLoad(Ruby ruby) throws IOException {
ruby.defineModule("Foo").defineClassUnder("Bar", ruby.getObject(), new ObjectAllocator() {
@Override
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
return new RespondTo(runtime, klazz);
}
}).defineAnnotatedMethods(RespondTo.class);
return true;
}
@JRubyClass(name = "RespondTo")
public static class RespondTo extends RubyObject {
public RespondTo(Ruby runtime, RubyClass klazz) {
super(runtime, klazz);
}
@JRubyMethod(name = "respond_to?", required = 1, optional = 1)
public IRubyObject respondTo(ThreadContext context, IRubyObject[] args) {
System.err.println("Custom repond_to? got called!");
return Helpers.invokeSuper(context, this, metaClass, "respond_to?", args, Block.NULL_BLOCK);
}
}
} The same behavior is observed when binding a static method: import java.io.IOException;
import org.jruby.anno.JRubyMethod;
import org.jruby.anno.JRubyClass;
import org.jruby.RubyObject;
import org.jruby.Ruby;
import org.jruby.RubyClass;
import org.jruby.RubyModule;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.Block;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.load.BasicLibraryService;
public class RespondToJavaService implements BasicLibraryService {
@Override
public boolean basicLoad(Ruby ruby) throws IOException {
ruby.defineModule("Foo").defineClassUnder("Bar", ruby.getObject(), new ObjectAllocator() {
@Override
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
return new RespondTo(runtime, klazz);
}
}).defineAnnotatedMethods(RespondTo.class);
return true;
}
@JRubyClass(name = "RespondTo")
public static class RespondTo extends RubyObject {
public RespondTo(Ruby runtime, RubyClass klazz) {
super(runtime, klazz);
}
@JRubyMethod(name = "respond_to?", required = 1, optional = 1)
public static IRubyObject respondTo(ThreadContext context, IRubyObject self, IRubyObject[] args) {
System.err.println("Custom repond_to? got called!");
String methodName = args[0].asJavaString();
return self.getMetaClass().respondsToMethod(methodName, true) ? context.runtime.getTrue() : context.runtime.getFalse();
}
}
} *** What did you expect to see *** What did you see instead? |
@headius suggested the following workaround that explicitly sets import java.io.IOException;
import org.jruby.anno.JRubyMethod;
import org.jruby.anno.JRubyClass;
import org.jruby.RubyObject;
import org.jruby.Ruby;
import org.jruby.RubyClass;
import org.jruby.RubyModule;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.Block;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.load.BasicLibraryService;
public class RespondToJavaService implements BasicLibraryService {
@Override
public boolean basicLoad(Ruby ruby) throws IOException {
RubyClass bar = ruby.defineModule("Foo").defineClassUnder("Bar", ruby.getObject(), new ObjectAllocator() {
@Override
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
return new RespondTo(runtime, klazz);
}
});
bar.defineAnnotatedMethods(RespondTo.class);
bar.searchMethod("respond_to?").setIsBuiltin(false);
return true;
}
@JRubyClass(name = "RespondTo")
public static class RespondTo extends RubyObject {
public RespondTo(Ruby runtime, RubyClass klazz) {
super(runtime, klazz);
}
@JRubyMethod(name = "respond_to?", required = 1, optional = 1)
public IRubyObject respondTo(ThreadContext context, IRubyObject[] args) {
System.err.println("Custom repond_to? got called!");
return Helpers.invokeSuper(context, this, metaClass, "respond_to?", args, Block.NULL_BLOCK);
}
}
} |
The original purpose of isBuiltin was to allow us to detect when a dynamically-acquired method is actually the implementation we shipped in a core JRuby class, to enable us to customize related logic specific to how we know the JRuby implementation works. This PR codifies that relationship, only setting methods to be isBuiltin if they are constructed and bound during the core boot process of JRuby itself. In the future we will entertain more descriptive metadata for such methods, but for now this narrows isBuiltin just enough to avoid third-party extensions running into issues. Fixes jruby#7154
The original purpose of isBuiltin was to allow us to detect when a dynamically-acquired method is actually the implementation we shipped in a core JRuby class, to enable us to customize related logic specific to how we know the JRuby implementation works. This PR codifies that relationship, only setting methods to be isBuiltin if they are constructed and bound during the core boot process of JRuby itself. In the future we will entertain more descriptive metadata for such methods, but for now this narrows isBuiltin just enough to avoid third-party extensions running into issues. Fixes jruby#7154
This should be fixed by #7156 for JRuby 9.3.5 and future versions. |
Perhaps someone could contribute a test case for this and |
Coming these issues in the protobuf project (environment details inside).
Is this something that the jruby team can help unblock?
The text was updated successfully, but these errors were encountered: