Plugin/custom CE build classloader issues


i'm currently working on a IntelliJ IDEA plugin for RoboVM as well as a custom build of CE that integrates the plugin out of the box. Compiling and installing the plugin standalone works as intended. Integrating the plugin in a checkout of IntelliJ IDEA CE (master or latest release branch) produces different classloader issues.

The plugin depends on a fat jar containing among other things a specific version of ASM, commons-io and other utility libraries. I added the plugin module to the CE project, added it as a dependency to the community-main module used to launch the IDEA run config, and also added it to the layout.gant file for CLI builds.

When running the IDEA run config, i get classloader errors related to the libraries included in the far jar. E.g. different methods of IOUtils from commons-io can not be found, which means some part of IDEA or a plugin IDEA ships with is pulling in an older version somewhere.

As per the plugin developer docs i'd have expected that the plugin classloader would prioritize the libraries the plugin depends on above the libraries pulled in by IDEA or other plugins.

I'm a bit at a loss at how to resolve this issue and would be greatful for any input.


Comment actions Permalink

Right now, when you're running IntelliJ IDEA under a debugger, it doesn't do any classloader separation for the modules added as dependencies to community-main; they are all loaded with the main classloader, as if they were not plugins. If you run IntelliJ IDEA under a debugger and then install your plugin through Settings | Plugins, it will be loaded as a normal plugin in a separate classloader.

Comment actions Permalink

Great, thanks for the quick reply! I already thought I forgot how to Java :)

I assume the normal development cycle for CE builds is to write and test plugins as usual (plugin project), then do a full Gant build of CE for integration testing, correct?

And one more question if I may: I noticed that the Gant build will run IDEA with all plugins initialized. I haven't dug to deeply into that yet, but I guess that's part of testing. How can a plugin detect that it's called during a test run? We display a dialogue on startup giving some conditions which makes the Gant build fail during the testing phase.

Comment actions Permalink

You can check Application.isHeadlessEnvironment(). The plugin should not perform any user interaction when running in the headless environment (this is not just tests, but also building searchable options, command-line inspections etc.).


Please sign in to leave a comment.