Configuring IntelliJ Platform plugin's workspace

Answered

Hello,
I've been setting up the workspace for IntelliJ's plugin development. There is one issue that I'm not able to solve.

I have two plugins: A and B. The B plugin depends on A. The A plugin is provided as an install-ready zip package (I don't have the code and I don't want to add it to my project).

In the manual, I met this page. I added jars from the A plugin (extracted from the zip file) to the SDK that is used when running B plugin. Unfortunately, when the sandbox is being bootstrapped, I get the following error:

Problems found loading plugins:
Plugin "B" was not loaded: required plugin "A" is disabled.

Disable B
Open plugin manager
I tried to install the A plugin in the sandbox but then I got a casting exception - two different class loaders were used.
 
On the console there is a line:
2017-10-24 14:43:03,121 [   3000]   INFO - llij.ide.plugins.PluginManager - Disabled plugins: B

Of course, I have appropriate dependency configuration in the B.plugin.xml file:

<depends>A</depends>

My question is how should I provide the A plugin to be able to develop the B plugin? Is it possible to develop the B plugin without A's sources?

In the jars that I added to the SDK's classpath, there is a package that contains the plugin.xml file for the A plugin. This plugin is also not listed on the list of plugins.

I'm sure that both plugins are properly configured because there are no problems when I install both of them in standalone IntelliJ's instance. Additionally, I don't have any compilation errors.

EDIT:

After debugging Intellij's code, I found the solution for the disabled plugin. In the plugin-sandbox/config folder, there is a disabled_plugins.txt file. There was an entry that caused that the A plugin was disabled on the startup.

Now I have a bit different problem.

Problems found loading plugins:
Plugin "B" was not loaded: required plugin "A" not installed.

Disable B
Open plugin manager

Does it mean that plugins from the SDK are not installed automatically?

EDIT2:
After couple more hours of debugging. The A plugin is marked as not installed because in the PluginManagerCore:loadDescriptorsFromClassPath method there are no appropriate jars URLs provided. It seems that BootstrapClassLoaderUtil doesn't include all of the entries configured in the SDK.

I tried to set -Didea.additional.classpath property, but then again I got the class cast exception.

 

9 comments
Comment actions Permalink

> I tried to install the A plugin in the sandbox but then I got a casting exception - two different class loaders were used.

What do you mean by "install the A plugin in the sandbox"? Do you mean that you started the plugin run configuration, and then installed 'the A plugin' in the IDE using 'Install Plugin from Disk' action?

0
Comment actions Permalink

> What do you mean by "install the A plugin in the sandbox"? Do you mean that you started the plugin run configuration, and then installed 'the A plugin' in the IDE using 'Install Plugin from Disk' action?

Yes, as far as I realized that the A plugin is not being installed automatically (from the classpath of an SDK) then I tried to provide it manually. Of course, after verifying that it doesn't work, I removed it.

0
Comment actions Permalink

> I tried to install the A plugin in the sandbox but then I got a casting exception - two different class loaders were used.

Could you please provide more details about exception which was thrown? 

0
Comment actions Permalink

With the A plugin installed manually in the sandbox (the B plugin is loaded from the workspace) I got something like this:

java.lang.ClassCastException: com.pluginb.ApiInterfaceImplementation cannot be cast to com.plugina.IApiInterface

The plugin B provides an implementation of the interface from plugin A.

Wider context from the code:

We have a list of registered services (classes that implement IApiInterface). These classes could be registered by different bundles (something like OSGi). The exception is thrown when we loop over the list and assign the current element to a local variable.
In this case, the B plugin registeres services and the A plugin processes them.

Is it possible that Gradle configuration somehow influences the loaded classes? I wonder because when I navigate through the code, from the B plugin I get the IApiInterface decompiled from the Gradle's cache. For the code from the A plugin, I get a class decompiled from the jar that is added to the SDK.

0
Comment actions Permalink

It looks like classes from A are somehow added to the classpath when you start the IDE (and actually these classes become part of the B plugin). How do you start the IDE? Do you use gradle-intellij-plugin?

0
Comment actions Permalink

> How do you start the IDE?

In my project, I have a plugin module. For the module, I have a plugin run configuration created.

> Do you use gradle-intellij-plugin?

No, I don't use this plugin. All of the required dependencies are provided by the regular Gradle configuration (build.gradle file).

0
Comment actions Permalink

Finally, I have found the solution.

The B plugin consists of other B submodules:
B.submodule-1
B.submodule-2
B.submodule-3

One of these submodules had dependencies to the A's submodule. Something like this:

B:
| B.plugin-submodule
| B.submodule-1
   | A.submodule1
   | A.submodule2
| B.submodule-2
| B.submodule-3

Based on the gradle setup, IntelliJ resolved all of the dependencies for all submodules. Initially, I removed Gradle dependencies and set the JDK only for the plugin submodule. It was required to do so for the others (submodule-1/2/3).

Nikolay thank you for your help :)

1
Comment actions Permalink

It's great that you have found the solution.

But I recommend you to try gradle-intellij-plugin to develop IntelliJ Platfrom plugins with Gradle. You can setup required plugins via `intellij.plugins` property and you won't need to manually edit dependencies after reimporting your Gradle projects.

1
Comment actions Permalink

I spent some time on configuring gradle-intellij-plugin. It makes the whole process way easier. After the very first contact with this plugin, I wasn't convinced that it might be useful in my case. I was wrong.

Thanks a lot!

0

Please sign in to leave a comment.