JRuby (please use github issues at http://bugs.jruby.org)
  1. JRuby (please use github issues at http://bugs.jruby.org)
  2. JRUBY-6792

Occasional java.lang.ArrayIndexOutOfBoundsException calling ScriptingContainer#runScriptlet

    Details

    • Type: Bug Bug
    • Status: Resolved Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: JRuby 1.6.7, JRuby 1.7.0.pre1
    • Fix Version/s: JRuby 1.7.0.pre2
    • Component/s: Embedding
    • Labels:
      None
    • Environment:
      We are getting this when running on Ruboto, but it may be platform independent.
    • Number of attachments :
      0

      Description

      When we call ScriptingContainer#runScriptlet with the following String:

      "defined?(TestAppActivity) == 'constant' && TestAppActivity.instance_methods(false).any?{|m| m.to_sym == :on_resume}"
      

      we occasionally get the following exception:

      07-20 13:28:59.074 E/AndroidRuntime(  817): Caused by: java.lang.ArrayIndexOutOfBoundsException
      07-20 13:28:59.074 E/AndroidRuntime(  817): 	at org.jruby.runtime.ThreadContext.popScope(ThreadContext.java:270)
      07-20 13:28:59.074 E/AndroidRuntime(  817): 	at org.jruby.embed.internal.EmbedEvalUnitImpl.run(EmbedEvalUnitImpl.java:139)
      07-20 13:28:59.074 E/AndroidRuntime(  817): 	at org.jruby.embed.ScriptingContainer.runUnit(ScriptingContainer.java:1264)
      07-20 13:28:59.074 E/AndroidRuntime(  817): 	at org.jruby.embed.ScriptingContainer.runScriptlet(ScriptingContainer.java:1257)
      07-20 13:28:59.074 E/AndroidRuntime(  817): 	at java.lang.reflect.Method.invokeNative(Native Method)
      07-20 13:28:59.074 E/AndroidRuntime(  817): 	at java.lang.reflect.Method.invoke(Method.java:507)
      07-20 13:28:59.074 E/AndroidRuntime(  817): 	at org.ruboto.JRubyAdapter.runScriptlet(JRubyAdapter.java:184)
      07-20 13:28:59.074 E/AndroidRuntime(  817): 	at org.ruboto.RubotoActivity.onResume(RubotoActivity.java:1164)
      07-20 13:28:59.074 E/AndroidRuntime(  817): 	at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1150)
      07-20 13:28:59.074 E/AndroidRuntime(  817): 	at android.app.Activity.performResume(Activity.java:3832)
      07-20 13:28:59.074 E/AndroidRuntime(  817): 	at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2110)
      07-20 13:28:59.074 E/AndroidRuntime(  817): 	... 10 more
      

      It may be that the actual Ruby code is not significant.

        Activity

        Hide
        Uwe Kubosch added a comment -

        I have investigated a bit. The error may be that the SoftReference to ThreadContext is collected while inside a ScriptingContainer method call. When the ThreadContext is recreated on demand, it has only the top static scope, and if that is popped, any call to getCurrentScope() will fail.

        What hard references should there be to ThreadContext during a call to ScriptingContainer?

        Show
        Uwe Kubosch added a comment - I have investigated a bit. The error may be that the SoftReference to ThreadContext is collected while inside a ScriptingContainer method call. When the ThreadContext is recreated on demand, it has only the top static scope, and if that is popped, any call to getCurrentScope() will fail. What hard references should there be to ThreadContext during a call to ScriptingContainer?
        Hide
        Uwe Kubosch added a comment -

        I have been struggling with this for days now, and I really need help reproducing outside Ruboto.

        Reproducing with Ruboto is pretty easy. Check out the project. Then start an emulator or connect a device. Then

        ./run_tests.sh
        

        I have forced the same error in a JRuby tests, but I had to use

        container.getProvider().getRuntime().getThreadService().disposeCurrentThread();
        

        and I am not sure this is legal during the use of a ScriptingContainer. Is it?

        Any help on this is greatly appreciated since this is currently the only blocker for the next Ruboto release.

        Show
        Uwe Kubosch added a comment - I have been struggling with this for days now, and I really need help reproducing outside Ruboto. Reproducing with Ruboto is pretty easy. Check out the project. Then start an emulator or connect a device. Then ./run_tests.sh I have forced the same error in a JRuby tests, but I had to use container.getProvider().getRuntime().getThreadService().disposeCurrentThread(); and I am not sure this is legal during the use of a ScriptingContainer. Is it? Any help on this is greatly appreciated since this is currently the only blocker for the next Ruboto release.
        Hide
        Uwe Kubosch added a comment -

        I have an example that fails with the same symptom:

        class JRUBY_6792 {
            public static void main(String[] args) {
                org.jruby.embed.ScriptingContainer container = new org.jruby.embed.ScriptingContainer();
        
                // Simulate a garbage collection of softreference to current context
                container.getProvider().getRuntime().getThreadService().setCurrentContext(null);
        
                container.put("MyConstant", 42);
                container.runScriptlet("a = 1");
                container.runScriptlet("b = 2");
            }
        }
        

        This will fail of there is a contained memory condition during a call to runScriptlet so that SoftReferences are collected.

        I simulate this by triggering an OutOfMemoryError inside EmbedEvalUnitImpl#run like this:

                        try {
                            java.util.List<byte[]> l = new java.util.ArrayList<byte[]>();
                            while(true) {
                                l.add(new byte[1024 * 1024]);
                            }
                        } catch (OutOfMemoryError oome) {
                            System.out.println("Forced SoftReference collection: " + oome);
                        }
        

        I have checked all this in on the JRUBY-6792 branch. I tried rebasing the branch and got into some GIT trouble, so tell me if there is a problem.

        Any help with this is still greatly appreciated.

        Show
        Uwe Kubosch added a comment - I have an example that fails with the same symptom: class JRUBY_6792 { public static void main(String[] args) { org.jruby.embed.ScriptingContainer container = new org.jruby.embed.ScriptingContainer(); // Simulate a garbage collection of softreference to current context container.getProvider().getRuntime().getThreadService().setCurrentContext(null); container.put("MyConstant", 42); container.runScriptlet("a = 1"); container.runScriptlet("b = 2"); } } This will fail of there is a contained memory condition during a call to runScriptlet so that SoftReferences are collected. I simulate this by triggering an OutOfMemoryError inside EmbedEvalUnitImpl#run like this: try { java.util.List<byte[]> l = new java.util.ArrayList<byte[]>(); while(true) { l.add(new byte[1024 * 1024]); } } catch (OutOfMemoryError oome) { System.out.println("Forced SoftReference collection: " + oome); } I have checked all this in on the JRUBY-6792 branch. I tried rebasing the branch and got into some GIT trouble, so tell me if there is a problem. Any help with this is still greatly appreciated.
        Hide
        Uwe Kubosch added a comment -

        OK, the reproduction I did was fixed by keeping a reference to the current ThreadContext during execution of EmbedEvalUnitImpl#run.

        I have committed this to master, and it looks like the change fixes this issue. Since the error is dependent on timing, I'll run the tests a few times before closing this issue.

        Show
        Uwe Kubosch added a comment - OK, the reproduction I did was fixed by keeping a reference to the current ThreadContext during execution of EmbedEvalUnitImpl#run. I have committed this to master, and it looks like the change fixes this issue. Since the error is dependent on timing, I'll run the tests a few times before closing this issue.
        Hide
        Uwe Kubosch added a comment -

        Multiple test runs have completed successfully, so I'm calling it fixed.

        Woohoo!

        Show
        Uwe Kubosch added a comment - Multiple test runs have completed successfully, so I'm calling it fixed. Woohoo!

          People

          • Assignee:
            Unassigned
            Reporter:
            Uwe Kubosch
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: