Можно ли создавать классы Java из JRuby и использовать их в Java? - PullRequest
4 голосов
/ 19 апреля 2011

Я пытаюсь расширить Analyzer Lucene от JRuby и использовать его из Java.Простой анализатор будет выглядеть так:

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

Затем я скомпилирую его: jrubyc -c /home/camilo/trunk/utils/target/dependency/lucene-core-3.0.2.jar --javac MyAnalyzer.rb и упакую в банку.

Теперь, при попытке использовать MyAnalyzer обратно в Java, MyAnalyzer является потомком org.jruby.RubyObject, а не org.apache.lucene.analysis.Analyzer.

Есть ли способ сделать Javaтрактовать MyAnalyzer как Analyzer вместо RubyObject?Или это выходит за рамки того, что JRuby может сделать сейчас?

Версия JRuby: jruby 1.6.0 (ruby 1.8.7 patchlevel 330)

1 Ответ

4 голосов
/ 24 августа 2011

Из того, что я понимаю, вы пытаетесь сделать, я предполагаю, что вы пытаетесь создать класс JRuby, который расширяет класс Java (с механизмом сценариев), и возвращать этот класс Java.

Ваш класс Ruby, вероятно, выглядит следующим образом:

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

Затем вы можете использовать этот класс в Java следующим образом:

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
    }
}

Затем вы скомпилируете и выполните:

$ javac -cp .:lucene-core.jar:$JRUBY_HOME/lib/jruby.jar RunMyAnalyzer.java 
$ java -cp .:lucene-core.jar:$JRUBY_HOME/lib/jruby.jar RunMyAnalyzer

Ключевым моментом здесь является то, что JRuby создает прокси-класс, который затем может быть преобразован в Analyzer, суперкласс Java.

...