Bug - Fixed Concurrent modification exception when whitelisting to two clans in a session

Ryo_Sangnoir

Developer
Staff member
Introduced in r27086:

Code:
Unexpected error, debug log printed.
class java.util.ConcurrentModificationException: null
java.util.ConcurrentModificationException
    at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1013)
    at java.base/java.util.ArrayList$Itr.next(ArrayList.java:967)
    at net.sourceforge.kolmafia.session.ClanManager.changeClan(ClanManager.java:166)
    at net.sourceforge.kolmafia.session.ClanManager.setClanName(ClanManager.java:217)
    at net.sourceforge.kolmafia.request.ProfileRequest.refreshFields(ProfileRequest.java:248)
    at net.sourceforge.kolmafia.request.ProfileRequest.processResults(ProfileRequest.java:518)
    at net.sourceforge.kolmafia.request.GenericRequest.processResponse(GenericRequest.java:2203)
    at net.sourceforge.kolmafia.request.GenericRequest.retrieveServerReply(GenericRequest.java:2109)

While iterating over ClanManager.getClanLounge() we may call ClanLoungeRequest.addSpeakeasyDrink which calls ClanManager.addToLounge which modifies the list we're iterating over.
 

Veracity

Developer
Staff member
Code:
  public static final void changeClan(final int clanId, String clanName) {
    // Drop all saved clan information
    ClanManager.clearCache(false);
It starts by clearing all saved info - including which Speakeasy drinks are present.

Code:
  public static final void clearCache(boolean newCharacter) {
...
    ClanLoungeRequest.resetHotdogs();
    ClanLoungeRequest.resetSpeakeasy();
    ClanLoungeRequest.resetFloundry();
...
    if (newCharacter) {
      ClanManager.clanLounge.clear();
      ClanManager.clanRumpus.clear();
      ClanManager.clanHotdogs.clear();
    }
  }
But the AdventureResults for speakeasy/rumpus/floundry are left intact.

Code:
      if (!ClanManager.getClanRumpus().isEmpty()) {
        // All of this stuff has already been checked, but hot dogs and
        // such need to be re-added as concoctions for the returned-to clan
        for (AdventureResult item : ClanManager.getClanLounge()) {
And then it iterates over those AdventureResults and wants the speakeasy/hotdogs/floundry to rebuild their availability data but not add the AdventureResults to the list.

Well, cool. That obviates having to go look at the clan furniture item and reparsing.

Should be easy to fix.
 

Malibu Stacey

Active member
Getting debug errors when switching clans via whitelist every time from the second onwards in r27088

Code:
Unexpected error, debug log printed.
class java.util.ConcurrentModificationException: null
java.util.ConcurrentModificationException
    at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1013)
    at java.base/java.util.ArrayList$Itr.next(ArrayList.java:967)
    at net.sourceforge.kolmafia.session.ClanManager.changeClan(ClanManager.java:166)
    at net.sourceforge.kolmafia.session.ClanManager.setClanName(ClanManager.java:217)
    at net.sourceforge.kolmafia.request.ProfileRequest.refreshFields(ProfileRequest.java:248)
    at net.sourceforge.kolmafia.request.ProfileRequest.processResults(ProfileRequest.java:518)
    at net.sourceforge.kolmafia.request.GenericRequest.processResponse(GenericRequest.java:2203)
    at net.sourceforge.kolmafia.request.GenericRequest.retrieveServerReply(GenericRequest.java:2109)
    at net.sourceforge.kolmafia.request.GenericRequest.retrieveServerReply(GenericRequest.java:1724)
    at net.sourceforge.kolmafia.request.GenericRequest.externalExecute(GenericRequest.java:1391)
    at net.sourceforge.kolmafia.request.GenericRequest.execute(GenericRequest.java:1378)
    at net.sourceforge.kolmafia.request.GenericRequest.run(GenericRequest.java:1145)
    at net.sourceforge.kolmafia.RequestThread.postRequest(RequestThread.java:242)
    at net.sourceforge.kolmafia.RequestThread.postRequest(RequestThread.java:207)
    at net.sourceforge.kolmafia.session.ClanManager.retrieveClanIdAndName(ClanManager.java:130)
    at net.sourceforge.kolmafia.session.ClanManager.getClanId(ClanManager.java:134)
    at net.sourceforge.kolmafia.request.ShowClanRequest.parseResponse(ShowClanRequest.java:32)
    at net.sourceforge.kolmafia.session.ResponseTextParser.externalUpdate(ResponseTextParser.java:531)
    at net.sourceforge.kolmafia.session.ResponseTextParser.externalUpdate(ResponseTextParser.java:217)
    at net.sourceforge.kolmafia.request.GenericRequest.processResults(GenericRequest.java:2380)
    at net.sourceforge.kolmafia.request.PasswordHashRequest.processResults(PasswordHashRequest.java:18)
    at net.sourceforge.kolmafia.request.GenericRequest.processResponse(GenericRequest.java:2203)
    at net.sourceforge.kolmafia.request.GenericRequest.retrieveServerReply(GenericRequest.java:2109)
    at net.sourceforge.kolmafia.request.GenericRequest.retrieveServerReply(GenericRequest.java:1724)
    at net.sourceforge.kolmafia.request.GenericRequest.externalExecute(GenericRequest.java:1391)
    at net.sourceforge.kolmafia.request.GenericRequest.execute(GenericRequest.java:1378)
    at net.sourceforge.kolmafia.request.GenericRequest.run(GenericRequest.java:1145)
    at net.sourceforge.kolmafia.request.RelayRequest.run(RelayRequest.java:3538)
    at net.sourceforge.kolmafia.RequestThread.postRequest(RequestThread.java:242)
    at net.sourceforge.kolmafia.RequestThread.postRequest(RequestThread.java:207)
    at net.sourceforge.kolmafia.webui.RelayAgent.readServerResponse(RelayAgent.java:436)
    at net.sourceforge.kolmafia.webui.RelayAgent.performRelay(RelayAgent.java:104)
    at net.sourceforge.kolmafia.webui.RelayAgent.run(RelayAgent.java:83)

Code:
Unexpected error, debug log printed.
class java.util.ConcurrentModificationException: null
java.util.ConcurrentModificationException
    at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1013)
    at java.base/java.util.ArrayList$Itr.next(ArrayList.java:967)
    at net.sourceforge.kolmafia.session.ClanManager.changeClan(ClanManager.java:166)
    at net.sourceforge.kolmafia.session.ClanManager.setClanName(ClanManager.java:217)
    at net.sourceforge.kolmafia.request.ProfileRequest.refreshFields(ProfileRequest.java:248)
    at net.sourceforge.kolmafia.request.ProfileRequest.processResults(ProfileRequest.java:518)
    at net.sourceforge.kolmafia.request.GenericRequest.processResponse(GenericRequest.java:2203)
    at net.sourceforge.kolmafia.request.GenericRequest.retrieveServerReply(GenericRequest.java:2109)
    at net.sourceforge.kolmafia.request.GenericRequest.retrieveServerReply(GenericRequest.java:1724)
    at net.sourceforge.kolmafia.request.GenericRequest.externalExecute(GenericRequest.java:1391)
    at net.sourceforge.kolmafia.request.GenericRequest.execute(GenericRequest.java:1378)
    at net.sourceforge.kolmafia.request.GenericRequest.run(GenericRequest.java:1145)
    at net.sourceforge.kolmafia.RequestThread.postRequest(RequestThread.java:242)
    at net.sourceforge.kolmafia.RequestThread.postRequest(RequestThread.java:207)
    at net.sourceforge.kolmafia.session.ClanManager.retrieveClanIdAndName(ClanManager.java:130)
    at net.sourceforge.kolmafia.session.ClanManager.getClanId(ClanManager.java:134)
    at net.sourceforge.kolmafia.request.ClanHallRequest.parseResponse(ClanHallRequest.java:23)
    at net.sourceforge.kolmafia.session.ResponseTextParser.externalUpdate(ResponseTextParser.java:279)
    at net.sourceforge.kolmafia.session.ResponseTextParser.externalUpdate(ResponseTextParser.java:217)
    at net.sourceforge.kolmafia.request.GenericRequest.processResults(GenericRequest.java:2380)
    at net.sourceforge.kolmafia.request.GenericRequest.processResponse(GenericRequest.java:2203)
    at net.sourceforge.kolmafia.request.GenericRequest.retrieveServerReply(GenericRequest.java:2109)
    at net.sourceforge.kolmafia.request.GenericRequest.retrieveServerReply(GenericRequest.java:1724)
    at net.sourceforge.kolmafia.request.GenericRequest.externalExecute(GenericRequest.java:1391)
    at net.sourceforge.kolmafia.request.GenericRequest.execute(GenericRequest.java:1378)
    at net.sourceforge.kolmafia.request.GenericRequest.run(GenericRequest.java:1145)
    at net.sourceforge.kolmafia.RequestThread.postRequest(RequestThread.java:242)
    at net.sourceforge.kolmafia.RequestThread.postRequest(RequestThread.java:207)
    at net.sourceforge.kolmafia.textui.RuntimeLibrary.visit_url(RuntimeLibrary.java:3305)
    at net.sourceforge.kolmafia.textui.RuntimeLibrary.visit_url(RuntimeLibrary.java:3253)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at net.sourceforge.kolmafia.textui.parsetree.LibraryFunction.executeWithoutInterpreter(LibraryFunction.java:108)
    at net.sourceforge.kolmafia.textui.javascript.LibraryFunctionStub.execute(LibraryFunctionStub.java:48)
    at net.sourceforge.kolmafia.textui.javascript.AshStub.call(AshStub.java:103)
    at net.sourceforge.kolmafia.textui.javascript.LibraryFunctionStub.call(LibraryFunctionStub.java:100)
    at org.mozilla.javascript.Interpreter.interpretLoop(Interpreter.java:1871)
    at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:1053)
    at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:90)
    at net.sourceforge.kolmafia.textui.javascript.JavascriptRuntime.lambda$executeRun$2(JavascriptRuntime.java:305)
    at net.sourceforge.kolmafia.textui.javascript.JavascriptRuntime.executeFunction(JavascriptRuntime.java:224)
    at net.sourceforge.kolmafia.textui.javascript.JavascriptRuntime.executeRun(JavascriptRuntime.java:282)
    at net.sourceforge.kolmafia.textui.javascript.JavascriptRuntime.lambda$execute$0(JavascriptRuntime.java:202)
    at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:380)
    at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3868)
    at net.sourceforge.kolmafia.textui.javascript.JavascriptRuntime.execute(JavascriptRuntime.java:201)
    at net.sourceforge.kolmafia.textui.AbstractRuntime.execute(AbstractRuntime.java:24)
    at net.sourceforge.kolmafia.textui.command.CallScriptCommand.call(CallScriptCommand.java:194)
    at net.sourceforge.kolmafia.KoLmafiaCLI.doExecuteCommand(KoLmafiaCLI.java:463)
    at net.sourceforge.kolmafia.KoLmafiaCLI.executeCommand(KoLmafiaCLI.java:419)
    at net.sourceforge.kolmafia.KoLmafiaCLI.executeLine(KoLmafiaCLI.java:338)
    at net.sourceforge.kolmafia.KoLmafiaCLI.executeLine(KoLmafiaCLI.java:225)
    at net.sourceforge.kolmafia.swingui.CommandDisplayFrame$CommandQueueHandler.handleQueue(CommandDisplayFrame.java:139)
    at net.sourceforge.kolmafia.swingui.CommandDisplayFrame$CommandQueueHandler.run(CommandDisplayFrame.java:116)

First one was from using the /whitelist chat command manually, second was from using visit_url() in a script.
 
Top