2011-02-03 96 views
1

使用JRuby 1.6.0RC1的JRuby +没有公共构造

我有一个像

package com.foo.bar 

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

如果在JRuby中,我做

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

然后我得到

的Java文件
TypeError: no public constructors for Java::ComFooBar::Foo 

阅读http://jira.codehaus.org/browse/JRUBY-5009让我这是WAD的事情,但我如何解决这个问题而不改变java文件?

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

ArgumentError: Constructor invocation failed: tried to access method com.foo.bar.Foo.(Ljava/lang/String;)V from class 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 

回答

0

在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

+0

这远非一个完整的解决方案,但它是最接近我,所以我会接受它的人的。 – yxhuvud 2011-02-07 11:49:04

3

有确实没有公共构造了点。构造函数是包级别。

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

如果没有,你可以做一个公共工厂类在包,可能在Java中,有可能在Ruby中,并从那里调用此构造。

您可能还能够猴子补丁添加红宝石访问的构造函数或工厂方法,而无需修改Java源代码。

相关问题