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

Loading script from file system twice locks file

    XMLWordPrintable

Details

    Description

      FULL PRODUCT VERSION :
      java version "1.8.0_161"
      Java(TM) SE Runtime Environment (build 1.8.0_161-b12)
      Java HotSpot(TM) 64-Bit Server VM (build 25.161-b12, mixed mode)

      and

      java version "1.8.0_121"
      Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
      Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows [Version 6.1.7601]

      A DESCRIPTION OF THE PROBLEM :
      When you use the "load" function from within java to load a javascript file *twice * using this pattern

                scriptEngine.eval("load('c:/temp/test.js');");


      it locks the JS file (prevents its deletion). This does NOT happen if i load the file only once.

      It does not appear to matter whether i assign the result of the load or null out the assigned variable nor to wait until some gc has occurred.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1) Create a file "test.js" and put it where you want. I put it in
      c:\temp\test.js

      (function(module) {
      var exports = module.exports;
      exports.test = function() {
      return "test ok";
      }
      return module.exports;})({exports:{}, id:'test'});


      2) Create a Temp.java as follows and run it first with *loadSecondSom =
      true*. The deletion will fail. Then run it with *loadSecondSom = false*.
      The deletion will succeed. (Note: the "pause" is only to make it clearer...)

      import java.io.IOException;
      import java.nio.file.Files;
      import java.nio.file.Path;
      import java.nio.file.Paths;

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

      import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
      import jdk.nashorn.api.scripting.ScriptObjectMirror;

      public class Temp {
      private static final NashornScriptEngineFactory nashornFactory = new
      NashornScriptEngineFactory();
      private static ScriptEngine scriptEngine = nashornFactory.getScriptEngine();

      private static void deleteFile(String sPath) throws IOException {
      Path p = Paths.get(sPath);
      Files.delete(p);
      }
      private static void pause(int numsecs) {
      int x;
      try {
      for (int i=0;i<numsecs;i++) {
      Thread.sleep(1000);
      x = i;
      }
      } catch (InterruptedException e) {
      e.printStackTrace();
      }
      }

      public static void main(String[] ss) {
      boolean loadSecondSom = true;
      String sPath = "C:/temp/test.js";
      try {
      System.out.println("loading and calling som1...");
      ScriptObjectMirror som1 = (ScriptObjectMirror)scriptEngine.eval("load('" +
      sPath + "');");
      System.out.println(som1.callMember("test"));
      System.out.println("Sleeping ... ");
      pause(2);
      if (loadSecondSom) {
      System.out.println("loading and calling som2...");
      ScriptObjectMirror som2 = (ScriptObjectMirror)scriptEngine.eval("load('" +
      sPath + "');");
      System.out.println(som2.callMember("test"));
      }

      System.out.println("Sleeping ... ");
      pause(2);

      System.out.println("Attempting to delete the file from the fs...");
      try {
      deleteFile(sPath);
      } catch (IOException e) {
      System.out.println("Cannot delete the file: "+e);
      }

      System.out.println("DONE");
      } catch (ScriptException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      }
      }
      }



      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      I expect the file to be deleted on the file system.
      ACTUAL -
      An exception is thrown indicating that the file is locked:

      java.nio.file.FileSystemException: C:\temp\test.js: The process cannot access the file because it is being used by another process.

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      java.nio.file.FileSystemException: C:\temp\test.js: The process cannot access the file because it is being used by another process.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      NOTE: you must first place the Javascript file test.js in the c:\temp directory (or somewhere on the file system) and ensure the path in the following source is correct. Please see the "Steps to Reproduce" for the simple steps.

      import java.io.IOException;
      import java.nio.file.Files;
      import java.nio.file.Path;
      import java.nio.file.Paths;

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

      import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
      import jdk.nashorn.api.scripting.ScriptObjectMirror;

      public class Temp {
      private static final NashornScriptEngineFactory nashornFactory = new
      NashornScriptEngineFactory();
      private static ScriptEngine scriptEngine = nashornFactory.getScriptEngine();

      private static void deleteFile(String sPath) throws IOException {
      Path p = Paths.get(sPath);
      Files.delete(p);
      }
      private static void pause(int numsecs) {
      int x;
      try {
      for (int i=0;i<numsecs;i++) {
      Thread.sleep(1000);
      x = i;
      }
      } catch (InterruptedException e) {
      e.printStackTrace();
      }
      }

      public static void main(String[] ss) {
      boolean loadSecondSom = true;
      String sPath = "C:/temp/test.js";
      try {
      System.out.println("loading and calling som1...");
      ScriptObjectMirror som1 = (ScriptObjectMirror)scriptEngine.eval("load('" +
      sPath + "');");
      System.out.println(som1.callMember("test"));
      System.out.println("Sleeping ... ");
      pause(2);
      if (loadSecondSom) {
      System.out.println("loading and calling som2...");
      ScriptObjectMirror som2 = (ScriptObjectMirror)scriptEngine.eval("load('" +
      sPath + "');");
      System.out.println(som2.callMember("test"));
      }

      System.out.println("Sleeping ... ");
      pause(2);

      System.out.println("Attempting to delete the file from the fs...");
      try {
      deleteFile(sPath);
      } catch (IOException e) {
      System.out.println("Cannot delete the file: "+e);
      }

      System.out.println("DONE");
      } catch (ScriptException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      }
      }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      i have not found one.

      Attachments

        1. Temp.java
          2 kB
        2. test.js
          0.2 kB

        Activity

          People

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

            Dates

              Created:
              Updated: