JRuby调用了错误的方法

发布于 2024-11-14 06:49:58 字数 1249 浏览 4 评论 0原文

我在从 JRuby 调用 Java 方法时遇到了一个奇怪的问题。

在我的 Java 类中,这些方法定义了两次,看来 JRuby 调用了错误的方法。

所以我尝试使用java_method,但我总是得到:

类型错误:无法将类 org.jruby.RubyModule 的实例转换为类 java.lang.Class

这是我的 Java 代码:

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);
    }
}

和我的 JRuby 代码:

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

我也尝试过使用 java_send 但遇到了相同的错误:

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

接下来,我尝试使用:

渲染器.add_renderer(TextRenderer.new.to_java(IElementRenderer))

这次没有错误,但调用了错误的方法......

我该如何解决这个问题?

I got a strange problem with a call 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

倒数 2024-11-21 06:49:58

您可以使用 java.lang.Class.for_name 修复 cannot conversion instant of class org.jruby.RubyModule to class java.lang.Class

在您的情况下,它是

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

This是因为 java 接口默认成为 Ruby 模块,并且 :java_method 的第二个参数需要一个 Class 对象数组。

您可以打印匹配的方法以查看它是否与预期的方法匹配。
例如,我看到下面的代码与 System.out 上的 println(String) 匹配。

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

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)>
夏见 2024-11-21 06:49:58

我以前也遇到过这样的问题。这是很多版本之前的事了,我认为 JRuby 的方法匹配算法随着时间的推移已经得到了改进。您使用的是最新的 JRuby 吗?

如果没有其他方法,您可能需要添加另一个方法或包装类。通过名称或参数数量(而不仅仅是参数类型)来区分方法的东西。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文