2

在将 JRuby 从 1.5.2 升级到 1.6.1 时,我遇到了一个有趣的问题。整个周末都让我毛骨悚然,直到我把它归结为几行。当 getEngineByName 被调用太多次时,似乎某个地方可能引入了一个错误,导致失败。例如,以下超简单代码在 1.5.2 中有效,但在大约 10-20 次迭代后在 1.6.1 中失败:

    ScriptEngineManager factory = new ScriptEngineManager();
    for (int i = 0; i < 10000; i++) {
        System.out.println(i);
        ScriptEngine engine = factory.getEngineByName("jruby");
        engine.eval("puts 'hello'");
    }

#16 之后的 1.6.1 结果:

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:未初始化常量”错误的任何想法?不,我还没有尝试检查源...

4

0 回答 0