尝试为 GRPC 请求创建 ManagedChannel 时,类 io.grpc.Channel 的加载程序约束冲突

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

提问人:Ayush Vachaspati 提问时间:11/17/2023 最后编辑:Eric AndersonAyush Vachaspati 更新时间:11/23/2023 访问量:58

问:

我正在尝试设置 grpc 客户端以在我的项目中向 Kotlin 中的 Nvidia Triton 推理服务器(版本:23.06-py3)发出推理请求。

我已经使用 gradle 设置了 protoc 代码生成(下面附上了 build.gradle.kts),但是当我尝试创建一个 ManagedChannel 以传递给 InferenceService 协程时,我收到此运行时错误

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()) }
  }
}

我认为这可能是由我在 gradle 文件中的 grpc-netty-shaded 依赖项引起的,但我不确定,因为我对此非常陌生。我尝试删除 grpc-netty-shaded 以支持 grpc-netty,并尝试删除依赖项整体,但它们都会导致此错误

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 

我真的很感激这方面的任何帮助。

intellij-plugin gradle-kotlin-dsl tritonserver grpc-kotlin

评论

0赞 Eric Anderson 11/22/2023
交联:github.com/grpc/grpc-java/issues/10692

答:

-1赞 Ayush Vachaspati 11/23/2023 #1

我已经在 JetBrains 论坛上发布了整个解决方案的摘要。https://intellij-support.jetbrains.com/hc/en-us/community/posts/15146127658002/comments/15268997066258

Git 问题:https://github.com/grpc/grpc-java/issues/10692(这是帮助我解决这个问题的讨论所在)

似乎这个问题是因为 IntelliJ 向插件公开了自己的 grpc 版本。这意味着删除对 grpc 的依赖,或将其添加到 compileOnly 依赖项中。但这不起作用并导致此错误。

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 

因此,解决方案是隐藏我们对 gprc 所需的所有依赖项(包括 netty),以便 IntelliJ 和我们的依赖项之间没有冲突。这可以通过使用 gradle-shadow 插件 https://imperceptiblethoughts.com/shadow/configuration/relocation/

正确隐藏依赖项的 kotlin gradle 配置是

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 在影子任务配置中是必需的,以避免

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)
       . . .

在本例中,shadow jar 在 build/libs 文件夹中创建为“shadow-0.0.1-all.jar”。

要为 runIde 设置 Jar,您可以设置 prepareSandbox.pluginJar 属性,如下所示。

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)
  }
}

这应该允许您在 IntelliJ 插件中使用 grpc。

评论

0赞 Jesse 11/23/2023
欢迎提供指向解决方案的链接,但请确保您的答案在没有它的情况下是有用的:在链接周围添加上下文,以便您的其他用户对它是什么以及它为什么存在有所了解,然后引用您要链接到的页面中最相关的部分,以防目标页面不可用。只不过是链接的答案可能会被删除。
0赞 Ayush Vachaspati 11/23/2023
感谢您的反馈。更新了答案以反映您的评论。希望现在好多了。