SFSB not removed from session when temporary conversation ends
--------------------------------------------------------------
Key: JBSEAM-3622
URL:
https://jira.jboss.org/jira/browse/JBSEAM-3622
Project: Seam
Issue Type: Bug
Components: Core
Affects Versions: 2.1.0.GA, 2.0.3.CR1
Environment: JBoss 4.2.2, Seam 2.0.3.CR1
Reporter: Nikolay Elenkov
I came across this while checking my app for session leaks. I have a simple listeners that
dumps session attributes on every add/remove/replace.
When I end a conversation, all entities are removed from the session, as expected.
However, manager components (SFSB's) are left over. Repeatedly starting and ending a
conversation results in something like (17, 18, 19 have ended, all other attributes for
those conversations have been removed from session; 20 is active):
20:11:12,440 INFO [STDOUT] org.jboss.seam.CONVERSATION#17$userManager
20:11:12,440 INFO [STDOUT] org.jboss.seam.CONVERSATION#18$userManager
20:11:12,440 INFO [STDOUT] org.jboss.seam.CONVERSATION#19$userManager
20:11:12,440 INFO [STDOUT] org.jboss.seam.CONVERSATION#20$userManager
20:11:12,440 INFO [STDOUT] org.jboss.seam.CONVERSATION#20$user
I stepped through this with the debugger, and it seems that SFSB's are not removed if
the conversation is a temporary one.
Here's what (I think) happens:
1. Conversation ended by @End or pages.xml
2. SFSB's @Remove @Destroy destroy() method is called
3. RemoveInterceptor calls ServerConversationContext#remove(). That results in the
component's name being added to ServerConversationContext#removals.
4. When ServerConversationContext#flush() is called, names in the removals list are
not actually removed from the session, because the conversation is temporary (see ***
below)
from ServerConversationContext.java:
public void flush()
{
boolean longRunning = !isCurrent() ||
Manager.instance().isLongRunningConversation();
if ( longRunning )
{
// ....
}
else
{
//TODO: for a pure temporary conversation, this is unnecessary, optimize it
// *** Here: getNamesFromSession does not include removals, so they are left
over
// Should probably be like this:
// START
for (String name: removals) {
session.remove(getKey(name));
}
removals.clear();
// END
for ( String name: getNamesFromSession() )
{
session.remove( getKey(name) );
}
}
}
private Set<String> getNamesFromSession()
{
HashSet<String> results = new HashSet<String>();
String prefix = getPrefix(getId());
for (String name: session.keySet()) {
if (name.startsWith(prefix)) {
name = name.substring(prefix.length());
if (!removals.contains(name)) { // *** Here: name not added to results if in
the removals list
results.add(name);
}
}
}
return results;
}
--
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