Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ScriptEngine causes NullPointerException with multi-threads #3731

Closed
shirosaki opened this issue Mar 14, 2016 · 5 comments
Closed

ScriptEngine causes NullPointerException with multi-threads #3731

shirosaki opened this issue Mar 14, 2016 · 5 comments

Comments

@shirosaki
Copy link
Contributor

Environment

  • JRuby 9.0.0.0
  • Windows 7 x64
  • Used by with wro4j https://github.com/wro4j/wro4j
  • require sass 3.2.1
  • eval script using JRuby embed (ScriptEngineManager)

Expected Behavior

Multiple embed JRuby engines execute eval scripts normally with multi-threaded environments.

Actual Behavior

Multiple embed JRuby engines cause NullPointerException while executing eval scripts with multi-threaded environments.
Error log is here.
wro4j/wro4j#1007

This NullPointerException doesn't occur with JRuby 1.7.14.

@kares
Copy link
Member

kares commented Mar 14, 2016

@shirosaki would it be possible for you to try out whether is still happens in 9.0.5.0 ... thanks!

@shirosaki
Copy link
Contributor Author

@kares I've tried 9.0.5.0. Different exceptionIndexOutOfBoundsException is raised.

I was able to workaround the issue by using a global lock for JRuby initialization.
wro4j/wro4j#1007 (comment)

Running ro.isdc.wro.extensions.processor.TestRubySassCssProcessorMultiThreads
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 9.02 sec <<< FAILURE!
shouldBeThreadSafe(ro.isdc.wro.extensions.processor.TestRubySassCssProcessorMultiThreads)  Time elapsed: 8.959 sec  <<< ERROR!
java.util.concurrent.ExecutionException: java.lang.RuntimeException: ro.isdc.wro.WroRuntimeException: org.jruby.embed.EvalFailedException: java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
        at java.util.concurrent.FutureTask.report(FutureTask.java:122)
        at java.util.concurrent.FutureTask.get(FutureTask.java:192)
        at ro.isdc.wro.util.WroTestUtils.runConcurrently(WroTestUtils.java:410)
        at ro.isdc.wro.util.WroTestUtils.runConcurrently(WroTestUtils.java:430)
        at ro.isdc.wro.extensions.processor.TestRubySassCssProcessorMultiThreads.shouldBeThreadSafe(TestRubySassCssProcessorMultiThreads.java:49)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
        at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
        at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
        at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
        at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
        at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
Caused by: java.lang.RuntimeException: ro.isdc.wro.WroRuntimeException: org.jruby.embed.EvalFailedException: java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
        at ro.isdc.wro.extensions.processor.TestRubySassCssProcessorMultiThreads$1.call(TestRubySassCssProcessorMultiThreads.java:44)
        at ro.isdc.wro.extensions.processor.TestRubySassCssProcessorMultiThreads$1.call(TestRubySassCssProcessorMultiThreads.java:36)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
Caused by: ro.isdc.wro.WroRuntimeException: org.jruby.embed.EvalFailedException: java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
        at ro.isdc.wro.extensions.processor.support.sass.RubySassEngine.process(RubySassEngine.java:91)
        at ro.isdc.wro.extensions.processor.css.RubySassCssProcessor.process(RubySassCssProcessor.java:59)
        at ro.isdc.wro.extensions.processor.css.RubySassCssProcessor.process(RubySassCssProcessor.java:101)
        at ro.isdc.wro.extensions.processor.TestRubySassCssProcessorMultiThreads$1.call(TestRubySassCssProcessorMultiThreads.java:41)
        ... 5 more
Caused by: javax.script.ScriptException: org.jruby.embed.EvalFailedException: java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
        at org.jruby.embed.jsr223.JRubyEngine.wrapException(JRubyEngine.java:104)
        at org.jruby.embed.jsr223.JRubyEngine.eval(JRubyEngine.java:93)
        at org.jruby.embed.jsr223.JRubyEngine.eval(JRubyEngine.java:142)
        at ro.isdc.wro.extensions.processor.support.sass.RubySassEngine.process(RubySassEngine.java:89)
        ... 8 more
Caused by: org.jruby.embed.EvalFailedException: java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
        at org.jruby.embed.internal.EmbedEvalUnitImpl.run(EmbedEvalUnitImpl.java:137)
        at org.jruby.embed.jsr223.JRubyEngine.eval(JRubyEngine.java:90)
        ... 10 more
Caused by: java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
        at java.util.ArrayList.rangeCheck(ArrayList.java:653)
        at java.util.ArrayList.get(ArrayList.java:429)
        at org.jruby.embed.internal.BiVariableMap.getVariable(BiVariableMap.java:270)
        at org.jruby.embed.internal.BiVariableMap.updateVariable(BiVariableMap.java:540)
        at org.jruby.embed.variable.LocalGlobalVariable.updateLocalGlobal(LocalGlobalVariable.java:101)
        at org.jruby.embed.variable.LocalGlobalVariable.retrieve(LocalGlobalVariable.java:95)
        at org.jruby.embed.variable.VariableInterceptor.retrieve(VariableInterceptor.java:157)
        at org.jruby.embed.internal.BiVariableMap.retrieve(BiVariableMap.java:389)
        at org.jruby.embed.internal.EmbedEvalUnitImpl.run(EmbedEvalUnitImpl.java:121)
        ... 11 more

@headius
Copy link
Member

headius commented Mar 14, 2016

Could be some race when initializing the JRuby instance for ScriptingContainer.

Is it sufficient to run the wro4j test suite to see this issue? If not, what's the easiest way for us to reproduce the bug?

@shirosaki
Copy link
Contributor Author

I can reproduce the bug by the following code.

$ javac TestJRubyEmbedThread.java
$ java -classpath .:/path/to/jruby-complete-9.0.5.0.jar TestJRubyEmbedThread

TestJRubyEmbedThread.java:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

class TestJRubyEmbedThread extends Thread {
  public TestJRubyEmbedThread() {
  }

  public void run() {
    ScriptEngineManager manager = new ScriptEngineManager();
    ScriptEngine engine = manager.getEngineByName("jruby");
    try {
       engine.eval("require 'webrick'");
    } catch (ScriptException e) {
       e.printStackTrace();
    }
  }

  public static void main(String[] args) {
    System.setProperty("org.jruby.embed.compat.version", "JRuby1.9");
    for (int i = 0; i < 20; i++) {
      new TestJRubyEmbedThread().start();
    }
  }
}

@shirosaki
Copy link
Contributor Author

After adding
System.setProperty("org.jruby.embed.localcontext.scope", "threadsafe");
JRuby 9.0.5.0 does not cause errors, but JRuby 9.0.0.0 causes errors.

In documents, default: System.setProperty("org.jruby.embed.localcontext.scope", "concurrent");
means that global variables and top level variables/constants are not thread safe.

So I think JRuby 9.0.5.0 behavior looks like expected.
And JRuby 9.0.0.0 has a bug.

@kares kares added this to the Invalid or Duplicate milestone Mar 17, 2016
fviale added a commit to fviale/scheduling that referenced this issue Jun 27, 2024
Enforce in the node a jruby property that ensures jruby context to be thread-safe

See jruby/jruby#3731
fviale added a commit to ow2-proactive/scheduling that referenced this issue Jul 20, 2024
Enforce in the node a jruby property that ensures jruby context to be thread-safe

See jruby/jruby#3731

(cherry picked from commit 84bce4b)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants