按class.forname从java加载jruby类

vc6uscn9  于 2021-06-30  发布在  Java
关注(0)|答案(3)|浏览(317)

我有以下java代码类:

public class CHRTreeCreator extends IndexCreator { ... }

相反 CHRTreeCreator 我想使用不同的实现,这也扩展了 IndexCreator ,但我想在jruby中编写它。问题是,具体执行 IndexCreator 基于xml配置文件选择:

<creator>dwe.index.tree.chr.CHRTreeCreator</creator>

代码如下所示:

// className is fetched from XML
Class creatorClass = Class.forName(className);
Constructor constructor = creatorClass.getConstructor(new Class[] {  });
creator = (IndexCreator) constructor.newInstance(new Object[] { });

问题是,有没有可能在ruby中实现它,比如:

class MyIndexCreator < IndexCreator
end

不知怎的 MyIndexCreator 将类名转换为xml配置文件。在这种情况下,模块包Map是如何工作的?
如果不能用java的class.forname加载ruby类,我应该如何解决这个问题?

xqkwcwgp

xqkwcwgp1#

目前,jruby子类不能通过java以这种方式访问,尽管它在未来的实现中有一定的容量(也许是JRuby1.5)。
一个选项(取决于类的api)是创建委托:

public class RubyIndexCreator extends IndexCreator {
  private IndexCreator rubyCreator;
  public RubyIndexCreator() {
    ScriptEngineManager factory = new ScriptEngineManager();
    ScriptEngine engine = factory.getEngineByName("ruby");
    FileReader r = new FileReader("ruby_index_creator.rb");
    try {
      rubyCreator = engine.eval(r);
    }
    finally {
      r.close();
    }
  }

  public Object create(String someArg) {
    return rubyCreator.create(someArg);
  }
}

我已经忽略了一些缓存的机会,也只是简单地描述了如何管理文件读取器,但希望您能够理解。
在这个例子中, ruby_index_creator.rb 将实现您的index creator类,然后返回它的一个示例—显然,从这里您可以引用其他ruby文件,并根据需要进行组织:

class MyIndexer < IndexCreator
 [...]
end
MyIndexer.new

就这样!

omqzjyyz

omqzjyyz2#

或者,您可以利用ruby的开放类,直接修改chrtreecreator的行为(而不是子类)。

x0fgdtte

x0fgdtte3#

使用ruby eval如何:

C:\>jirb
irb(main):001:0> require 'java'
=> false
irb(main):002:0> class MyDate < Java::JavaUtil::Date
irb(main):003:1> def my_method;puts "hi there";end
irb(main):004:1> end
=> nil
irb(main):005:0>
irb(main):006:0* c = "MyDate"
=> "MyDate"
irb(main):007:0> obj = eval("#{c}.new")
=> #<MyDate:0xd2efa1>
irb(main):008:0> obj.my_method
hi there
=> nil
irb(main):009:0>

相关问题