Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8029604

Scripting/Nashorn - Nashorn appears to use incorrect scope

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P3 P3
    • None
    • 8
    • core-libs

      FULL PRODUCT VERSION :
      java version "1.8.0-ea"
      Java(TM) SE Runtime Environment (build 1.8.0-ea-b118)
      Java HotSpot(TM) 64-Bit Server VM (build 25.0-b60, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Linux 3.5.0-17-generic #28-Ubuntu SMP x86_64 GNU/Linux

      A DESCRIPTION OF THE PROBLEM :
      I've been playing around with Nashorn, and in particular I've been trying to implement commonJS-like require() functionality, but having some problems.

      While trying to implement this using Nashorn and running scripts in different scopes I've found it's possible for Nashorn to get confused about what scope it's using, and for scopes to leak from one to another.

      I created this a simple runnable example to demonstrate the issue (attached).

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile and run the example program.


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import javax.script.*;
       
      /*
      This example demonstrates possible leakage of Nashorn scopes and the incorrect scope being used when executing
      a function defined in one scope, from another scope.
       */
      public class LeakTest {
        public static void main(String[] args) {
          new LeakTest().run();
        }
       
        /*
        script1 contains a function which simply sets a global, and then immediately logs out the type of the global
        to system.out
        I would expect it to log "typeof global is number"
        Instead it logs "typeof global is undefined"
       
        script1 runs inside its own scope - this is basically how commonJS modules would be run -they are allowed to set
        globals but these won't be visible to other scopes that call it.
         */
        private String script1 =
            "function foo() {
      " +
            " _someglobal = 123;
      " +
            " java.lang.System.out.println('typeof global is ' + typeof _someglobal);
      " +
            " // Now set another global
      " +
            " _someotherglobal = 456;
      " +
            "}
      " +
            "_javaobject.setFunction(foo);";
       
        /*
        script2 simply calls the function foo() which we export by setting its value through a Java object
        it then tries to display the value of _someotherglobal which was defined in another scope, and succeeds!
         */
        private String script2 =
            "foo();
      " +
            "java.lang.System.out.println('someotherglobal is ' + _someotherglobal)";
       
        private void run() {
          try {
            ScriptEngineManager factory = new ScriptEngineManager();
            ScriptEngine engine = factory.getEngineByName("nashorn");
       
            // Run script1 in it's own scope
            ScriptContext ctx = new SimpleScriptContext();
            Bindings bindings = engine.createBindings();
            bindings.put("_javaobject", this);
            ctx.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
            engine.eval(script1, ctx);
       
            // Run script2 in it's own scope
            bindings = engine.createBindings();
            bindings.put("foo", function);
            ctx = new SimpleScriptContext();
            ctx.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
            engine.eval(script2, ctx);
       
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
       
        private Object function;
       
        // This allows us to pass an JavaScript object from one scope to another
        public void setFunction(Object function) {
          this.function = function;
        }
       
       
      }
      ---------- END SOURCE ----------

            sundar Sundararajan Athijegannathan
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: