Google App Engine / Java : ConcurrentModificationException thrown when using session.setAttribute()

Everything works fine on local, but when deployed I get a ConcurrentModificationException thrown when I use session.setAttribute() from a servlet. I use this to return a value from the datastore after using an HTML form to add an Entity.

How come and what could I do about it?

Here is the broken servlet:

public class AdminServlet extends HttpServlet {
    public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        Boolean logged = false;
        HttpSession session = req.getSession(true);
        Enumeration<String> names = session.getAttributeNames();

        while(names.hasMoreElements()) {
            String name = (String) names.nextElement();

            if(name.equals("logged")) {
                logged = (Boolean) session.getAttribute("logged");
            }
        }

        if(logged) {
            String p1 = req.getParameter("name");
            String p2 = req.getParameter("value");

            if(p1 != "" && p2 != "") {
                Entity e= new Entity("MyEntity");
                e.setProperty("name", p1);
                e.setProperty("value", p2);

                DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
                Transaction txn = datastore.beginTransaction();

                Key k = datastore.put(e);

                txn.commit();

                if(txn.isActive())
                    txn.rollback();

                session.setAttribute("returnedKey", KeyFactory.keyToString(k)); // CRASHES HERE
            }
        }

        resp.sendRedirect("adminpage.jsp");
    }
}

Thanks!

Answers


You have an Enumeration open on the session as well.

Enumeration names = session.getAttributeNames();

Changing attributes in session would affect name and that is why you are seeing the error.

Try writing your code so that names is not in use (nulled or out of scope):

It'd be easy to put it in a method

public boolean logLogged(HttpSession session){

    Enumeration<String> names = session.getAttributeNames();

    boolean loggedTmp=false;

    while(names.hasMoreElements()){

        String name = (String) names.nextElement();

        if(name.equals("logged")){
            loggedTmp = (Boolean) session.getAttribute("logged");
        }
    }

    return loggedTmp;

}

Need Your Help

Migrating from redis to mongodb in ruby on rails application

ruby-on-rails mongodb redis

I am completely new to Mongodb. Earlier I have used redis to store the data that I have processed in my ruby on rails application. My redis content is like following:

Modification to Selection Sort. Theoretically seems correct but doesn't give the results

algorithm sorting selection-sort

I am learning ruby and the way I am going about this is by learning and implementing sort algorithms. While working on selection sort, I tried to modify it as follows: