Я столкнулся с интересной проблемой при обновлении JRuby с 1.5.2 до 1.6.1.Это пугало меня весь уик-энд, пока я не свел его к горстке строк.Кажется, что где-то может быть введена ошибка, которая вызывает ошибку, когда getEngineByName вызывается слишком много раз.Например, следующий супер-простой код работает в 1.5.2, но не работает в 1.6.1 после примерно 10-20 итераций:
ScriptEngineManager factory = new ScriptEngineManager();
for (int i = 0; i < 10000; i++) {
System.out.println(i);
ScriptEngine engine = factory.getEngineByName("jruby");
engine.eval("puts 'hello'");
}
Результат в 1.6.1 после # 16:
NameError: uninitialized constant #<Class:0x101a41cc7>::ARGV
const_missing at org/jruby/RubyModule.java:2526
Exception in thread "main" java.lang.NullPointerException
at org.jruby.embed.jsr223.JRubyEngine.wrapException(JRubyEngine.java:110)
at org.jruby.embed.jsr223.JRubyEngine.eval(JRubyEngine.java:93)
at org.jruby.embed.jsr223.JRubyEngine.eval(JRubyEngine.java:154)
at JRubyTestFailure.main(JRubyTestFailure.java:16)
Чтобы избежать этой проблемы, все, что вам нужно сделать, это переместить getEngineByName за пределы цикла:
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("jruby");
for (int i = 0; i < 10000; i++) {
System.out.println(i);
engine.eval("puts 'hello'");
}
К сожалению, это не так просто для моего приложения по архитектурным соображениям.Возможно, мне придется поместить отдельные экземпляры ScriptEngine в ThreadLocal.Непонимание, почему это не помогает, меня беспокоит.
Есть идеи, почему я получаю эту ошибку "NameError: uninitialized constant"?Нет, я еще не пробовал проверить источник ...