-
Notifications
You must be signed in to change notification settings - Fork 357
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Jersey Entity Filter Threads Racing issue leads to Corrupted Entity Graph and Object Graph #4189
Milestone
Comments
Duplicates #4187 |
This was referenced Jun 26, 2021
This was referenced Aug 5, 2021
This was referenced Sep 5, 2021
This was referenced Oct 4, 2021
This was referenced Oct 18, 2021
This was referenced Oct 21, 2021
Merged
Merged
Closed
Closed
This was referenced Oct 21, 2021
1 task
This was referenced Mar 7, 2022
This was referenced Mar 15, 2022
This was referenced Apr 17, 2022
This was referenced May 3, 2022
1 task
1 task
1 task
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
We are using Jersey version 2.27
The Jersey configuration has the SelectableEntityFilteringFeature configured.
The server environment is Felix server with Jetty.
When we send two concurrent same Web Service API calls to the server, the entity in the response got corrupted, i.e., some attributes in the entity got lost.
This is intermittent, but if it happens, all subsequent calls to that corrupted web service API will got back the same corrupted entity with same attributes missed.
Correct response entity example
[
{
"jobInstanceId": "1",
"jobId": "1",
"startTime": "2019-06-26T01:52:54",
"instanceState": {
"state": "FINISHED",
"detail": "Data discovery job finished successfully",
"reportedTime": "2019-06-26T01:53:04",
"stateSeq": 15
},
"schedule": "NOW",
},
{
"jobInstanceId": "2",
"jobId": "2",
"startTime": "2019-06-26T01:55:24",
"instanceState": {
"state": "FINISHED",
"detail": "Data discovery job finished successfully",
"reportedTime": "2019-06-26T01:55:38",
"stateSeq": 30
},
"schedule": "NOW",
},
{
"jobInstanceId": "3",
"jobId": "3",
"startTime": "2019-06-26T02:06:52",
"instanceState": {
"state": "FINISHED",
"detail": "Data discovery job finished successfully",
"reportedTime": "2019-06-26T02:07:06",
"stateSeq": 45
},
"schedule": "NOW",
}
]
Corrupted response entity example
[
{
"jobInstanceId": "1"
},
{
"jobInstanceId": "2"
},
{
"jobInstanceId": "3"
}
]
How to reproduce:
2) check if the response entity corrupted or not
3) if not corrupted, repeat from step 1). You may need many times retries.
Observed Jersey Exception stack trace (occurred in both Moxy provider and Jackson provide.)
With Moxy Provider
Similar stack trace for the Jackson Provider
Caused by:
|java.util.ConcurrentModificationException
| at java.util.HashMap$HashIterator.nextNode(HashMap.java:1442)
| at java.util.HashMap$EntryIterator.next(HashMap.java:1476)
| at java.util.HashMap$EntryIterator.next(HashMap.java:1474)
| at org.glassfish.jersey.internal.guava.AbstractMapBasedMultimap$AsMap$AsMapIterator.next(AbstractMapBasedMultimap.java:1348)
| at org.glassfish.jersey.internal.guava.AbstractMapBasedMultimap$AsMap$AsMapIterator.next(AbstractMapBasedMultimap.java:1336)
| at org.glassfish.jersey.internal.guava.TransformedIterator.next(TransformedIterator.java:45)
| at org.glassfish.jersey.internal.guava.AbstractMultimap.containsValue(AbstractMultimap.java:41)
| at org.glassfish.jersey.internal.guava.HashMultimap.containsValue(HashMultimap.java:44)
| at org.glassfish.jersey.message.filtering.EntityGraphImpl.presentInScopes(EntityGraphImpl.java:205)
| at org.glassfish.jersey.message.filtering.DefaultEntityProcessor.process(DefaultEntityProcessor.java:95)
| at org.glassfish.jersey.message.filtering.DefaultEntityProcessor.process(DefaultEntityProcessor.java:79)
| at org.glassfish.jersey.message.filtering.EntityInspectorImpl.inspectEntityProperties(EntityInspectorImpl.java:173)
| at org.glassfish.jersey.message.filtering.EntityInspectorImpl.inspect(EntityInspectorImpl.java:104)
| at org.glassfish.jersey.message.filtering.spi.AbstractObjectProvider.getFilteringObject(AbstractObjectProvider.java:90)
| at org.glassfish.jersey.message.filtering.spi.AbstractObjectProvider.getFilteringObject(AbstractObjectProvider.java:84)
| at org.glassfish.jersey.jackson.internal.FilteringJacksonJaxbJsonProvider.writeTo(FilteringJacksonJaxbJsonProvider.java:130)
| at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:266)
| at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:251)
| at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:163)
| at org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo(JsonWithPaddingInterceptor.java:109)
| at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:163)
| at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInterceptor.java:85)
| at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:163)
Possible Root Cause :
When two requests received by the Jetty server at the same time, two threads are dispatched to service the requests at the same time. The two threads are going to create the Entity Graph and Object Graph by both calling the following Methods in
org.glassfish.jersey.message.filtering.spi.AbstractObjectProvider.getFilteringObject(final Class<?> entityClass, final boolean forWriter, final Annotation... annotations)
The implementation in above method is not threads safe!
Once the corrupted filteringObject is saved to the Guava cache, it stays there, so all subsequent calls will get the same corrupted response entity
So the fix is how to make the buildup of Entity Graph and Object Graph to be thread save.
The text was updated successfully, but these errors were encountered: