
|
If you were logged in you would be able to see more operations.
|
|
|
|
Original Estimate:
|
Unknown
|
Remaining Estimate:
|
Unknown
|
Time Spent:
|
Unknown
|
|
Issue Links:
|
Duplicate
|
|
|
|
This issue is duplicated by:
|
|
UP-1124
PortletStateManager.clearState(Portle...
|
|
|
|
|
|
|
PortletStateManager.clearState(PortletWindow) implementation is buggy and can lead to ConcurrentModificationException under stress.
Under stress, you can
run into the following scenaro which produces this stack trace.
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:782)
at java.util.HashMap$KeyIterator.next(HashMap.java:818)
at org.jasig.portal.container.services.information.PortletStateManager.clearState(PortletStateManager.java:355)
at
org.jasig.portal.channels.portlet.CPortletAdapter.receiveEvent(CPortletAdapt
er.java:345)
at
org.jasig.portal.MultithreadedCharacterChannelAdapter.receiveEvent(Multithre
adedCharacterChannelAdapter.java:62)
at
org.jasig.portal.ChannelManager.finishedSession(ChannelManager.java:269)
After examining the code, it looks like you'd get this exception when two
users end/begin the lifecycle of this channel at the same time (likely under
stress??), since they both have access to the same Map object at the same
time -- classic concurrency stuff. And once the remove operation throws
that exception, I believe the ChannelState object get left behind. It looks
like remove's and put's into the channelStateMap need to broken out into
synchronized methods.
|
|
Description
|
PortletStateManager.clearState(PortletWindow) implementation is buggy and can lead to ConcurrentModificationException under stress.
Under stress, you can
run into the following scenaro which produces this stack trace.
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:782)
at java.util.HashMap$KeyIterator.next(HashMap.java:818)
at org.jasig.portal.container.services.information.PortletStateManager.clearState(PortletStateManager.java:355)
at
org.jasig.portal.channels.portlet.CPortletAdapter.receiveEvent(CPortletAdapt
er.java:345)
at
org.jasig.portal.MultithreadedCharacterChannelAdapter.receiveEvent(Multithre
adedCharacterChannelAdapter.java:62)
at
org.jasig.portal.ChannelManager.finishedSession(ChannelManager.java:269)
After examining the code, it looks like you'd get this exception when two
users end/begin the lifecycle of this channel at the same time (likely under
stress??), since they both have access to the same Map object at the same
time -- classic concurrency stuff. And once the remove operation throws
that exception, I believe the ChannelState object get left behind. It looks
like remove's and put's into the channelStateMap need to broken out into
synchronized methods. |
Show » |
|
I'm concerned with the implementation of the clearState method and
actually the PortletStateManager in general.
The fact that we cannot use normal get or remove methods to
retrieve/remove items from the map when we have the key implies there
may be something wrong with the implementation.
It seems like we should have a Map keyed on geyKey(portletWindow) and
then the Map stores Maps which are keyed on whatever additional
information was used in the first Key.
Then we can do something like this:
Map map = <whereever we got map from>
String key = getKey(portletWindow) <-- can we even just key on portlet
windows???)
Map portletWindowMap = map.get(key);
portletWindowMap.clear();
map.remove(key);
However this would most likely require other code to be rewritten (and
is incompatible with clearState(HttpServletRequest). What are the use
cases when clearState(HttpServletRequest) would be called vs.
clearState(PortletWindow)
Also, getKey is checking if a session exists (clearState does this
also) but it calls request.getSession() which according to the JavaDoc
does this: "Returns the current session associated with this request, or
if the request does not have a session, creates one."