简体   繁体   English

jruby +没有公共构造函数

[英]jruby + no public constructor

Using JRuby 1.6.0RC1 使用JRuby 1.6.0RC1

I've got a java file like 我有一个像

package com.foo.bar

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

If, in jruby, I do 如果在jruby中,我愿意

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

then I get 然后我得到

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

Reading http://jira.codehaus.org/browse/JRUBY-5009 makes me thing this is WAD, but how do I get around the problem without altering the java file? 阅读http://jira.codehaus.org/browse/JRUBY-5009使我知道这是WAD,但是如何在不更改Java文件的情况下解决该问题?

Subclassing Foo and then instantiating I get a different error: 子类化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 ArgumentError:构造函数调用失败:尝试从类org.jruby.proxy.com.foo.bar.Foo $ Proxy0访问方法com.foo.bar.Foo。(Ljava / lang / String;)V

EDIT: 编辑:

Got it to work through help from Headius on IRC. 通过Headius在IRC上的帮助使它起作用。 The following works, but could possibly be more intelligent: 以下工作可行,但可能更智能:

 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

There indeed is no public constructor for that. 确实没有为此的公共构造函数。 The constructor is package level. 构造函数是程序包级别的。

How do other Java classes outside the package com.foo.bar acquire objects of this type? com.foo.bar之外的其他Java类如何获取这种类型的对象? It may be there is already a factory in that package that produces this class by calling the package-scoped constructor, and that you could call from JRuby. 该包中可能已经存在一个工厂,可以通过调用包作用域的构造函数来生成此类,并且可以从JRuby调用该工厂。

If not, you could make a public factory class in that package, possibly in Java, possibly in Ruby, and call this constructor from there. 如果没有,您可以在该程序包中创建一个公共工厂类,可能使用Java,也可能使用Ruby,然后从那里调用此构造函数。

You might also be able to monkey-patch to add a ruby-accessible constructor or factory method, without having to modify the Java source. 您还可以通过猴子补丁添加红宝石可访问的构造函数或工厂方法,而无需修改Java源代码。

That's because the constructor is has package level access. 这是因为构造函数具有包级别的访问权限。

You could try to define your ruby class in the same package as the foo class. 您可以尝试在与foo类相同的包中定义ruby类。

See: Assigning a Java package to a JRuby class 请参阅: 将Java包分配给JRuby类

In Java you can use the reflection API to do something like: 在Java中,您可以使用反射API来执行以下操作:

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

Not sure you can do that in JRuby, but I'd imagine you could. 不确定您可以在JRuby中做到这一点,但我想您可以做到。

There's an oracle guide to this: http://download.oracle.com/javase/tutorial/reflect/member/ctorInstance.html 对此有一个oracle指南: http : //download.oracle.com/javase/tutorial/reflect/member/ctorInstance.html

Guess the only fixes are the one you proposed, or "remove your initializer from the ruby class" (which may be a bug in jruby--shouldn't it call its ancestor no matter what?) or "make the java class initializer protected access" [I'm not sure why jruby disdains package level so much]. 猜猜唯一的修补程序是您提出的修补程序,或者是“从ruby类中删除您的初始化程序”(这可能是jruby中的错误-无论如何,它都不应该调用其祖先吗?)或“使Java类初始化程序受到保护”访问” [我不确定jruby为什么如此轻视软件包级别]。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM