问题
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?
回答1:
It should be, but unfortunately isn't quite wired up that way yet. For now, #java_implements
and #java_signature
are only used by the jrubyc --java
command that creates a Java source file based on the Ruby class. You may want to consider using that for your Ruby integration.
We're aiming for this example to work for both precompiled scripts and runtime-executed scripts in the future. If you instead want this script to work as intended, try using include Java::some.package.ScriptDemoIf
instead of java_implements
.
来源:https://stackoverflow.com/questions/4617364/how-to-get-from-jruby-a-correctly-typed-ruby-implementation-of-a-java-interface