【问题标题】:jruby + no public constructorjruby + 没有公共构造函数
【发布时间】:2011-06-01 10:28:17
【问题描述】:

使用 JRuby 1.6.0RC1

我有一个类似的 java 文件

package com.foo.bar

public class Foo
{
Foo(String baz){}
}

如果,在 jruby 中,我会这样做

com.foo.bar.Foo.new "foo"

然后我得到

TypeError: no public constructors for Java::ComFooBar::Foo

阅读http://jira.codehaus.org/browse/JRUBY-5009 让我觉得这是 WAD,但是如何在不更改 java 文件的情况下解决这个问题?

子类化 Foo 然后实例化我得到一个不同的错误:

ArgumentError:构造函数 调用失败:试图访问 方法 com.foo.bar.Foo.(Ljava/lang/String;)V 从班级 org.jruby.proxy.com.foo.bar.Foo$Proxy0

编辑:

在 Headius 对 IRC 的帮助下,它得以工作。以下工作,但可能更智能:

 def package_local_constructor klass,*values
    constructors = klass.java_class.declared_constructors
    constructors.each do |c|
      c.accessible = true
      begin
        return c.new_instance(*values).to_java
      rescue TypeError 
        false
      end
    end
    raise TypeError,"found no matching constructor for " + klass.to_s + "(" + value.class + ")"
  end

【问题讨论】:

    标签: java ruby jruby


    【解决方案1】:

    确实没有为此的公共构造函数。构造函数是包级别的。

    com.foo.bar 之外的其他Java 类如何获取这种类型的对象?可能该包中已经有一个工厂,它通过调用包范围的构造函数来生成此类,并且您可以从 JRuby 中调用它。

    如果没有,您可以在该包中创建一个公共工厂类,可能在 Java 中,可能在 Ruby 中,然后从那里调用此构造函数。

    您还可以通过猴子补丁添加一个 ruby​​ 可访问的构造函数或工厂方法,而无需修改 Java 源代码。

    【讨论】:

      【解决方案2】:

      这是因为构造函数具有包级别的访问权限。

      您可以尝试在与 foo 类相同的包中定义您的 ruby​​ 类。

      见:Assigning a Java package to a JRuby class

      【讨论】:

      • 我相信这应该是正确的方法,但它似乎不起作用。
      • 作为参考,我在 groovy 中尝试过同样的事情,而要能够实例化类,我唯一​​要做的就是导入包。但这在这里没有区别。
      【解决方案3】:

      在 Java 中,您可以使用反射 API 执行以下操作:

      Constructor constructor = MyClass.class.getConstructor(Class ... paramTypes);
      constructor.setAccessible(true);
      MyClass myClass = (MyClass)constructor.newInstance(Object ... args);
      

      不确定你可以在 JRuby 中做到这一点,但我想你可以做到。

      对此有一个 oracle 指南:http://download.oracle.com/javase/tutorial/reflect/member/ctorInstance.html

      【讨论】:

      • 这远不是一个完整的解决方案,但它是我得到的最接近的解决方案,所以我会接受它。
      【解决方案4】:

      猜猜唯一的修复是你提出的那个,或者“从 ruby​​ 类中删除你的初始化程序”(这可能是 jruby 中的一个错误——无论如何它不应该调用它的祖先吗?)或“让 java类初始化程序受保护的访问” [我不知道为什么 jruby 如此鄙视包级别]。

      http://betterlogic.com/roger/2011/05/javajavamirah-woe/comment-page-1/#comment-5034

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-07-10
        • 2011-02-08
        • 2017-04-30
        • 1970-01-01
        • 2011-03-01
        • 1970-01-01
        • 2012-02-27
        • 1970-01-01
        相关资源
        最近更新 更多