Loading module failed for Android studio 2020.3.1

Answered

I have developed a plugin to load and unload multiple modules at the same time. This is mostly for our own internal use but I have opensourced this. I need to load and unload modules frequently and using IDE's UI is very slow, so I developed this plugin. Everything was working fine until the latest Android Studio update. Unloading of module works fine, but loading modules gives this error.

java.util.NoSuchElementException: Key Gradle: kaptGeneratedClasses is missing in the map.
at kotlin.collections.MapsKt__MapWithDefaultKt.getOrImplicitDefaultNullable(MapWithDefault.kt:24)
at kotlin.collections.MapsKt__MapsKt.getValue(Maps.kt:344)
at com.intellij.workspaceModel.ide.impl.jps.serialization.ModuleImlFileEntitiesSerializer.saveDependencyItem(ModuleImlFileEntitiesSerializer.kt:491)
at com.intellij.workspaceModel.ide.impl.jps.serialization.ModuleImlFileEntitiesSerializer.saveRootManagerElement(ModuleImlFileEntitiesSerializer.kt:430)
at com.intellij.workspaceModel.ide.impl.jps.serialization.ModuleImlFileEntitiesSerializer.saveModuleEntities(ModuleImlFileEntitiesSerializer.kt:384)
at com.intellij.workspaceModel.ide.impl.jps.serialization.ModuleImlFileEntitiesSerializer.saveEntities(ModuleImlFileEntitiesSerializer.kt:345)
at com.intellij.workspaceModel.ide.impl.jps.serialization.JpsProjectSerializersImpl.saveEntitiesBySerializer(JpsProjectSerializersImpl.kt:496)
at com.intellij.workspaceModel.ide.impl.jps.serialization.JpsProjectSerializersImpl.saveEntities(JpsProjectSerializersImpl.kt:438)
at com.intellij.workspaceModel.ide.impl.jps.serialization.JpsProjectModelSynchronizer.saveChangedProjectEntities(JpsProjectModelSynchronizer.kt:286)
at com.intellij.configurationStore.ProjectStoreBridge.saveModules(ProjectStoreBridge.kt:30)
at com.intellij.configurationStore.ProjectWithModulesStoreImpl.saveModules(ProjectStoreImpl.kt:166)
at com.intellij.configurationStore.ProjectStoreImpl$doSave$2$1.invokeSuspend(ProjectStoreImpl.kt:115)
(Coroutine boundary)
at com.intellij.configurationStore.ComponentStoreImpl.save$suspendImpl(ComponentStoreImpl.kt:166)
at com.intellij.configurationStore.StoreUtilKt.saveSettings(storeUtil.kt:89)
at com.intellij.configurationStore.StoreUtilKt.saveProjectsAndApp(storeUtil.kt:162)
at com.intellij.configurationStore.SaveAndSyncHandlerImpl.processTasks(SaveAndSyncHandlerImpl.kt:107)
at com.intellij.configurationStore.SaveAndSyncHandlerImpl$requestSave$1.invokeSuspend(SaveAndSyncHandlerImpl.kt:82)
Caused by: java.util.NoSuchElementException: Key Gradle: kaptGeneratedClasses is missing in the map.
at kotlin.collections.MapsKt__MapWithDefaultKt.getOrImplicitDefaultNullable(MapWithDefault.kt:24)
at kotlin.collections.MapsKt__MapsKt.getValue(Maps.kt:344)
at com.intellij.workspaceModel.ide.impl.jps.serialization.ModuleImlFileEntitiesSerializer.saveDependencyItem(ModuleImlFileEntitiesSerializer.kt:491)
at com.intellij.workspaceModel.ide.impl.jps.serialization.ModuleImlFileEntitiesSerializer.saveRootManagerElement(ModuleImlFileEntitiesSerializer.kt:430)
at com.intellij.workspaceModel.ide.impl.jps.serialization.ModuleImlFileEntitiesSerializer.saveModuleEntities(ModuleImlFileEntitiesSerializer.kt:384)
at com.intellij.workspaceModel.ide.impl.jps.serialization.ModuleImlFileEntitiesSerializer.saveEntities(ModuleImlFileEntitiesSerializer.kt:345)
at com.intellij.workspaceModel.ide.impl.jps.serialization.JpsProjectSerializersImpl.saveEntitiesBySerializer(JpsProjectSerializersImpl.kt:496)
at com.intellij.workspaceModel.ide.impl.jps.serialization.JpsProjectSerializersImpl.saveEntities(JpsProjectSerializersImpl.kt:438)
at com.intellij.workspaceModel.ide.impl.jps.serialization.JpsProjectModelSynchronizer.saveChangedProjectEntities(JpsProjectModelSynchronizer.kt:286)
at com.intellij.configurationStore.ProjectStoreBridge.saveModules(ProjectStoreBridge.kt:30)
at com.intellij.configurationStore.ProjectWithModulesStoreImpl.saveModules(ProjectStoreImpl.kt:166)
at com.intellij.configurationStore.ProjectStoreImpl$doSave$2$1.invokeSuspend(ProjectStoreImpl.kt:115)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:738)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
2021-10-05 05:55:41,080 [ 388553] ERROR - intellij.openapi.progress.Task - null

I am using this function to load the module

        modules.forEach {
val path = VirtualFileManager.getInstance()
.getFileSystem("file")
.refreshAndFindFileByPath(it.identifier)
?.toNioPath()
if (path != null) {
runWriteAction {
ModuleManager.getInstance(project).loadModule(path)
logger.debug("loading module: $it")
}
} else {
logger.warn("failed to resolve path for module: $it")
}
}

Previously I was using the deprecated function to load the modules with string path. I think the problem is caused by using the new function that takes the path argument.

0
3 comments

The exception is caused by a bug in intellij platform (IDEA-264111). It was fixed in 2021.1.2, but Android Studio is based on 2020.3.1 version of the platform. I think you may rewrite code in your plugin to avoid this bug. Note that ModuleManager.loadModule adds the specified module to the project, whereas 'setUnloadedModules' just mark it as unloaded, but doesn't fully remove the module from the project. So these actions aren't quite opposite, and if you want to load previously unloaded module back, it's better to invoke 'setUnloadedModules' and pass list where the module name is absent, instead of calling 'loadModule'.

0

Thank you so much for pointing that out, it makes perfect sense. I will use this approach to load modules.

0

However I am facing another problem now. When I trigger gradle sync after loading modules, I get the following exceptions

Caused by: com.intellij.serviceContainer.AlreadyDisposedException: Already disposed: Module: 'ModuleLoaderTest.features.FeatureA' (disposed)
at com.intellij.serviceContainer.ComponentManagerImpl.getMessageBus(ComponentManagerImpl.kt:175)
at com.android.tools.idea.model.AndroidModel.set(AndroidModel.java:61)
at com.android.tools.idea.projectsystem.gradle.sync.AndroidModuleDataServiceKt.configureFacet(AndroidModuleDataService.kt:285)
at com.android.tools.idea.projectsystem.gradle.sync.AndroidModuleDataServiceKt.access$configureFacet(AndroidModuleDataService.kt:1)
at com.android.tools.idea.projectsystem.gradle.sync.AndroidModuleDataService.importData(AndroidModuleDataService.kt:129)
at com.android.tools.idea.gradle.project.sync.idea.data.service.ModuleModelDataService.lambda$importData$0(ModuleModelDataService.java:46)
at com.intellij.openapi.command.WriteCommandAction.lambda$runWriteCommandAction$5(WriteCommandAction.java:362)
at com.intellij.openapi.command.WriteCommandAction$BuilderImpl$1.run(WriteCommandAction.java:112)
at com.intellij.openapi.application.RunResult.run(RunResult.java:35)
at com.intellij.openapi.command.WriteCommandAction.lambda$performWriteCommandAction$1(WriteCommandAction.java:253)
at com.intellij.openapi.application.impl.ApplicationImpl.runWriteAction(ApplicationImpl.java:1006)
at com.intellij.openapi.command.WriteCommandAction.lambda$performWriteCommandAction$2(WriteCommandAction.java:252)
at com.intellij.openapi.command.WriteCommandAction.lambda$doExecuteCommand$4(WriteCommandAction.java:310)
at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:220)
at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:187)
at com.intellij.openapi.command.WriteCommandAction.doExecuteCommand(WriteCommandAction.java:312)
at com.intellij.openapi.command.WriteCommandAction.performWriteCommandAction(WriteCommandAction.java:251)
at com.intellij.openapi.command.WriteCommandAction.lambda$execute$0(WriteCommandAction.java:236)
at com.intellij.openapi.application.TransactionGuardImpl.runWithWritingAllowed(TransactionGuardImpl.java:216)
at com.intellij.openapi.application.TransactionGuardImpl.access$200(TransactionGuardImpl.java:24)
at com.intellij.openapi.application.TransactionGuardImpl$2.run(TransactionGuardImpl.java:199)
at com.intellij.openapi.application.impl.ApplicationImpl.runIntendedWriteActionOnCurrentThread(ApplicationImpl.java:828)
at com.intellij.openapi.application.impl.ApplicationImpl.lambda$invokeAndWait$8(ApplicationImpl.java:482)
at com.intellij.openapi.application.impl.LaterInvocator$1.run(LaterInvocator.java:127)
at com.intellij.openapi.application.impl.FlushQueue.doRun(FlushQueue.java:85)
at com.intellij.openapi.application.impl.FlushQueue.runNextEvent(FlushQueue.java:134)
at com.intellij.openapi.application.impl.FlushQueue.flushNow(FlushQueue.java:47)
at com.intellij.openapi.application.impl.FlushQueue$FlushNow.run(FlushQueue.java:190)
at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:976)
at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:843)
at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$8(IdeEventQueue.java:454)
at com.intellij.openapi.progress.impl.CoreProgressManager.computePrioritized(CoreProgressManager.java:773)
at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$9(IdeEventQueue.java:453)
at com.intellij.openapi.application.impl.ApplicationImpl.runIntendedWriteActionOnCurrentThread(ApplicationImpl.java:828)
at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:501)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

I am triggering gradle sync programmatically using this code.

GradleSyncInvoker.getInstance().requestProjectSync(project, GradleSyncStats.Trigger.TRIGGER_USER_SYNC_ACTION)

 

0

Please sign in to leave a comment.