开发者

JRuby calls the wrong method

开发者 https://www.devze.com 2023-03-10 04:52 出处:网络
I got a strange problem with a call 开发者_JAVA百科to a Java method from JRuby. In my Java class these methods are defined twice, and it appears JRuby calls the wrong one.

I got a strange problem with a call 开发者_JAVA百科to a Java method from JRuby.

In my Java class these methods are defined twice, and it appears JRuby calls the wrong one.

So I tried to use java_method, but I always got a:

TypeError: cannot convert instance of class org.jruby.RubyModule to class java.lang.Class

Here's my Java code:

public class Renderer {

    ...
    public void addRenderer(IElementRenderer r) {
        System.out.println("Added element render: " + r.getClass().toString());

        basicRenderers.add(r);
        rendererMap.put(r.elementClass(), r);
    }

    public void addRenderer(IBasicRenderer r) {
        System.out.println("SHOULD NOT GO THERE !!");
        basicRenderers.add(r);
    }
}

and my JRuby code:

add_renderer = renderer.java_method :add_renderer, [Java::dragon.render.IElementRenderer]
add_renderer.call TextRenderer.new

I also tried with java_send but I got the same error:

renderer.java_send(:add_renderer, [Java::dragon.render.IElementRenderer], TextRenderer.new)

Next, I tried with:

renderer.add_renderer(TextRenderer.new.to_java(IElementRenderer))

This time no errors but the wrong method is called ...

How can I fix this problem?


You can fix that cannot convert instance of class org.jruby.RubyModule to class java.lang.Class using java.lang.Class.for_name

In your case, it is

add_renderer = renderer.java_method :add_renderer, [java.lang.Class.for_name("dragon.render.IElementRenderer")]

This is because java interfaces become Ruby Modules by default and the second argument to :java_method expects an array of Class objects.

You can print the matched method to see it is matching the intended method. For example, I see below code is matching the println(String) on System.out.

>>java.lang.System.out.java_method "println", [java.lang.Class.for_name("java.lang.String")]
#<Method: Java::JavaIo::PrintStream#(java.lang.String)>


I've had problems like this before. It was many versions ago and I think JRuby's method matching algorithm has improvedd over time. Are you using the latest JRuby?

If nothing else works, you may need to add another method, or a wrapper class. Something that distinguishes your methods by name or number of parameters, not just parameter type.

0

精彩评论

暂无评论...
验证码 换一张
取 消