Hi Ben, thanks for your response! I was thinking about a custom type coercer - seems like the best bet in the short term. We will have another go at identifying the underlying cause as well - would be better if we could solve it at source.
Cheers, Adriaan On Tue, 5 Oct 2021 at 22:23, Ben Weidig <b...@netzgut.net> wrote: > Hi Adriaan, > > we're using Ajax/JSONObject, too, but haven't seen such problems so far. > But I'm sure it's highly dependent on the context, and concurrent requests > count. > > For your problem, if you can't switch out the underlying data structure, > you might get around it by writing a custom type coercer for > JSONObject-->String with a custom toString() / print() method. > The only problem is that JSONObject is a final class, and print-related > stuff is package-scoped. > So you would need to copy/adapt all the related code into a utility able to > convert a JSONObject to a String and contribute a type coercer using it. > > Another option would be a custom tapestry-json version by vendoring the > whole tapestry-json code into your project and adapt it to your needs. > > Cheers, > Ben > > On Tue, Oct 5, 2021 at 8:09 PM Adriaan Joubert <adriaan...@gmail.com> > wrote: > > > Hi Ben, > > > > thanks for the reply! No, the json object is not stored in the session, > but > > it does traverse a lot of different components. The most likely cause > seems > > to be from separate threads that we use to speed up data loading during a > > request, but we have not been able to pin it down - naturally we have not > > been able to reproduce this problem. > > > > I have been considering using a different, thread safe data structure, > but > > it is a lot of code to change. And we see this error only once every 2-3 > > weeks. We will have to spend more time trying to understand where this > > could happen. > > > > The reason I mentioned it here is that json is used a lot in ajax > requests > > nowadays, so this seems like a problem that could arise in other > situations > > as well. > > > > All the best, > > > > Adriaan > > > > On Tue, 5 Oct 2021 at 18:48, Ben Weidig <b...@netzgut.net> wrote: > > > > > Hi, > > > > > > is the JSONObject in the Session and do you have Session locking > > disabled? > > > See > > > > > > > > > https://tapestry.apache.org/session-storage.html#SessionStorage-SessionLocking > > > > > > Changing the print-loop to check if keys still exist would just hide > the > > > underlying problem: using a data-structure concurrently that isn't > > designed > > > to be used in a concurrent environment. > > > > > > Maybe you could use another type of thread-safe data structure in your > > > session, and convert it to a JSONObject before sending it back to the > > > client? > > > > > > Cheers, > > > Ben > > > > > > > > > On Tue, Oct 5, 2021 at 2:50 PM Adriaan Joubert <adriaan...@gmail.com> > > > wrote: > > > > > > > Hi, > > > > > > > > we intermittently see coercion errors for JSONObject - which we use > > > > frequently for ajax context information. > > > > > > > > The relevant bit of stack trace is > > > > > > > > - Caused by: java.util.ConcurrentModificationException > > > > - at > > > > > > > > > > java.base/java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:719) > > > > - at > > > > > > > > > > java.base/java.util.LinkedHashMap$LinkedKeyIterator.next(LinkedHashMap.java:741) > > > > - at > > > org.apache.tapestry5.json.JSONObject.print(JSONObject.java:805) > > > > - at > > > > > > org.apache.tapestry5.json.JSONCollection.toString(JSONCollection.java:46) > > > > - at > > > > > > > > > > org.apache.tapestry5.commons.internal.BasicTypeCoercions$1.coerce(BasicTypeCoercions.java:69) > > > > - at > > > > > > > > > > org.apache.tapestry5.commons.internal.BasicTypeCoercions$1.coerce(BasicTypeCoercions.java:65) > > > > - at > > > > > > > > > > org.apache.tapestry5.commons.services.CoercionTuple$CoercionWrapper.coerce(CoercionTuple.java:57) > > > > > > > > > > > > Overlapping calls mean the json object is modified in one place while > > it > > > is > > > > written elsewhere - as the objects themselves are not thread safe, it > > is > > > > quite messy to protect all possible writes. > > > > > > > > Copying the keys before the print loop, with a check that the value > > still > > > > exists when printing, would narrow the window for this to happen > > > > considerably. We could not think of any better solutions to solve > this > > > > problem, but any suggestions are welcome. > > > > > > > > Cheers, > > > > > > > > Adriaan > > > > > > > > > >