Is it possible to create Java classes from JRuby and use them in Java?

I am trying to extend Lucene Analyzer from JRuby and use it from java. A simple analyzer will look like this:

 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 pack it like a jar.

Now when you try to use MyAnalyzer in java, MyAnalyzer is a descendant of org.jruby.RubyObject , not org.apache.lucene.analysis.Analyzer .

Is there a way to get Java to treat MyAnalyzer as an Analyzer instead of RubyObject ? Or is it beyond what JRuby can do now?

JRuby version: jruby 1.6.0 (ruby 1.8.7 patchlevel 330)

+4
source share
1 answer

From what I understand what you are trying to do, I assume that you are trying to create a JRuby class that extends the Java class (using a scripting mechanism) and returns this class in 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 

Then you can 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 } } 

Then you 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 point here is that JRuby creates a proxy class that can then be added to Analyzer , the Java superclass.

+4
source

All Articles