I'm having some troubles overriding a java method from a jruby class. Since JRuby exposes java methods with both camel and snake case syntaxes, i've tried both approaches to override the same method, but i'm having strange results:
JAVA
package tabaqui;
class MyJavaClass {
public void myMethod() {
System.out.println("Java method");
}
public void invokeMyMethod() {
myMethod();
}
}
RUBY
class MyRubyClass1 < Java::tabaqui.MyJavaClass
def my_method
puts "Ruby method from MyRubyClass1\n";
end
end
class MyRubyClass2 < Java::tabaqui.MyJavaClass
def myMethod
puts "Ruby method from MyRubyClass2\n";
end
end
a = MyRubyClass1.new
a.my_method #output: "Ruby method from MyRubyClass1"
a.invoke_my_method #output: "Java method"
b = MyRubyClass2.new
b.my_method #output: "Java method"
b.invoke_my_method #output: "Ruby method from MyRubyClass2"
The only solution i've found to obtain the expected result (ruby methods invoked in every case) is giving the overridden method an alias after defining it in ruby:
alias_method :myMethod, :my_method
Am i doing something wrong?
while confusing at first sight, this is "expected" once you understand alias ...
MyJavaClass#myMethod
will have a my_method
alias setup by the JRuby runtime.
in MyRubyClass1
you redefined my_method
(alias) thus seeing the expected output.
however you did not override myMethod
-> the convention does not work backwards.
while in MyRubyClass2
you redefined myMethod
so it ends up doing virtual Java dispatch from invokeMyMethod()
, es expected.
while this might seem confusing its how it is, the Java alias conventions are really there for "bare" consumers. while if you're extending a Java class you should stick to proper Java names. there's room for improvement here to re-define Java aliases once a proxy class is generated, although it might be a breaking change.