[英]jruby + no public constructor
使用JRuby 1.6.0RC1
我有一個像
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:構造函數調用失敗:嘗試從類org.jruby.proxy.com.foo.bar.Foo $ Proxy0訪問方法com.foo.bar.Foo。(Ljava / lang / String;)V
編輯:
通過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
確實沒有為此的公共構造函數。 構造函數是程序包級別的。
包com.foo.bar
之外的其他Java類如何獲取這種類型的對象? 該包中可能已經存在一個工廠,可以通過調用包作用域的構造函數來生成此類,並且可以從JRuby調用該工廠。
如果沒有,您可以在該程序包中創建一個公共工廠類,可能使用Java,也可能使用Ruby,然后從那里調用此構造函數。
您還可以通過猴子補丁添加紅寶石可訪問的構造函數或工廠方法,而無需修改Java源代碼。
在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
猜猜唯一的修補程序是您提出的修補程序,或者是“從ruby類中刪除您的初始化程序”(這可能是jruby中的錯誤-無論如何,它都不應該調用其祖先嗎?)或“使Java類初始化程序受到保護”訪問” [我不確定jruby為什么如此輕視軟件包級別]。
http://betterlogic.com/roger/2011/05/javajavamirah-woe/comment-page-1/#comment-5034
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.