java.util.ConcurrentModificationException from the "session" compactFlashScope.cfc

I have been seeing the following error in our logs frequently after upgrading to ColdBox 3.5 beta. In this particular instance, it is using the “session” scope and the thought occurs to me that perhaps the problem can be fixed by locking that scope before running the structDelete function. I have put this in place on our server, but since I cant get a consistent duplication, I am watching the logs to see if the issue is resolved.

Does anyone have any thoughts on this, or is there any other information I should provide to further illuminate the issue? Maybe I am just using something incorrectly, but I am not sure what it would be.

Oops! Exception Encountered### Application Execution ExceptionError Type: java.util.ConcurrentModificationException : [N/A]

Error Messages:

Tag Context:
ID: CF_CASEINSENSITIVEMAP
LINE: 84
Template: C:\Projects\kostizi\coldbox\system\web\flash\AbstractFlashScope.cfc
ID: CF_UDFMETHOD
LINE: 133
Template: C:\Projects\kostizi\coldbox\system\web\flash\AbstractFlashScope.cfc
ID: CF_TEMPLATEPROXY
LINE: 118
Template: C:\Projects\kostizi\coldbox\system\web\services\RequestService.cfc
ID: CF_TEMPLATEPROXY
LINE: 179
Template: C:\Projects\kostizi\coldbox\system\Coldbox.cfc
ID: CF_UDFMETHOD
LINE: 55
Template: C:\Projects\kostizi\Application.cfc
Framework Snapshot
Current Event: ajax.getMerchantList
Current Layout: N/A (Module: )
Current View: N/A
Bug Date: 03/12/2012 03:52:52 PM
Coldfusion ID: CFID= ; CFToken= ; JSessionID=84303adf17698a979e446219426a2f5e2a2a
Template Path : C:\Projects\kostizi\index.cfm
Path Info :
Host & Server: www.kostizi.com WIN-KOSTIZI
Query String:
Referrer: https://www.kostizi.com/boGC/dspCertificateUpdate/1514
Browser: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3
Remote Address: 64.244.90.66
Form variables:
MICROSITEONLY: 0
MPFILTER: 24
EVENT: ajax.getMerchantList
RENDERTYPE: json
Session Storage:
mpFilter: 24
boIsSuperAdmin: 1
boUserId: 15
qPartnerPreferences: qPartnerPreferences [complex]
boPartnerName: Kostizi
boRedirectString: boGC.dspCertificateTypesList
boUser:

mpId: 1
boIsDeveloper: 1
boMediaPartnerId: 1
baseURL: https://www.kostizi.com
boLoginStatus: ok
Cookies:
__unam: bdaa7f2-12dcdfc0557-776d4245-109
__qca: P0-830092219-1317655531772
s_dslv: 1320166738596
CFID: 108808113
CFTOKEN: 77227087
JSESSIONID: 84303adf17698a979e446219426a2f5e2a2a
__utma: 232597824.563824848.1299711035.1331580502.1331586570.1134
__utmb: 232597824.5.10.1331586570
__utmc: 232597824
__utmz: 232597824.1331570333.1130.480.utmcsr=kostizi.com|utmccn=(referral)|utmcmd=referral|utmcct=/boDailyDeals/dspDailyDeals
Stack Trace:

java.util.ConcurrentModificationException
	at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)
	at java.util.HashMap$KeyIterator.next(HashMap.java:828)
	at java.util.AbstractCollection.toArray(AbstractCollection.java:171)
	at coldfusion.util.CaseInsensitiveMap$FastHashKeyEnumerator.

Extra Information Dump
[N/A]

I apologize for not including the version in the subject. I just read the new posting rules and I don’t see a way to change it.

This error is caused when you are iterating through an array, at the same time it is being removed or delete etc.

The only way around this that I can tell, is too put locks around where you are using this.

In this case, it seems to be coming from iterating through a structure, but I am assuming its the same issue?

for(key in scope){
if( scope[key].autoPurge ){
structDelete(scope, key);
}
}

Ok am I guessing you have lots of Ajax requests?

This doesn’t even have to be an Ajax request.

I ran into a similar problem about this when modifying an array, that was in a singleton that was being read at the same time another connection was in the process.

So even though it is a concurrent issue, it is not specific to an Ajax request. And the clue is that this is stored in the session scope, where two concurrent can cause this issue when modifying something like this.

That’s the thing. Maybe we need to add locking to the session scope in the flash scope as Ajax requests is the cause of the issue as they are asynchronous requests.

Ajax is a cause, it is not the only cause. 2 concurrent request will cause this too.

It might pay to lock this down.

That’s actually what I did and it seems to be working pretty well. Its only been a day, but I haven’t seen any of these errors since then. It does make sense that its more prevalent when doing ajax requests, since several of them may be happening at the same time for a particular user.

I am sure there is a better way to do this, but this is what I did in the AbstractFlashScope.cfc:

var key = ""; var scope = "";

// Check if flash exists
if( flashExists() ){
scope = getFlash();

// jreese: lock the session scope so to stop ConcurrentModificationException errors
if(instance.controller.getConfigSettings().flashURLPersistScope eq ‘session’){

lock scope=‘session’ type=‘exclusive’ timeout=10 {

// loop over contents and clear flash items that are marked for autopurging.
for(key in scope){
if( scope[key].autoPurge ){
structDelete(scope, key);
}
}

// Destroy if empty
if( structIsEmpty(scope) ){
removeFlash();
}
}

} else {

// loop over contents and clear flash items that are marked for autopurging.
for(key in scope){
if( scope[key].autoPurge ){
structDelete(scope, key);
}
}

// Destroy if empty
if( structIsEmpty(scope) ){
removeFlash();
}

}

}

I have modified the flash scopes a bit and just committed them, Can you please try with this new strategy please:

Let me know how it works out

Luis F. Majano
CEO
Ortus Solutions, Corp
www.ortussolutions.com

ColdBox Platform: http://www.coldbox.org
Linked In: http://www.linkedin.com/pub/3/731/483
Blog: http://www.luismajano.com
IECFUG Manager: http://www.iecfug.com

Social: twitter.com/lmajano facebook.com/lmajano

Ah… I knew there was a better place to do the locking. Makes sense that it happens in the sessionFlash object. I will put this in place and report back.

Luis, you are a friggin’ Ninja and I am surprised you got to this so quick!

Thank you very much.