按Class.forName从Java加载JRuby类
我有以下Java代码类:按Class.forName从Java加载JRuby类,java,jruby,classloader,Java,Jruby,Classloader,我有以下Java代码类: public class CHRTreeCreator extends IndexCreator { ... } 相反,CHRTreeCreator我想使用不同的实现,它也扩展了IndexCreator,但我想在JRuby中对其进行编码。问题是,IndexCreator的具体实现是基于xml配置文件选择的: <creator>dwe.index.tree.chr.CHRTreeCreator</creator> 问题是,是否可以在Ruby中实
public class CHRTreeCreator extends IndexCreator { ... }
相反,CHRTreeCreator
我想使用不同的实现,它也扩展了IndexCreator
,但我想在JRuby中对其进行编码。问题是,IndexCreator
的具体实现是基于xml配置文件选择的:
<creator>dwe.index.tree.chr.CHRTreeCreator</creator>
问题是,是否可以在Ruby中实现它,如下所示:
// className is fetched from XML
Class creatorClass = Class.forName(className);
Constructor constructor = creatorClass.getConstructor(new Class[] { });
creator = (IndexCreator) constructor.newInstance(new Object[] { });
class MyIndexCreator < IndexCreator
end
类MyIndexCreator
并以某种方式将MyIndexCreator
类名放入XML配置文件中。在这种情况下,模块包映射是如何工作的
如果无法通过Java的Class.forName加载Ruby类,我应该如何解决这个问题 另一种选择是,您可以利用Ruby的开放类,直接修改chrtecreator的行为(而不是子类)。使用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>
C:\>jirb
irb(主):001:0>需要“java”
=>错误
irb(main):002:0>classmydate定义我的方法;把“你好”;终止
irb(主):004:1>结束
=>零
irb(主要):005:0>
irb(主):006:0*c=“我的日期”
=>“我的日期”
irb(main):007:0>obj=eval(“{c}.new”)
=> #
irb(main):008:0>obj.my_方法
你好
=>零
irb(主要):009:0>
目前,JRuby子类无法通过Java以这种方式访问,尽管计划在未来的实现中使用它(可能是JRuby 1.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\u index\u creator.rb
将实现您的index creator类,然后返回它的一个实例-显然,您可以从这里引用其他ruby文件,并根据需要组织:
class MyIndexer < IndexCreator
[...]
end
MyIndexer.new
class MyIndexer
就这样 感谢Rob,这个解决方案在我的情况下可以起到一定的作用(我现在确实是这样做的),但我不希望对Java类进行猴子补丁。应该有一些通用的方法来使用.forName方法加载Ruby类,对吗?