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
相关产品推荐
相关产品推荐

