[jbossseam-issues] [JBoss JIRA] Commented: (JBSEAM-3652) Major reentrancy problem with "Page Scope" components and injection/disinjection
Dan Allen (JIRA)
jira-events at lists.jboss.org
Fri Nov 14 00:33:48 EST 2008
[ https://jira.jboss.org/jira/browse/JBSEAM-3652?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12438410#action_12438410 ]
Dan Allen commented on JBSEAM-3652:
I thoroughly studied the attached cases as well as the existing unit tests and have answers/responses to all of your questions.
You were correct that there was a bug in the counter logic. Both finally blocks were decrementing the counter for the same invocation. I have changed it so that the first finally block consults the value of the counter without changing the value. I also changed the field name from "counter" to "client" to make it more apparent that we are counting client threads.
Fixing the counter bug brings the other observations into focus. Let's take each test scenario in turn.
Case 1: An instance of the page-scoped component exists at the time the user clicks on the button to activate one of its methods. No long-running conversation exists.
If the page-scoped component is not synchronized, then each concurrent click will invoke the same page-scoped component, but the conversation-scoped component will only be injected on the first invocation since injection does not happen again until the component has no more clients (invoking threads). That is why you only see one instance of the conversation-scoped component and not one per click. If you add @Synchronized to the page-scoped component, then each click is processed in turn, and then you have one conversation-scoped component created and injected per click. Page-scoped components are now synchronized by default.
Case 2: The page-scoped component is created when the user clicks on the link. No long-running conversation exists.
In this case, a new page-scoped component created (and in turn a new conversation-scoped component created and injected) per click. The reason is that Seam only flushes the page context held in a thread local at the end of the request. Thus, even though you are invoking a command button from the same view, the newly created page-scoped component is not yet associated with that UI component tree. In this case, it's really like 6 different requests because none of the requests know that the other requests have also created a page-scoped component.
Case 3: An instance of the page-scoped component exists at the time the user clicks on the button to activate on of its methods. A long-running conversation is active.
In this case, a long-running conversation is active and Seam is serializing access to that conversation. Therefore, the page-scoped component is naturally protected against concurrent access. Essentially, access to the entire UI component tree is being serialized by the conversation.
Case 4: The page-scoped component is created when the user clicks on the link, also creating a long-running conversation.
Exactly the same explanation as Case #2.
> Major reentrancy problem with "Page Scope" components and injection/disinjection
> Key: JBSEAM-3652
> URL: https://jira.jboss.org/jira/browse/JBSEAM-3652
> Project: Seam
> Issue Type: Bug
> Affects Versions: 2.0.2.SP1, 2.0.3.CR1, 2.1.0.GA
> Environment: WebSphere v188.8.131.52 in POJO Mode
> Reporter: Denis Forveille
> Assignee: Dan Allen
> Priority: Blocker
> Fix For: 2.1.1.CR1
> Attachments: Test3652.java, Test3652Conv.java, testJBSEAM3652.xhtml, traces.txt
> This bug is very similar to the JBSEAM-3295 bug, but for "Page Scope" components this time
> Under stress, we have random NPE, "conversation expired" and other strange eroors from time to time in production
> This is due to a flaw in the "BijectionInterceptor" class and it is quite easy to reproduce
> On a facelets page, we have a datatable with a list of h:commadLink, teh first page of a classic "list entities/showDetail" scheme. The controleur that manages the list is in "Page Scope"
> When the user clics on one of the link, then quickly clic on another link, another one etc... without waiting for the detail view to show up, we have two concurrent request addressed to the same Page Scope component (Verified by putting traces in the BijectionInterceptor class)
> In BijectionInterceptor, in that case, counter == 2 after line 77 meaning there is two concurrent thread running: the current thread + another one currently "using" the component
> The counter will be decrease for the first time on line 82, then a second time on line 129 and so, disinjection will occur on line 134. This occurs while there is another thread "using" the component, causing random NPE and other errors!!!!
> In fact this will happen each time counter >1, ie there is more than one "concurrent" request on the same component
> This alleviate some questions:-
> - is this normal that 2 (or more) concurrent request from the same user/conversation/page acces the same page scope component concurrently (I thought seam was taking care of this and was serializing such requests...
> - is this normal that on line 88, components are outjected, only when the last concurrent "user" of the component exits the interceptor and not when each request "eixts" the interceptor?
This message is automatically generated by JIRA.
If you think it was sent incorrectly contact one of the administrators: https://jira.jboss.org/jira/secure/Administrators.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira
More information about the seam-issues