You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Keycloak 21.1.2集成VertX集群(Hazelcast)遇NoSuchMethodError求助

Keycloak自定义Provider与VertX Hazelcast集群协同异常问题

在旧版Keycloak中,自定义Provider可正常与基于Hazelcast的VertX集群协同工作,但切换到Quarkus架构的Keycloak 21.1.2后出现兼容性问题,目前面临两种异常场景:

  • 场景A:通过shadowJar加载VertX依赖时,Quarkus抛出重复接口错误,暂未找到解决办法,若存在构建时重命名包的方案请告知。
  • 场景B:通过Arc.container()注入Keycloak内置的VertX实例,虽能正常加入Hazelcast集群,但调用EventBus的publish()等方法时抛出如下异常:
Caused by: java.lang.NoSuchMethodError: 'java.util.concurrent.ExecutorService io.vertx.core.impl.VertxInternal.getWorkerPool()'

完整异常栈:

last handler in the pipeline did not handle the exception.: io.netty.channel.ChannelPipelineException: io.vertx.core.net.impl.VertxHandler.handlerAdded() has thrown an exception; removed.
2023-07-20T19:54:04.958126142Z  at io.netty.channel.DefaultChannelPipeline.callHandlerAdded0(DefaultChannelPipeline.java:624)
2023-07-20T19:54:04.958134097Z  at io.netty.channel.DefaultChannelPipeline.addLast(DefaultChannelPipeline.java:223)
2023-07-20T19:54:04.958138785Z  at io.netty.channel.DefaultChannelPipeline.addLast(DefaultChannelPipeline.java:195)
2023-07-20T19:54:04.958142132Z  at io.vertx.core.net.impl.NetClientImpl.connected(NetClientImpl.java:313)
2023-07-20T19:54:04.958145217Z  at io.vertx.core.net.impl.NetClientImpl.lambda$connectInternal2$2(NetClientImpl.java:271)
2023-07-20T19:54:04.958148243Z  at io.vertx.core.impl.ContextInternal.dispatch(ContextInternal.java:264)
2023-07-20T19:54:04.958151119Z  at io.vertx.core.net.impl.ChannelProvider.connected(ChannelProvider.java:175)
2023-07-20T19:54:04.958154044Z  at io.vertx.core.net.impl.ChannelProvider.lambda$handleConnect$0(ChannelProvider.java:158)
2023-07-20T19:54:04.958156949Z  at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:590)
2023-07-20T19:54:04.958159885Z  at io.netty.util.concurrent.DefaultPromise.notifyListeners0(DefaultPromise.java:583)
2023-07-20T19:54:04.958162790Z  at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:559)
2023-07-20T19:54:04.958165836Z  at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:492)
2023-07-20T19:54:04.958168772Z  at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:636)
2023-07-20T19:54:04.958171657Z  at io.netty.util.concurrent.DefaultPromise.setSuccess0(DefaultPromise.java:625)
2023-07-20T19:54:04.958174653Z  at io.netty.util.concurrent.DefaultPromise.trySuccess(DefaultPromise.java:105)
2023-07-20T19:54:04.958177588Z  at io.netty.channel.DefaultChannelPromise.trySuccess(DefaultChannelPromise.java:84)
2023-07-20T19:54:04.958180604Z  at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.fulfillConnectPromise(AbstractNioChannel.java:300)
2023-07-20T19:54:04.958183619Z  at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:335)
2023-07-20T19:54:04.958199038Z  at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:776)
2023-07-20T19:54:04.958204529Z  at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)
2023-07-20T19:54:04.958210690Z  at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650)
2023-07-20T19:54:04.958216261Z  at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)
2023-07-20T19:54:04.958222412Z  at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
2023-07-20T19:54:04.958228433Z  at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
2023-07-20T19:54:04.958234575Z  at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
2023-07-20T19:54:04.958240216Z  at java.base/java.lang.Thread.run(Thread.java:833)
2023-07-20T19:54:04.958244904Z Caused by: java.lang.NoSuchMethodError: 'java.util.concurrent.ExecutorService io.vertx.core.impl.VertxInternal.getWorkerPool()'
2023-07-20T19:54:04.958250525Z  at io.vertx.spi.cluster.hazelcast.impl.SubsOpSerializer.execute(SubsOpSerializer.java:60)
2023-07-20T19:54:04.958255665Z  at io.vertx.spi.cluster.hazelcast.HazelcastClusterManager.addRegistration(HazelcastClusterManager.java:361)
2023-07-20T19:54:04.958261455Z  at io.vertx.core.eventbus.impl.clustered.ClusteredEventBus.onLocalRegistration(ClusteredEventBus.java:143)
2023-07-20T19:54:04.958266745Z  at io.vertx.core.eventbus.impl.EventBusImpl.addRegistration(EventBusImpl.java:262)
2023-07-20T19:54:04.958272015Z  at io.vertx.core.eventbus.impl.HandlerRegistration.register(HandlerRegistration.java:63)
2023-07-20T19:54:04.958277906Z  at io.vertx.core.eventbus.impl.MessageConsumerImpl.handler(MessageConsumerImpl.java:226)
2023-07-20T19:54:04.958284469Z  at io.vertx.core.net.impl.NetSocketImpl.registerEventBusHandler(NetSocketImpl.java:108)
2023-07-20T19:54:04.958290039Z  at io.vertx.core.net.impl.NetClientImpl.lambda$connected$8(NetClientImpl.java:309)
2023-07-20T19:54:04.958295529Z  at io.vertx.core.net.impl.VertxHandler.setConnection(VertxHandler.java:82)
2023-07-20T19:54:04.958301080Z  at io.vertx.core.net.impl.VertxHandler.handlerAdded(VertxHandler.java:88)
2023-07-20T19:54:04.958306209Z  at io.netty.channel.AbstractChannelHandlerContext.callHandlerAdded(AbstractChannelHandlerContext.java:1114)
2023-07-20T19:54:04.958316639Z  at io.netty.channel.DefaultChannelPipeline.callHandlerAdded0(DefaultChannelPipeline.java:609)
2023-07-20T19:54:04.958323031Z  ... 25 more
2023-07-20T19:54:04.958329142Z 

相关配置文件及代码

Dockerfile

FROM quay.io/keycloak/keycloak:21.1.2 as builder

# Enable health and metrics support
ENV KC_HEALTH_ENABLED=false

# Configure a database vendor
ENV KC_DB=postgres
ENV JDBC_PARAMS="connectTimeout=30000"

WORKDIR /opt/keycloak
COPY --chown=keycloak:keycloak ./extensions/package.module-all.jar /opt/keycloak/providers/package.module-all.jar
RUN /opt/keycloak/bin/kc.sh build

FROM quay.io/keycloak/keycloak:21.1.2
COPY --from=builder /opt/keycloak/ /opt/keycloak/
ENTRYPOINT ["/opt/keycloak/bin/kc.sh"]

build.gradle

plugins {
    id 'java'
    id 'org.jetbrains.kotlin.jvm' version '1.9.0'
    id 'com.github.johnrengelman.shadow' version '8.1.1'
    id 'io.quarkus'
}

version ''

repositories {
    mavenCentral()
    jcenter()
}

test {
    useJUnitPlatform()
}

shadowJar {
    zip64 = true
    destinationDirectory.set(file("$rootDir/../keycloak/extensions"))
}

compileKotlin {
    kotlinOptions {
        sourceCompatibility = JavaVersion.VERSION_11
        targetCompatibility = JavaVersion.VERSION_11
    }
}

compileTestKotlin {
    kotlinOptions {
        jvmTarget = "11"
    }
}

dependencies {
    compileOnly group: 'com.google.auto.service', name: 'auto-service', version: '1.0-rc7'
    compileOnly group: 'org.keycloak', name: 'keycloak-server-spi', version: keycloakVersion
    compileOnly group: 'org.keycloak', name: 'keycloak-core', version: keycloakVersion
    compileOnly group: 'org.keycloak', name: 'keycloak-services', version: keycloakVersion
    compileOnly group: 'org.keycloak', name: 'keycloak-server-spi-private', version: keycloakVersion
    compileOnly group: 'org.keycloak', name: 'keycloak-model-jpa', version: keycloakVersion
    compileOnly group: 'io.vertx', name: 'vertx-core', version: vertxVersion
    compileOnly group: 'io.vertx', name: 'vertx-auth-common', version: vertxVersion
    compileOnly group: 'io.vertx', name: 'vertx-bridge-common', version: vertxVersion
    compileOnly group: 'io.vertx', name: 'vertx-codegen', version: vertxVersion
    compileOnly group: 'io.vertx', name: 'vertx-web', version: vertxVersion
    compileOnly group: 'io.vertx', name: 'vertx-web-common', version: vertxVersion
    compileOnly group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib-jdk8', version: '1.7.10'
    compileOnly group: 'org.jetbrains.kotlinx', name: 'kotlinx-coroutines-core', version: '1.6.4'

    compileOnly enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")
    compileOnly group: 'io.quarkus', name: 'quarkus-vertx'
    compileOnly group: 'io.quarkus', name: 'quarkus-arc'

    implementation group: 'io.vertx', name: 'vertx-hazelcast', version: vertxVersion, {
        exclude(group: 'io.vertx')
    }
    implementation group: 'io.vertx', name: 'vertx-lang-kotlin', version: vertxVersion, {
        exclude(group: 'io.vertx')
    }
    implementation group: 'io.vertx', name: 'vertx-lang-kotlin-coroutines', version: vertxVersion, {
        exclude(group: 'io.vertx')
    }
    implementation group: 'io.vertx', name: 'vertx-config', version: vertxVersion, {
        exclude(group: 'io.vertx')
    }
}

EventBusProviderImpl实现代码

@AutoService(EventBusProvider::class)
class EventBusProviderImpl : EventBusProvider {
    override fun get(): EventBus {
        if (instance != null) {
            return instance as EventBus
        }

        setupEventBus()
        return instance!!
    }

    companion object {
        private var instance: EventBus? = null

        private fun setupEventBus() {
            runBlocking {
                val container = Arc.container()
                val vertxInjectable = container.select(Vertx::class.java)
                val vertx = vertxInjectable.get()
                vertx.eventBus().publish("test", "{\"test\":\"boo\"}")
                instance = vertx.eventBus()
            }
        }
    }

}

因对Quarkus开发模式不熟悉,与之前JBoss开发方式差异较大,恳请提供解决思路或技术指导。

内容的提问来源于stack exchange,提问作者N.Schipper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 17:29:52