title: Java reading JSON as associative array like javascript and PHP ( ['key']['subKey'] )
body: <p>I am writing a java program to read <strong>Json</strong> as associative array,  like we do in <strong>javascript</strong> and <strong>PHP</strong>. I am 90% done but problem occurs when i try to read array from <strong>Json object</strong>.</p>
  
  <p>Here is <code>data.json</code> file which contains student record</p>
  
  <pre><code>{
  "students": {
      "2334": {
          "name": {
              "firstname": "umer",
              "lastname": "farooq"
          },
          "subject": {
              "marks": {
                  "maths": {
                      "total": 100.0,
                      "obtained": 70.0
                  },
                  "computer": {
                      "total": 100.0,
                      "obtained": 96.0
                  }
              }
          },
          "lang": ["java", "javascript", "C#"]
      },
      "1003": {
          "name": {
              "firstname": "yasir",
              "lastname": "khan"
          },
          "subject": {
              "marks": {
                  "maths": {
                      "total": 100.0,
                      "obtained": 80.0
                  },
                  "computer": {
                      "total": 100.0,
                      "obtained": 60.0
                  }
              }
          },
          "lang": ["C++", "PHP", "C#"]
      },
      "1233": {
          "name": {
              "firstname": "Mubarak",
              "lastname": "Amin"
          },
          "subject": {
              "marks": {
                  "maths": {
                      "total": 100.0,
                      "obtained": 70.0
                  },
                  "computer": {
                      "total": 100.0,
                      "obtained": 50.0
                  }
              }
          },
          "lang": ["Ruby", "javascript", "C"]
      }
  }
  </code></pre>
  
  <p>}</p>
  
  <p>To fetch marks obtained by student with the id <code>1233</code> in mathematics, i would simple pass string <code>['students']['1233']['subject']['marks']['maths']['obtained']</code> to <code>getValue()</code> method </p>
  
  <pre><code>     JSONAssociativeArrayReader parser = new JSONAssociativeArrayReader();
       parser.setJSONFile(new File("data.json"));
       double marksObtainedInMaths = (double) parser.getValue("['students']['1233']['subject']['marks']['maths']['obtained']");
  
       System.out.println("Marks obtained (maths) = " + marksObtainedInMaths);
  </code></pre>
  
  <p>Above code produces <code>Marks obtained (maths) = 70.0</code> which is correct. Problem occurs when i try to fetch <code>array</code> from Json file via my <code>getArray()</code> method.</p>
  
  <pre><code>System.out.println("languages = " + parser.getArray("['students']['1233']['lang']") );
  expected output : languages = [Ruby, javascript, C]
  </code></pre>
  
  <p>Following error occurs when above statement is executed</p>
  
  <pre><code>    Exception in thread "main" javax.script.ScriptException: TypeError: Cannot read property "lang" from undefined in &lt;eval&gt; at line number 1
      at jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:467)
      at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:451)
      at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:403)
      at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:399)
      at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:155)
      at javax.script.AbstractScriptEngine.eval(Unknown Source)
      at JSONAssociativeArrayReader.getArray(Main.java:77)
      at Main.main(Main.java:30)
  Caused by: &lt;eval&gt;:1 TypeError: Cannot read property "lang" from undefined
      at jdk.nashorn.internal.runtime.ECMAErrors.error(ECMAErrors.java:57)
      at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:213)
      at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:185)
      at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:172)
      at jdk.nashorn.internal.runtime.Undefined.get(Undefined.java:157)
      at jdk.nashorn.internal.scripts.Script$2$\^eval\_.:program(&lt;eval&gt;:1)
      at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:637)
      at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:494)
      at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
      at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:446)
      ... 6 more
  </code></pre>
  
  <p>Here is the code for <code>JSONAssociativeArrayReader</code></p>
  
  <pre><code>class JSONAssociativeArrayReader 
  {
       private ScriptEngineManager factory;
       private ScriptEngine engine;
       private static final String JSON_OBJECT_NAME = "jsonObject";
       private static final String JSON_ARRAY_NAME = "jsonArray";
  
  
      public JSONAssociativeArrayReader() throws ScriptException
      {
          factory = new ScriptEngineManager();
          engine = factory.getEngineByName("JavaScript");
      }
  
      public void setJSONFile(File jsonFile) throws IOException, ScriptException
      {
  
          String jsonStringFromFile = "";
          if(jsonFile != null) 
          {
              BufferedReader br = new BufferedReader(new FileReader(jsonFile));
              String line = "";
              while((line = br.readLine()) != null)
              {
                  jsonStringFromFile += line;
              }
  
          }
  
          engine.eval("var " + JSON_OBJECT_NAME + " = " + jsonStringFromFile);
  
      }
  
      public ArrayList&lt;Object&gt; getArray(String associativeArray) throws ScriptException
      {
          ArrayList&lt;Object&gt; objects = new ArrayList&lt;&gt;();
  
          engine.eval("var " + JSON_ARRAY_NAME + " = " + associativeArray);
  
          engine.eval("var arraylength = " +  JSON_ARRAY_NAME + ".length");
          int arrayLength = (int) engine.eval("arraylength");
  
          for (int i = 0; i &lt; arrayLength; i++)
          {
              engine.eval(" var arrayElement = " + JSON_ARRAY_NAME + "["+i+"]");
              objects.add(engine.get("arrayElement"));
          }
  
          return objects;
  
      }
  
  
  
      public Object getValue(String associativeArray) throws ScriptException
      {
          return engine.eval(JSON_OBJECT_NAME+associativeArray);
      }
  
  
  }
  </code></pre>
  
  <p>What i am doing wrong ?</p>