Я пытаюсь вызвать метод Ruby из Java, используя пример кода из:
https://github.com/tc/call-jruby-from-java-example
Вот как выглядит код Java с помощью встроенного сценария Ruby:
@Service
public class ProcessorImpl extends RubyObject implements IProcessor {
private static final Ruby __ruby__ = Ruby.getGlobalRuntime();
private static final RubyClass __metaclass__;
static {
String source = new StringBuilder(
"require 'java'\n" +
"require 'resque'\n" +
"\n" +
"class SaveData\n" +
" @queue = :general\n" +
"end\n" +
" \n" +
"class JRubyResqueImpl\n" +
" include Java::IProcessor\n" +
" \n" +
" java_signature 'void enqueue( Object )'\n" +
" def enqueue( data )\n" +
" Resque.enqueue( SaveData, data )\n" +
" end\n" +
"end\n" +
"").toString();
__ruby__.executeScript(source, "JRubyResqueImpl.rb");
RubyClass metaclass = __ruby__.getClass("JRubyResqueImpl");
metaclass.setRubyStaticAllocator(ActProcessorImpl.class);
__metaclass__ = metaclass;
}
public ActProcessorImpl(Ruby runtime, RubyClass metaClass)
{
super(runtime, metaClass);
}
public static IRubyObject __allocate__(Ruby ruby, RubyClass metaClass)
{
return new ActProcessorImpl(ruby, metaClass);
}
public ActProcessorImpl()
{
this(__ruby__, __metaclass__);
}
@Override
public void enqueue(Object obj)
{
ObjectMapper mapper = new ObjectMapper();
OutputStream os = new ByteArrayOutputStream();
try {
mapper.writeValue(os, obj);
} catch (Exception e) {
throw new RuntimeException(e);
}
String json = os.toString();
IRubyObject rbJson = JavaUtil.convertJavaToRuby(__ruby__, json);
RuntimeHelpers.invoke(__ruby__.getCurrentContext(), this, "enqueue",rbJson);
}
}
Когда модуль Spring Framework IoC выполняет автоматическое подключение, он пытается создать экземпляр этого класса, который завершается ошибкой со следующим сообщением об ошибке:
org.jruby.exceptions.RaiseException: (LoadError) no such file to load -- resque
Я не вижу ошибок, когда беру встроенный скрипт Ruby и запускаю его через CLI с помощью команды:
jruby -S JRubyResqueImpl.rb
Где содержимое JRubyResqueImpl.rb:
require 'java'
require 'resque'
class SaveData
@queue = :general
end
class JRubyResqueImpl
include Java::IProcessor
java_signature 'void enqueue( Object )'
def enqueue( data )
Resque.enqueue( SaveData, data )
end
end
Я настроил переменные окружения GEM_HOME, GEM_PATH и установил JRUBY_OPTS = - 1.9.
Использование Oracle Java 1.6.0_25, JRuby 1.6.4 и Resque 1.19.0 под управлением Ubuntu 11.10.
Заранее спасибо.
Мне удалось добиться некоторого прогресса, явно загрузив зависимости во встроенный скрипт ruby, например:
//java code
String source = new StringBuilder(
"require 'java'\n" +
"load '/usr/local/jruby/jruby-1.6.4/lib/ruby/1.9/singleton.rb'\n" +
"load '/usr/local/jruby/jruby-1.6.4/lib/ruby/gems/gems/monitor-0.1.3/lib/monitor/controller.rb'\n" +
"load '/usr/local/jruby/jruby-1.6.4/lib/ruby/gems/gems/monitor-0.1.3/lib/monitor.rb'\n" +
"load'/usr/local/jruby/jruby-1.6.4/lib/ruby/gems/redis-2.2.2/lib/redis.rb'\n" +
"load '/usr/local/jruby/jruby-1.6.4/lib/ruby/gems/redis-namespace-1.0.3/lib/redis-namespace.rb'\n" +
"load '/usr/local/jruby/jruby-1.6.4/lib/ruby/gems/resque-1.19.0/lib/resque.rb'\n" +
"\n" +
etc...
Но теперь я вижу следующую ошибку Spring IoC:
org.jruby.exceptions.RaiseException: (LoadError) no such file to load -- singleton
Все еще застрял ...