java.lang.ClassCastException: class lermitage.intellij.extraidetweaks.settings.SettingsIDEService cannot be cast to class lermitage.intellij.extraidetweaks.settings.SettingsIDEService (lermitage.intellij.extraidetweaks.settings.SettingsIDEService is in unnamed module of loader com.intellij.ide.plugins.cl.PluginClassLoader @3cd7f00f; lermitage.intellij.extraidetweaks.settings.SettingsIDEService is in unnamed module of loader com.intellij.ide.plugins.cl.PluginClassLoader @bba969). This issue makes me crazy. This happens when getting my service in a ModuleRootListener, or an AppLifecycleListener. I don’t know why.
This worked perfectly for years (at least 3 years), but the recent IDE releases broke this.
I opened an issue just in case (Youtrack issue). I’m wondering if you have the same problem.
java.lang.Throwable: krasa.grepconsole.tail.TailRunExecutor <clinit>
requests lermitage.intellij.extratci.SettingsService instance.
Class initialization must not depend on services. Consider using instance of the service on-demand instead.
Here the issue seems clear, right? You have a static final field probably in TailRunExecutor that want to access the service
TailRunExecutor comes fro another plugin (not mine). My plugin registers an IconPathPatcher, which changes many icons, including an icon from the other plugin.
I get my service in the IconPathPatcher:patchPath method (previously, I did this in my constructor, but got the same error), but it raises the given stacktrace. I don’t know why it says I’m in an “init” block.
It looks lioke you may not use services in this case. Icons can be used when application have not started yet from static contexts, for instance from AllIcons class; in these cases an exception during those classes init will ruin the class init and JVM will not try to init those again anymore.
Please avoid using services from stacks that originate in class loading activities. This is a real and not imaginary problem, that is why the assertion is present
java.lang.Throwable: icons.AwsIcons$Resources <clinit> requests lermitage.intellij.extratci.SettingsService instance. Class initialization must not depend on services. Consider using instance of the service on-demand instead.
at com.intellij.openapi.diagnostic.Logger.error(Logger.java:375)
at com.intellij.serviceContainer.ComponentManagerImplKt.checkOutsideClassInitializer(ComponentManagerImpl.kt:1585)
at com.intellij.serviceContainer.ComponentManagerImplKt.getOrCreateInstanceBlocking(ComponentManagerImpl.kt:1554)
at com.intellij.serviceContainer.ComponentManagerImpl.doGetService(ComponentManagerImpl.kt:752)
at com.intellij.serviceContainer.ComponentManagerImpl.getService(ComponentManagerImpl.kt:696)
at lermitage.intellij.extratci.SettingsService.getInstance(SourceFile:47)
at lermitage.intellij.extratci.d.a(SourceFile:34)
at lermitage.intellij.extratci.d.a(SourceFile:45)
at lermitage.intellij.extratci.SettingsService.getAllIcons(SourceFile:51)
at lermitage.intellij.extratci.d.a(SourceFile:161)
at lermitage.intellij.extratci.d.patchPath(SourceFile:89)
at com.intellij.ui.icons.IconTransform.applyPatchers(IconTransform.kt:91)
at com.intellij.ui.icons.IconTransform.patchPath(IconTransform.kt:77)
at com.intellij.ui.icons.CachedImageIconKt.patchIconPath(CachedImageIcon.kt:53)
at com.intellij.openapi.util.IconLoaderKt.findIconUsingDeprecatedImplementation(IconLoader.kt:354)
at com.intellij.openapi.util.IconLoaderKt.findIconUsingDeprecatedImplementation$default(IconLoader.kt:346)
at com.intellij.openapi.util.IconLoader.getIcon(IconLoader.kt:113)
at icons.AwsIcons.load(AwsIcons.kt:190)
at icons.AwsIcons.access$load(AwsIcons.kt:14)
at icons.AwsIcons$Resources.<clinit>(AwsIcons.kt:65)
Here your service initialized from class loading activity of AwsIcons class
I can only suggest some other SPI, your own or ServiceLoader of JVM, but yes accessing services from static context is unsafe and LOG.error there is important
I believe since icons used often from static context you must adapt your solution to that. I can only repeat - this is a real problem that needs to be addressed.
I believe since icons used often from static context you must adapt your solution to that. I can only repeat - this is a real problem that needs to be addressed.
I’m completely lost. What should I do? IconPathPatcher worked for years.
They are racy I believe because classloading is concurrent and depends on init sequence. You may try to ask for icons classes fields in some early init stages, e.g. ApplicationActivity
@State(
name = "ExtraTciSettings",
storages = @Storage(value = "lermitage-extratci.xml", roamingType = RoamingType.DEFAULT),
category = SettingsCategory.PLUGINS
)
public class SettingsService implements PersistentStateComponent<SettingsService> {
private static final @NonNls Logger LOGGER = Logger.getInstance(SettingsService.class);
// the implementation of PersistentStateComponent works by serializing public fields, so keep them public
@SuppressWarnings("WeakerAccess")
public List<String> disabledIcons = new ArrayList<>();
@SuppressWarnings("WeakerAccess")
public UITypeIconsPreference uiTypeIconsPreference;
@SuppressWarnings("WeakerAccess")
public Boolean lifetimeLicHintNotifDisplayed2;
public static SettingsService getInstance() {
return ApplicationManager.getApplication().getService(SettingsService.class);
}
...
Should I replace getInstance() by ApplicationManager.getApplication().getService(SettingsService.class) everywhere? Is it why the IDE thinks I’m in an init block?
Again, all these errors are very new. Something changed recently in the IDE…
My customers are also facing `java.lang.ClassCastException: class lermitage.intellij.extraidetweaks.settings.SettingsIDEService cannot be cast to class lermitage.intellij.extraidetweaks.settings.SettingsIDEService` errors, which, I guess, breaks my plugins. I can’t explain these errors (the package name is different because I have 4 plugins. They’re all affected by the same errors. Their settings service are very similar).
This error is very new, and it seems related to the PluginClassLoader. I do not touch class loaders…
Do you have optionally loaded modules though in the plugin? Usually such errors caused by the fact that a class of an optionally loaded module touched from the main plugin classloader directly. Such things lead to double classloading in two class loaders