Search code examples
javajsonrestapistack-overflow

StackOverflowError because JSONTokener


I am trying to transform a json file received through REST API into a list of java objects. Everything works well until couple runnings when I get StackOverFlow error.If I am not calling that method everything works well. I do not have any idea of how to solve this. Thank you

The error is :

Exception in thread "main" java.lang.StackOverflowError
    at org.json.JSONTokener.nextClean(JSONTokener.java:292)
    at org.json.JSONTokener.nextValue(JSONTokener.java:422)
    at org.json.JSONObject.<init>(JSONObject.java:225)
    at org.json.JSONTokener.nextValue(JSONTokener.java:431)
    at org.json.JSONObject.<init>(JSONObject.java:244)
    at org.json.JSONTokener.nextValue(JSONTokener.java:431)
    at org.json.JSONArray.<init>(JSONArray.java:124)
    at org.json.JSONTokener.nextValue(JSONTokener.java:434)
    at org.json.JSONObject.<init>(JSONObject.java:244)
    at org.json.JSONTokener.nextValue(JSONTokener.java:431)
    at org.json.JSONObject.<init>(JSONObject.java:244)
    at org.json.JSONTokener.nextValue(JSONTokener.java:431)
    at org.json.JSONArray.<init>(JSONArray.java:124)
    at org.json.JSONTokener.nextValue(JSONTokener.java:434)
    at org.json.JSONObject.<init>(JSONObject.java:244)

The method that calls the REST Api is :

public List<Student> getAllStudents() {
    try {

        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpGet getRequest = new HttpGet(
                "http://localhost:8080/students/getAllStudents" + 
                "");
        getRequest.addHeader("accept", "application/json");

        HttpResponse response = httpClient.execute(getRequest);

        if (response.getStatusLine().getStatusCode() != 200) {
            throw new RuntimeException("Failed : HTTP error code : "
                    + response.getStatusLine().getStatusCode());
        }

        BufferedReader br = new BufferedReader(
                new InputStreamReader((response.getEntity().getContent())));

        String output;
        System.out.println("Output from Server .... \n");

        ObjectMapper objMap = new ObjectMapper();
        Student tabusca = new Student();
        output = br.readLine();
       tabusca = objMap.readValue(output, Student.class);

        System.out.println(tabusca.toString());
        String file = "";
        while ((output = br.readLine()) != null) {
            file += output;
            //System.out.println(output);
        }

        //System.out.println(file);

        JSONArray jsonArray= new JSONArray(file);
        List<Student> list = new ArrayList<Student>();


        for(int i=0; i<jsonArray.length(); i++) {
            Student p = new Student(); 
            p.setStudentId(jsonArray.getJSONObject(i).getLong("studentId"));
            p.setEmail(jsonArray.getJSONObject(i).getString("email"));
            p.setPassword(jsonArray.getJSONObject(i).getString("password"));
            p.setFullname(jsonArray.getJSONObject(i).getString("fullname"));
            p.setGrupa(jsonArray.getJSONObject(i).getLong("grupa"));
            p.setHobby(jsonArray.getJSONObject(i).getString("hobby"));
            p.setToken(jsonArray.getJSONObject(i).getString("token"));
            p.setAssigmentStudent(null);
            p.setAttendances(null);
            p.setStudentUid(null);
            list.add(p);
       }




        httpClient.getConnectionManager().shutdown();
        return list;

    } catch (ClientProtocolException e) {

        e.printStackTrace();

    } catch (IOException e) {

        e.printStackTrace();
    }
    return null;
}

Solution

  • The issue is your JSON is too 'deep'. There are too many nested elements in your json. The org.json parser gets too many recursive method calls to it resulting into Stackoverflow.

    Even if you change your json library, you may still run in same problem.

    To solve the issue you should either reconsider the JSON structure or increase the JRE stack size using jvm argument eg -Xss4m