I had the similar problem. If my end action was called through a form submit I was always getting an error saying that the conversation was already closed or expired.
Of course if you don't finish the conversation, memory resources won't be released. You can get some information about this in the strut2 conversation plugin site: https://code.google.com/p/struts2-conversation/wiki/UsageGuide#Memory_Management
There you can see that it is possible to set some parameters related with the expiration of the conversation thread and the number of them that can be used at the same time:
<!-- monitoring frequency in milliseconds -->
<constant name="conversation.monitoring.frequency" value="300000"/>
<!-- idle conversation timeout in milliseconds -->
<constant name="conversation.idle.timeout" value="28800000"/>
<!-- max instances of a conversation -->
<constant name="conversation.max.instances" value="20"/>
<!-- number of timeout monitoring threads -->
<constant name="conversation.monitoring.thread.pool.size" value="20"/>
Anyway, I resolved this issue adding a redirect result in the last action which calls to an action which contains the @EndConversation tag. In it I just set the result I wanted to be the last one. The conversation fields variables are still correct set and available.
@ConversationAction(conversations = "form")
@Action(value="formSecondLast", results={@Result(name=SUCCESS, type = "redirect", location="formLast")})
public String formSecondLast() throws Exception {
//Here goes the code you want it to manipulate the conversation field data.
//Maybe save to the database or send it to the business tier.
return SUCCESS;
}
@EndConversation(conversations = "form")
@Action(value="formLast", results={@Result(name=SUCCESS, location="/jsp/form-end.jsp")})
public String formEnd() throws Exception {
// This is a dummy action that does not do anything.
// It is called just after formSecondLast ends and sends the user the jsp page.
return SUCCESS;
}