carymrobbins/intellij-haskforce

LinkageError: “scala/collection/Seq” when using another IntelliJ plugin written in Scala

Opened this issue · 9 comments

TL;DR HaskForce bundles a scala-library jar which interferes with other IntelliJ plugins written in Scala.

Details:
We have an IntelliJ plugin that is written in mostly Scala, and one of our users complained that on occasion, an exception:

java.lang.LinkageError: loader constraint violation: loader (instance of com/intellij/ide/plugins/cl/PluginClassLoader) previously initiated loading for a different type with name "scala/collection/Seq"
    at ...

would appear. I couldn't initially reproduce it, until I asked the affected user to dump the contents of their plugins directory. I suspected a conflicting scala version was somehow interfering with the plugin. After running find . | grep scala-, here is what I saw:

./HaskForce/lib/scala-library-2.12.4.jar
./HaskForce/lib/scala-reflect-2.12.4.jar
./Scala/lib/scala-nailgun-runner.jar
./Scala/lib/scala-library.jar
./Scala/lib/scala-play-2-jps-plugin.jar
./Scala/lib/scala-reflect.jar
./Scala/lib/scala-xml.jar
./Scala/lib/scala-parser-combinators_2.12-1.0.6.jar

It seems HaskForce is bundling a specific scala-library 2.12.4. On a hunch, I asked the user to remove HaskForce, and after IntelliJ restart, the problem disappeared!

I believe the problem is caused by using compile instead of implementation in the gradle script, which causes the scala-library jar to be bundled.

If I recall correctly, IntelliJ's class loader should allow for this. Is your plugin open sourced? Would be interesting for me to look at to see how to resolve. I will double check as well to confirm that HaskForce's class loader is doing the right thing.

The strange thing is, Scala plugin also bundles its own scala-library.jar, it seems, but it's without any version information... I'm not sure how this works to be honest, whether the jar name/version has any part in it).

The plugin is not opensource, unfortunately, but let me try to get a small repro. If my suspicions are correct, this surely would affect other plugins written in Scala...

I have a coworker hitting the same problem (but different class) - I've asked them to disable a bunch of their plugins to see if we can narrow down to which one is a problem.

@puffnfresh Can you ask them to look for plugins that have scala-library.2.12.x.jar included? Maybe will be a hint :)

I think the problem is that I'm using the following in the plugin.xml -

<idea-plugin use-idea-classloader="true">

According to the docs

A separate class loader is used to load the classes of each plugin. This allows each plugin to use a different version of a library, even if the same library is used by the IDE itself or by another plugin.

So I need to remove that attribute from the plugin.xml and ensure classes are still resolved properly.

@hmemcpy - I would also make sure that the closed-source plugin being used is also not using this attribute as that may be part of the problem as well.

@hmemcpy - I've cut a pre-release which contains a fix for this - v0.3.43-SNAPSHOT-b5425ef8

Could you have the user install this version and see if it alleviates the issue?

Hey! Sorry for the lack of response. Thanks for the fix, let me try it (as well as the suggestion above) and I'll report back.

Updates! I first tried seeing if my plugin was using use-idea-classloader="true" - it wasn't, and when I tried adding it myself (with false), I got a strikethrough on it, with a hint that this option is deprecated!

I installed the pre-release version and can confirm the problem was resolved! Before installing it, my sandboxed instance with HaskForce and my plugin was throwing this exception, after loading the pre-release - the problem disappeared!

Thank you very much!

Fantastic! I'll work on cutting a full release for this, thanks for the report!