I'm trying to use JRuby (through the JSR233 interface included in JRuby 1.5) from a Java application to load a ruby implementation of a Java interface.
My sample implementation looks like this:
Interface:
package some.package;
import java.util.List;
public interface ScriptDemoIf {
int fibonacci(int d);
List<String> filterLength(List<String> source, int maxlen);
}
Ruby Implementation:
require 'java'
include Java
class ScriptDemo
java_implements some.package.ScriptDemoIf
java_signature 'int fibonacci(int d)'
def fibonacci(d)
d < 2 ? d : fibonacci(d-1) + fibonacci(d-2)
end
java_signature 'List<String> filterLength(List<String> source, int maxlen)'
def filterLength(source, maxlen)
source.find_all { |str| str.length <= maxlen }
end
end
Class loader:
public ScriptDemoIf load(String filename) throws ScriptException {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("jruby");
FileReader script = new FileReader(filename);
try {
engine.eval(new FileReader(script));
} catch (FileNotFoundException e) {
throw new ScriptException("Failed to load " + filename);
}
return (ScriptDemoIf) m_engine.eval("ScriptDemo.new");
}
(Obviously the loader is a bit more generic in real life - it doesn't assume that the implementation class name is "ScriptDemo" - this is just for simplicity).
Problem - I get a class cast exception in the last line of the loader - the engine.eval()
return a RubyObject
type which doesn't cast down nicely to my interface. From stuff I read all over the web I was under the impression that the whole point of use java_implements
in the Ruby section was for the interface implementations to be compiled in properly.
What am I doing wrong?