Loader Constraint Violation for class io.grpc.Channel when trying to create ManagedChannel for GRPC Request

139 views Asked by At

I'm trying to setup grpc client to make inference requests to Nvidia Triton inference server (version:23.06-py3) in Kotlin for my project.

I've setup protoc code generation using gradle (attached build.gradle.kts below), but when I try to create a ManagedChannel to pass to the InferenceService Coroutine, I get this Runtime Error

val channel = ManagedChannelBuilder.forTarget("127.0.0.1:8001")
            .usePlainText()
            .build()
val inferenceStub = GRPCInferenceServiceGrpcKt.GRPCInferenceServiceCoroutineStub(channel)
val modelLive = inferenceStub.modelReady(
    GrpcService.ModelReadyRequest.newBuilder()
         .setName("santacoder_huggingface")
         .build()
)
2023-11-17 15:11:36,839 [   9708]  ERROR - pplication.impl.LaterInvocator - loader constraint violation: loader com.intellij.util.lang.UrlClassLoader @174d20a wants to load abstract class io.grpc.Channel. A different abstract class with the same name was previously loaded by com.intellij.ide.plugins.cl.PluginClassLoader @6404ea6d. (io.grpc.Channel is in unnamed module of loader com.intellij.ide.plugins.cl.PluginClassLoader @6404ea6d, parent loader 'bootstrap') 
java.lang.LinkageError: loader constraint violation: loader com.intellij.util.lang.UrlClassLoader @174d20a wants to load abstract class io.grpc.Channel. A different abstract class with the same name was previously loaded by com.intellij.ide.plugins.cl.PluginClassLoader @6404ea6d. (io.grpc.Channel is in unnamed module of loader com.intellij.ide.plugins.cl.PluginClassLoader @6404ea6d, parent loader 'bootstrap')
    at java.base/java.lang.ClassLoader.defineClass1(Native Method)
    at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1017)
    at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:878)
    at com.intellij.util.lang.UrlClassLoader._defineClass(UrlClassLoader.java:400)
    at com.intellij.util.lang.UrlClassLoader.defineClass(UrlClassLoader.java:392)
    at com.intellij.util.lang.UrlClassLoader._findClass(UrlClassLoader.java:350)
    at com.intellij.util.lang.UrlClassLoader.findClass(UrlClassLoader.java:336)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:589)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
    at io.grpc.stub.AbstractStub.<init>(AbstractStub.java:73)
    at io.grpc.kotlin.AbstractCoroutineStub.<init>(AbstractCoroutineStub.kt:34)
    at inference.GRPCInferenceServiceGrpcKt$GRPCInferenceServiceCoroutineStub.<init>(GrpcServiceGrpcKt.kt:146)
    at inference.GRPCInferenceServiceGrpcKt$GRPCInferenceServiceCoroutineStub.<init>(GrpcServiceGrpcKt.kt:143)
    at com.artemus.completionProvider.ArtemusCompletionProvider.getInlineCompletion(ArtemusCompletionProvider.kt:16)
    at com.artemus.inlineCompletionApi.InlineCompletionsManager$createPreviewInline$1.invokeSuspend(InlineCompletionsManager.kt:27)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
    at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:284)
    at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85)
    at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
    at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
    at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
    at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
    at com.artemus.inlineCompletionApi.InlineCompletionsManager.createPreviewInline(InlineCompletionsManager.kt:27)
    at com.artemus.inlineCompletionApi.listeners.DocumentListener.documentChangedNonBulk$lambda$2(DocumentListener.kt:78)
    at com.intellij.openapi.application.TransactionGuardImpl.runWithWritingAllowed(TransactionGuardImpl.java:216)
    at com.intellij.openapi.application.TransactionGuardImpl.access$200(TransactionGuardImpl.java:24)
    at com.intellij.openapi.application.TransactionGuardImpl$2.run(TransactionGuardImpl.java:199)
    at com.intellij.openapi.application.impl.ApplicationImpl.runIntendedWriteActionOnCurrentThread(ApplicationImpl.java:822)
    at com.intellij.openapi.application.impl.ApplicationImpl.lambda$invokeLater$4(ApplicationImpl.java:324)
    at com.intellij.openapi.application.impl.FlushQueue.doRun(FlushQueue.java:85)
    at com.intellij.openapi.application.impl.FlushQueue.runNextEvent(FlushQueue.java:134)
    at com.intellij.openapi.application.impl.FlushQueue.flushNow(FlushQueue.java:47)
    at com.intellij.openapi.application.impl.FlushQueue$FlushNow.run(FlushQueue.java:190)
    at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:776)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:727)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:746)
    at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:976)
    at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:843)
    at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$8(IdeEventQueue.java:454)
    at com.intellij.openapi.progress.impl.CoreProgressManager.computePrioritized(CoreProgressManager.java:773)
    at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$9(IdeEventQueue.java:453)
    at com.intellij.openapi.application.impl.ApplicationImpl.runIntendedWriteActionOnCurrentThread(ApplicationImpl.java:822)
    at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:501)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
2023-11-17 15:11:36,841 [   9710]  ERROR - pplication.impl.LaterInvocator - IntelliJ IDEA 2020.3  Build #IC-203.5981.155 
2023-11-17 15:11:36,842 [   9711]  ERROR - pplication.impl.LaterInvocator - JDK: 11.0.9; VM: OpenJDK 64-Bit Server VM; Vendor: JetBrains s.r.o. 
2023-11-17 15:11:36,842 [   9711]  ERROR - pplication.impl.LaterInvocator - OS: Windows 10 
2023-11-17 15:11:36,842 [   9711]  ERROR - pplication.impl.LaterInvocator - Plugin to blame: Artemus version: 0.0.1 
2023-11-17 15:11:36,842 [   9711]  ERROR - pplication.impl.LaterInvocator - Last Action: EditorEnter 
fun properties(key: String) = providers.gradleProperty(key)
fun environment(key: String) = providers.environmentVariable(key)

plugins {
  id("java")
  alias(libs.plugins.kotlin) // Kotlin support
  alias(libs.plugins.gradleIntelliJPlugin) // Gradle IntelliJ Plugin
  alias(libs.plugins.changelog) // Gradle Changelog Plugin
  alias(libs.plugins.qodana) // Gradle Qodana Plugin
  id("com.google.protobuf") version "0.9.4"
}

group = properties("pluginGroup").get()
version = properties("pluginVersion").get()

repositories {
  mavenCentral()
}

kotlin {
  jvmToolchain(11)
}

intellij {
  pluginName = properties("pluginName")
  version = properties("platformVersion")
  type = properties("platformType")

  plugins = properties("platformPlugins").map { it.split(',').map(String::trim).filter(String::isNotEmpty) }
}

dependencies {
  implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.3")
  implementation("org.jetbrains.kotlinx:kotlinx-coroutines-swing:1.6.3")

  implementation("io.grpc:grpc-netty-shaded:1.59.0")
  implementation("io.grpc:grpc-protobuf:1.59.0")
  implementation("io.grpc:grpc-stub:1.59.0")

  implementation("com.google.protobuf:protobuf-java:3.25.1")
  implementation("com.google.protobuf:protobuf-java-util:3.25.1")
  implementation("com.google.protobuf:protobuf-kotlin:3.25.1")
  implementation("io.grpc:protoc-gen-grpc-kotlin:1.4.0")

}

protobuf {
  protoc {
    artifact = "com.google.protobuf:protoc:3.25.1"
  }

  plugins {
    create("grpc") {
      artifact = "io.grpc:protoc-gen-grpc-java:1.59.0"
    }
    create("grpckt") {
      artifact = "io.grpc:protoc-gen-grpc-kotlin:1.4.0:jdk8@jar"
    }
  }
  generateProtoTasks {
    all().forEach {
      it.plugins {
        create("grpc")
        create("grpckt")
      }
      it.builtins {
        create("kotlin")
      }
    }
  }
}

tasks {
  wrapper {
    gradleVersion = properties("gradleVersion").get()
  }

  patchPluginXml {
    version = properties("pluginVersion")
    sinceBuild = properties("pluginSinceBuild")
    untilBuild = properties("pluginUntilBuild")
  }

  signPlugin {
    certificateChain = environment("CERTIFICATE_CHAIN")
    privateKey = environment("PRIVATE_KEY")
    password = environment("PRIVATE_KEY_PASSWORD")
  }

  publishPlugin {
    token = environment("PUBLISH_TOKEN")
    channels = properties("pluginVersion").map { listOf(it.split('-').getOrElse(1) { "default" }.split('.').first()) }
  }
}

I thought this might be caused by grpc-netty-shaded dependency I have in the gradle file but I'm not sure since I'm very new to this. I tried removing grpc-netty-shaded in favour of grpc-netty, and also tried to remove the dependency entiry, but both of them lead to this error

2023-11-17 15:25:48,470 [   7696]  ERROR - pplication.impl.LaterInvocator - io.grpc.ManagedChannelProvider: io.grpc.netty.shaded.io.grpc.netty.NettyChannelProvider not a subtype 
java.util.ServiceConfigurationError: io.grpc.ManagedChannelProvider: io.grpc.netty.shaded.io.grpc.netty.NettyChannelProvider not a subtype
    at java.base/java.util.ServiceLoader.fail(ServiceLoader.java:588)
    at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNextService(ServiceLoader.java:1236)
    at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNext(ServiceLoader.java:1264)
    at java.base/java.util.ServiceLoader$2.hasNext(ServiceLoader.java:1299)
    at java.base/java.util.ServiceLoader$3.hasNext(ServiceLoader.java:1384)
    at io.grpc.ServiceProviders.loadAll(ServiceProviders.java:67)
    at io.grpc.ManagedChannelRegistry.getDefaultRegistry(ManagedChannelRegistry.java:101)
    at io.grpc.ManagedChannelProvider.provider(ManagedChannelProvider.java:43)
    at io.grpc.ManagedChannelBuilder.forTarget(ManagedChannelBuilder.java:86)
    at com.artemus.completionProvider.ArtemusCompletionProvider.getInlineCompletion(ArtemusCompletionProvider.kt:13)
    at com.artemus.inlineCompletionApi.InlineCompletionsManager$createPreviewInline$1.invokeSuspend(InlineCompletionsManager.kt:27)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
    at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:284)
    at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85)
    at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
    at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
    at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
    at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
    at com.artemus.inlineCompletionApi.InlineCompletionsManager.createPreviewInline(InlineCompletionsManager.kt:27)
    at com.artemus.inlineCompletionApi.listeners.DocumentListener.documentChangedNonBulk$lambda$2(DocumentListener.kt:78)
    at com.intellij.openapi.application.TransactionGuardImpl.runWithWritingAllowed(TransactionGuardImpl.java:216)
    at com.intellij.openapi.application.TransactionGuardImpl.access$200(TransactionGuardImpl.java:24)
    at com.intellij.openapi.application.TransactionGuardImpl$2.run(TransactionGuardImpl.java:199)
    at com.intellij.openapi.application.impl.ApplicationImpl.runIntendedWriteActionOnCurrentThread(ApplicationImpl.java:822)
    at com.intellij.openapi.application.impl.ApplicationImpl.lambda$invokeLater$4(ApplicationImpl.java:324)
    at com.intellij.openapi.application.impl.FlushQueue.doRun(FlushQueue.java:85)
    at com.intellij.openapi.application.impl.FlushQueue.runNextEvent(FlushQueue.java:134)
    at com.intellij.openapi.application.impl.FlushQueue.flushNow(FlushQueue.java:47)
    at com.intellij.openapi.application.impl.FlushQueue$FlushNow.run(FlushQueue.java:190)
    at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:776)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:727)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:746)
    at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:976)
    at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:843)
    at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$8(IdeEventQueue.java:454)
    at com.intellij.openapi.progress.impl.CoreProgressManager.computePrioritized(CoreProgressManager.java:773)
    at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$9(IdeEventQueue.java:453)
    at com.intellij.openapi.application.impl.ApplicationImpl.runIntendedWriteActionOnCurrentThread(ApplicationImpl.java:822)
    at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:501)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
2023-11-17 15:25:48,472 [   7698]  ERROR - pplication.impl.LaterInvocator - IntelliJ IDEA 2020.3  Build #IC-203.5981.155 
2023-11-17 15:25:48,473 [   7699]  ERROR - pplication.impl.LaterInvocator - JDK: 11.0.9; VM: OpenJDK 64-Bit Server VM; Vendor: JetBrains s.r.o. 
2023-11-17 15:25:48,473 [   7699]  ERROR - pplication.impl.LaterInvocator - OS: Windows 10 
2023-11-17 15:25:48,473 [   7699]  ERROR - pplication.impl.LaterInvocator - Plugin to blame: Artemus version: 0.0.1 
2023-11-17 15:25:48,473 [   7699]  ERROR - pplication.impl.LaterInvocator - Last Action: EditorEnter 

I'd really appreciate any help on this.

1

There are 1 answers

2
Ayush Vachaspati On BEST ANSWER

I've posted a summary of the entire solution on JetBrains forums. https://intellij-support.jetbrains.com/hc/en-us/community/posts/15146127658002/comments/15268997066258

Git Issue : https://github.com/grpc/grpc-java/issues/10692 (this is where the discussion is that helped me solve this)

It seems like this issue is caused because IntelliJ is exposing its own version of grpc to the plugins. Which implies removing the dependency on grpc, or adding it to compileOnly dependency. But this does not work and leads to this error.

2023-11-17 15:25:48,470 [   7696]  ERROR - pplication.impl.LaterInvocator - io.grpc.ManagedChannelProvider: io.grpc.netty.shaded.io.grpc.netty.NettyChannelProvider not a subtype 

So the solution is to shadow all the dependencies we require for gprc (including netty), so that there are no conflicts between IntelliJ and our dependencies. This can be done by using the gradle-shadow plugin https://imperceptiblethoughts.com/shadow/configuration/relocation/

The kotlin gradle configs to shadow dependencies properly is

import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar

plugins {
  id("com.github.johnrengelman.shadow") version "8.1.1"
}

group = properties("pluginGroup").get()
version = properties("pluginVersion").get()

val grpcVersion = "1.59.0"
val protobufVersion = "3.25.1"
val kotlinGrpcVersion = "1.4.0"

dependencies {
  implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.3")
  implementation("org.jetbrains.kotlinx:kotlinx-coroutines-swing:1.6.3")

  implementation("io.grpc:grpc-netty-shaded:$grpcVersion")
  implementation("io.grpc:grpc-protobuf:$grpcVersion")
  implementation("io.grpc:grpc-stub:$grpcVersion")
  implementation("io.grpc:grpc-kotlin-stub:$kotlinGrpcVersion")

  implementation("com.google.protobuf:protobuf-java:$protobufVersion")
  implementation("com.google.protobuf:protobuf-java-util:$protobufVersion")
  implementation("com.google.protobuf:protobuf-kotlin:$protobufVersion")
  implementation("io.grpc:protoc-gen-grpc-kotlin:$kotlinGrpcVersion")
}

// Shadow all dependencies. Use relocate to shadow specific ones.
tasks {
  shadowJar{
    archiveBaseName = "shadow"  //can be replaced by pluginName
    version = "0.0.1"   // can be replaced by pluginVersion
    isEnableRelocation = true
    relocationPrefix = "shadow"
    mergeServiceFiles()
  }
}

tasks{
  buildPlugin{
    dependsOn(shadowJar)
  }
}

mergeServiceFiles() https://imperceptiblethoughts.com/shadow/configuration/merging/#merging-service-descriptor-files is required in the shadow task config to avoid

shadow.io.grpc.ManagedChannelProvider$ProviderNotFoundException: No functional channel service provider found. Try adding a dependency on the grpc-okhttp, grpc-netty, or grpc-netty-shaded artifact
    at shadow.io.grpc.ManagedChannelProvider.provider(ManagedChannelProvider.java:45)
    at shadow.io.grpc.ManagedChannelBuilder.forTarget(ManagedChannelBuilder.java:86)
       . . .

The shadow jar is created in in build/libs folder as “shadow-0.0.1-all.jar” in this case.

To set the Jar for runIde, you can set prepareSandbox.pluginJar property as shown below.

tasks {
  shadowJar{
    archiveBaseName = properties("pluginName").get()
    version = properties("pluginVersion").get()
    isEnableRelocation = true
    relocationPrefix = "shadow"
    mergeServiceFiles()
  }
}

tasks{
  buildPlugin{
    dependsOn(shadowJar)
  }
}

tasks{
  prepareSandbox{
    pluginJar = shadowJar.get().archiveFile
    dependsOn(shadowJar)
  }
}

This should allow you to use grpc within IntelliJ plugin.