I’m experience an odd behavior when repackaging co...
# compiler
r
I’m experience an odd behavior when repackaging compiler plugins with the gradle shadow plugin. If I depend in the shadowed version of the compiler plugin once the compiler loads my plugin I always get:
Copy code
e: java.lang.IllegalStateException: The provided plugin arrow.meta.MetaPlugin is not compatible with this version of compiler
My current config for the shadow plugin looks like:
Copy code
shadowJar {
    configurations = [project.configurations.compile]
    relocate 'org.jetbrains.kotlin.com.intellij', 'com.intellij'
    dependencies {
        exclude(dependency {
            it.moduleGroup.startsWith('org.jetbrains') || it.moduleGroup.startsWith('org.intellij')
        })
    }
    //relocate 'org.jetbrains.kotlin.load', 'kotlin.reflect.jvm.internal.impl.load'
}
Same behavior regardless if I include the embedded Kotlin deps or not. Whenever I shadow a compiler plugin I get that error. does anyone know if there is a special setting or something I am missing?. The only difference between the jars I’ve noticed is that due to the package relocation the shadowed version may have different size .class files. Any help is much appreciated. Thanks.
h
Yes, i had this issue when toying with compiler plugins as well, but sadly i cannot help you because i didn't solve it :(
r
Apparently an AbstractMethodError is thrown and caught at ComponentRegistar.registerProjectComponents
As if it's loosing the Kotlin metadata
We had a similar issue trying to shadow the arrow code base where it would all works but we could no longer import extensions with the shadowed produced dependency
I looked at the Kotlin compiler sources which also shadows and I can't figure out what is doing different
h
Very strange question but when did you get the error exactly? Loading your ide plugin? Executing a test from command line with your plugin included? Because i rememer that there were some strange effects with idea, i am not too sure but i got problems only after updating my ide/plugin or sth. There's also some info here, did you read that https://github.com/Kotlin/kotlinx.serialization/issues/87 ?
r
I get the exception running the CLI compiler in Gradle if I use as a plugin compiler-plugin-all.jar instead of compiler-plugin.jar
If I don't use the shadow version works
But I need to shadow it to embed some other dependencies.
I wanna avoid having to resort to pluginClasspath because I'm gonna have to declare the deps in the compiler plugin and also inject them to the compiler args in two places
k
You get that exception if the compiler uses the unshadowed version and your plugin the shadowed version or vice versa. I experienced these problems when running the compiler plugin in a Intellij plugin. The way I got it to work is the following: My compiler plugin is written based on the
org.jetbrains.kotlin:kotlin-compiler
dependency using the
com.intellij
namespace. I then repacked it for the gradle cli compiler by chaning the namespace to
org.jetbrains.kotlin.com.intellij
. The IDE plugin can directly use the compiler plugin as it makes use of the
com.intellij
namespace.
r
I get this if only in the shadow version
In the CLI but it works fine in the IDE
k
Well, try putting something like this in your `ComponentRegistrar`:
Copy code
class WarnowComponentRegistrar : ComponentRegistrar {

    init {
        runSafe {
            val type = ComponentRegistrar::class.java
            LOG.debug { "expected (${type.protectionDomain.codeSource.location})" }
            type.declaredMethods.filter { it.name == "registerProjectComponents" }.forEach { LOG.debug { "  $it" } }
        }

        runSafe {
            val actual = WarnowComponentRegistrar::class.java
            LOG.debug { "actual (${actual.protectionDomain.codeSource.location})" }
            actual.declaredMethods.filter { it.name == "registerProjectComponents" }.forEach { LOG.debug { "  $it" } }
        }
    }

    private inline fun <T> runSafe(block: () -> T): T? {
        return try {
            block()
        } catch (t: Throwable) {
            LOG.error(t) { "failed to read signature" }
            null
        }
    }

    override fun registerProjectComponents(
        project: MockProject,
        configuration: CompilerConfiguration
    ) { ... }
}
It will print out what compiler is executing your plugin and what namespace it expects
That way you can find what is making the difference between your working version and the other
r
Thanks so much, will try that
f
If you remove the relocation of
org.jetbrains.kotlin.com.intellij
from your shadowJar, it will probably work again for the CLI. However, it won’t work in the IDE anymore.
Thus, you’ll need different versions for the CLI and IDE versions of Kotlin.
r
Thanks Fabian, makes sense, I may end pulling in kastree with sources and not shadowing because in meta de Compiler plugin has a lot of what it does in the IDE.