Defeating Concurrent Modification Exceptions (CME) in Java

If you’re like me, sometimes you’ll try to program something in a way that seems very intuitive and then find that it is the wrong way to do it, and that it is actually quite catastrophic. Enter Concurrent Modification Exception. Here’s an example code snippet from where a Concurrent Modification Exception occurred:

public boolean handle(CommandSender sender) {
	Player player = Helper.validateCommandSender(sender);
	//if player is in a faction
	if ( Helper.isPlayerInAnyFaction(player.getDisplayName()) ) {
		Faction fac = Helper.getPlayerFaction(player.getUniqueId());
		
		for (LandClaim lc : fac.getClaims()) {
			fac.removeClaim(lc);
		}
		sender.sendMessage(MsgPrefix.INFO + "You have unclaimed all land claims.");
		Faction.serialize(fac, fac.getAutoFileName());
		return true;
	}
	
	return false;
}

Can you spot the problem?

Don’t feel too bad if you don’t see it straight-away. The issue lies with the body of the enhanced for-loop. You see in this case the cause of the exception was that I was attempting to change elements of an arraylist, specifically an arraylist, while actively iterating over it.

The solution was actually quite simple:

public boolean handle(CommandSender sender) {
	Player player = Helper.validateCommandSender(sender);
	//if player is in a faction
	if ( Helper.isPlayerInAnyFaction(player.getDisplayName()) ) {
		Faction fac = Helper.getPlayerFaction(player.getUniqueId());
		
		//added to prevent CME
		ArrayList<LandClaim> claimsList = new ArrayList<LandClaim>();
		
		for (LandClaim lc : claimsList) {
			fac.removeClaim(lc);
		}
		sender.sendMessage(MsgPrefix.INFO + "You have unclaimed all land claims.");
		Faction.serialize(fac, fac.getAutoFileName());
		return true;
	}
	
	return false;
}

Rather than iterating over the arraylist that I am actively trying to change, the solution was to iterate over a copy of the original arraylist, and I was no longer running into the tricky Concurrent Modification Exception.

The moral of the story

It is very easy for someone to say that one should write their code correctly the first time. Story-boarding and planning are sure to help mitigate some of the troubles that befall programmers but many of us are headstrong and eager to get things done quickly. It is also the case that sometimes when implementing something we get a little lost on the finer details. But what was most troublesome about this particular exception for me was that this isn’t obvious at all. I am a college graduate (Computer Information Systems) and I don’t remember ever being warned about this. I just want to point out that even with years of studying and programming under your belt sometimes you too can have egg on your face. You are never done learning.

Leave a comment