18 January 2012

Tags:

CodeNarc for IntelliJ IDEA 0.16.1

Eventually, I managed to upgrade the CodeNarc for IntelliJ IDEA plugin to use CodeNarc 0.16.1. It took a while (sorry Hamlet ;)), but I faced an awful jar hell issue.

java.lang.LinkageError

It’s quite interesting indeed, though I am not fully happy with the ``fix''. Let’s see what’s the problem. If any IntelliJ expert is here, I’d be happy to have some help. Basically, for compatibility with newer versions of Groovy, both CodeNarc and GMetrics (a dependency of CodeNarc) embed in their jar three classes which have disappeared from the newest Groovy version (in fact, they were moved in other packages):

  • org.codehaus.groovy.ast.expr.RegexExpression

  • org.codehaus.groovy.transform.powerassert.Value

  • org.codehaus.groovy.transform.powerassert.ValueRecorder

Normally, this shouldn’t be a problem, but when I ran the plugin, it failed loading with this cryptic error, well known from OSGI users:

java.lang.LinkageError: loader constraint violation: loader (instance of com/intellij/ide/plugins/cl/PluginClassLoader) previously initiated loading for a different type with name "org/codehaus/groovy/ast/expr/RegexExpression"
 at java.lang.ClassLoader.defineClass1(Native Method)
 at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
 at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
 at java.lang.ClassLoader.defineClass(ClassLoader.java:465)
 at com.intellij.util.lang.UrlClassLoader._defineClass(UrlClassLoader.java:124)
 at com.intellij.util.lang.UrlClassLoader.defineClass(UrlClassLoader.java:120)
 at com.intellij.util.lang.UrlClassLoader._findClass(UrlClassLoader.java:96)
 at com.intellij.ide.plugins.cl.PluginClassLoader.d(PluginClassLoader.java:102)
 at com.intellij.ide.plugins.cl.PluginClassLoader.loadClass(PluginClassLoader.java:63)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:247)

Oh my, a LinkageError. Worse than a classical classpath issue. The problem comes from the fact that IntelliJ internally uses Groovy (where ?) and bundles groovy-all-1.7.3.jar. I had to remove the compatibility classes from the CodeNarc jars in order to have the plugin loaded correctly. I think a better solution would be to be able to use an embedded version of Groovy, but the plugin loaded would always include those classes. By the way, it looks to me that CodeNarc would use the internal Groovy version to run (1.7.3) whereas it would probably be better if we could use the version used by the project…

Anyway, the plugin is upgraded, have fun!