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
> > >
> >
>

Reply via email to