由多个 class 加载程序加载的相同 class - Intellij 插件

Same class loaded by multiple class loaders - Intellij plugin

正在开发一个插件,以使用 Intellij 为 android studio 扩展新项目向导。

当我尝试调用 AndroidSdkUtils.isAndroidSdkAvailable() 时得到 Assertion:null,粘贴下面的错误,

null
java.lang.AssertionError
at com.intellij.openapi.projectRoots.SdkType.findInstance(SdkType.java:207)
at org.jetbrains.android.sdk.AndroidSdkType.getInstance(AndroidSdkType.java:231)
at org.jetbrains.android.sdk.AndroidSdkUtils.getAllAndroidSdks(AndroidSdkUtils.java:462)
at org.jetbrains.android.sdk.AndroidSdkUtils.getAndroidSdkPathsFromExistingPlatforms(AndroidSdkUtils.java:443)
at org.jetbrains.android.sdk.AndroidSdkUtils.tryToChooseAndroidSdk(AndroidSdkUtils.java:853)
at com.android.tools.idea.npw.ConfigureAndroidProjectPath.putSdkDependentParams(ConfigureAndroidProjectPath.java:97)
at com.android.tools.idea.npw.ConfigureAndroidProjectPath.init(ConfigureAndroidProjectPath.java:59)
at com.android.tools.idea.wizard.dynamic.DynamicWizardPath.attachToWizard(DynamicWizardPath.java:98)
at com.android.tools.idea.wizard.dynamic.DynamicWizard.addPath(DynamicWizard.java:242)
at com.android.tools.idea.npw.NewProjectWizardDynamic.addPaths(NewProjectWizardDynamic.java:84)
at tru.NewModuleWizardDynamicExtension.init(NewModuleWizardDynamicExtension.java:27)
at NewProAction.actionPerformed(NewProAction.java:30)
at com.intellij.openapi.actionSystem.ex.ActionUtil.performActionDumbAware(ActionUtil.java:182)
at com.intellij.openapi.actionSystem.impl.ActionMenuItem$ActionTransmitter.run(ActionMenuItem.java:311)
at com.intellij.openapi.wm.impl.FocusManagerImpl.runOnOwnContext(FocusManagerImpl.java:958)
at com.intellij.openapi.wm.impl.IdeFocusManagerImpl.runOnOwnContext(IdeFocusManagerImpl.java:124)
at com.intellij.openapi.actionSystem.impl.ActionMenuItem$ActionTransmitter.actionPerformed(ActionMenuItem.java:281)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
at com.intellij.openapi.actionSystem.impl.ActionMenuItem.fireActionPerformed(ActionMenuItem.java:109)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.JToggleButton$ToggleButtonModel.setPressed(JToggleButton.java:308)
at javax.swing.AbstractButton.doClick(AbstractButton.java:376)
at com.apple.laf.ScreenMenuItemCheckbox.itemStateChanged(ScreenMenuItemCheckbox.java:193)
at java.awt.CheckboxMenuItem.processItemEvent(CheckboxMenuItem.java:389)
at java.awt.CheckboxMenuItem.processEvent(CheckboxMenuItem.java:357)
at java.awt.MenuComponent.dispatchEventImpl(MenuComponent.java:351)
at java.awt.MenuComponent.dispatchEvent(MenuComponent.java:339)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:761)
at java.awt.EventQueue.access0(EventQueue.java:97)
at java.awt.EventQueue.run(EventQueue.java:709)
at java.awt.EventQueue.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.awt.EventQueue.run(EventQueue.java:731)
at java.awt.EventQueue.run(EventQueue.java:729)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:866)
at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:654)
at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:381)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

发生这种情况是因为 findInstance 方法试图将 AndroidSdkType.Class 与 for 循环内的 sdkType class 之一进行比较,类 实际上是相同的,但由两个不同的加载器加载,一个来自(org.jetbrains.android) 和其他来自本地加载程序 (com.sample.sample)

如何解决这个问题?

由于这个 class 加载程序问题,我也经常遇到 classcastexception。因此,当我尝试使用不同的方式开发插件时,我对这个 class 加载程序问题感到震惊。

您需要将 Android 插件的 .jar 文件添加到您的 IntelliJ IDEA SDK 的类路径中,而不是将它们添加为库。

是的,正如 Yole 所说,我昨天刚做了这个并成功执行了插件。

本文档完美解答了我的问题。 Think 可能对其他人有用。

http://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_dependencies.html

为了其他人,我附上在 Plugin SDK 的类路径中添加 "android.jar" 的屏幕截图。

下面是我添加到 plugin.xml 文件的代码片段,其中 "org.jetbrains.android" 是 "android.jar" 插件的插件 ID。

org.jetbrains.android

并且在为 android studio 开发这个时,我无法在 Intellij IDE 中 运行 但能够在 android studio 中执行。

Intellij SDK classpath screenshot