Forum Stats

  • 3,723,348 Users
  • 2,244,533 Discussions
  • 7,850,425 Comments

Discussions

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Invoking invokeFunction("someJSbject") twice both have same properties

Hi Guys,

We are moving from rhino to javax.script. Well you can guess that is a major step in our development of our software. Of course I didn’t expect it to just be a breeze. I have found a very strange feature of javax.script package.

I have a very simple js script:

load("nashorn:mozilla_compat.js");

function JSDevice() {

               this.deviceType = "";

               this.deviceId = "";

               return this;

}

And a Java code:

import java.io.File;

import java.io.FileReader;

import java.io.Reader;

import java.util.ArrayList;

import java.util.List;

import javax.script.Bindings;

import javax.script.Invocable;

import javax.script.ScriptEngine;

import javax.script.ScriptEngineManager;

/**

* @author jdalecki

*

*/

public class Main {

  /**

   * @param args

   */

  public static void main(String[] args) {

    Main m = new Main();

    m.exposeTheBug();

  }

  private void exposeTheBug() {

    ScriptEngine engine = (new ScriptEngineManager()).getEngineByName("JavaScript");

    List<Bindings> allDevices = new ArrayList<Bindings>();

    String scriptFilename = <point to the folder where you saved the js script file>

    try {

      File fName = new File(scriptFilename);

      Reader scriptReader = new FileReader(fName);

      engine.eval(scriptReader);

      Invocable invocable = (Invocable) engine;

      System.out.println("Creating two different JSDevice objects:");

      System.out.println("\tFirst with the properties:");

      System.out.println("\t\tdeviceType=JSDevice1.type");

      System.out.println("\t\tdeviceId=JSDevice1.id");

     

      System.out.println("\tSecond with the properties:");

      System.out.println("\t\tdeviceType=JSDevice2.type");

      System.out.println("\t\tdeviceId=JSDevice2.id");

      // Step 1

      System.out.println("First object created:");

      Bindings jsDevice1 = (Bindings)invocable.invokeFunction("JSDevice");

      jsDevice1.put("deviceType", "JSDevice1.type");

      jsDevice1.put("deviceId", "JSDevice1.id");

      for(String key :  jsDevice1.keySet())

      {

        if(key.equals("deviceType") || key.equals("deviceId"))

        {

          Object obj = jsDevice1.get(key);

          System.out.println(obj);

        }

      }

      allDevices.add(jsDevice1);

      System.out.println("");

      // Step 2

      System.out.println("Second object created:");

      Bindings jsDevice2 = (Bindings)invocable.invokeFunction("JSDevice");

      jsDevice2.put("deviceType", "JSDevice2.type");

      jsDevice2.put("deviceId", "JSDevice2.id");

      for(String key :  jsDevice2.keySet())

      {

        if(key.equals("deviceType") || key.equals("deviceId"))

        {

          Object obj = jsDevice2.get(key);

          System.out.println(obj);

        }

      }

      allDevices.add(jsDevice2);

      System.out.println("");

      // Summary

      System.out.println("In summary: Both JSDevice objects point to the properties I set in the second JSDevice object, why?");

     

      for(Bindings b : allDevices)

      {

        for(String key : b.keySet())

        {

          if(key.equals("deviceType") || key.equals("deviceId"))

          {

            System.out.println("Device: "+key+" Value="+b.get(key));

          }

        }

      }

    } catch (Exception ex) {

      ex.printStackTrace();

    }

  }

}

The problem description:

As you can see I am creating sequentially two Java Script object calling engine invokeFunction("JSDevice"). That is all good so far.
However when I set the properties (“deviceType” and “deviceId”) on both of them, the last setting seems to overwrite the properties of the first object.
Both “JSDevice” objects point to the properties I set in the second JSDevice object, why?

Regards,

Janusz

Sign In or Register to comment.