问题
I'm trying to extend Lucene's Analyzer
from JRuby and use it from java. A simple analyzer would look like:
class MyAnalyzer < Java::OrgApacheLuceneAnalysis::Analyzer
def TokenStream (file_name, reader)
result = StandardTokenizer.new(Version::LUCENE_CURRENT, reader)
result = LowerCaseFilter.new(result)
result = LengthFilter.new(result, 3, 50)
result = StopFilter.new(result, StandardAnalyzer.STOP_WORDS_SET)
result = PorterStemFilter.new(result)
result
end
end
Then I compile it: jrubyc -c /home/camilo/trunk/utils/target/dependency/lucene-core-3.0.2.jar --javac MyAnalyzer.rb
and package it as a jar.
Now, when trying to use MyAnalyzer
back in java, MyAnalyzer
is a descendent of org.jruby.RubyObject
, and not of org.apache.lucene.analysis.Analyzer
.
Is there a way to make Java treat MyAnalyzer
as an Analyzer
instead of a RubyObject
? Or is this way outside the scope of what JRuby can do now?
JRuby version: jruby 1.6.0 (ruby 1.8.7 patchlevel 330)
回答1:
From what I understand from you are trying to do, I’m guessing you are trying to create a JRuby class that extends a Java class (with a scripting engine), and hand back that class to Java.
Your Ruby class probably looks like this:
require 'java'
require 'lucene-core.jar'
java_import 'org.apache.lucene.analysis.Analyzer'
java_import 'org.apache.lucene.analysis.standard.StandardTokenizer'
java_import 'org.apache.lucene.util.Version'
java_import 'org.apache.lucene.analysis.TokenStream'
java_import 'java.io.Reader'
class MyAnalyzer < Analyzer
def tokenStream(file_name, reader)
result = StandardTokenizer.new(Version::LUCENE_CURRENT, reader)
# ...
end
end
You can then use this class in Java as follows:
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.io.Reader;
import org.apache.lucene.analysis.Analyzer;
public class RunMyAnalyzer {
public static void main(String[] args) throws ScriptException, FileNotFoundException {
String filename = "my-analyzer.rb";
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("jruby");
Reader reader = new FileReader(filename);
engine.eval(reader);
// Instantiate the JRuby class, and cast the result of eval.
Analyzer analyzer = (Analyzer) engine.eval("MyAnalyzer.new");
// You can then use this analyzer like a Lucene Analyzer
}
}
You then compile and run with:
$ javac -cp .:lucene-core.jar:$JRUBY_HOME/lib/jruby.jar RunMyAnalyzer.java
$ java -cp .:lucene-core.jar:$JRUBY_HOME/lib/jruby.jar RunMyAnalyzer
The key here is that JRuby produces a proxy class that can then be casted into Analyzer
, the Java superclass.
来源:https://stackoverflow.com/questions/5721134/is-it-possible-to-create-java-classes-from-jruby-and-use-them-in-java