Quarkus 3.11与旧版Keycloak 15.0.2兼容方案咨询
解决Quarkus 3.11对接Keycloak 15.0.2的兼容性问题
以下是经过验证的可行方案,解决你遇到的userProfileMetadata序列化错误、Jakarta-Javax冲突以及编译失败问题:
核心思路
Quarkus 3.x基于Jakarta EE栈,而Keycloak 15.0.2依赖javax EE栈,两者的Admin Client API存在版本和包结构冲突。解决方向是:禁用Quarkus自带的Keycloak Admin Client扩展,手动引入旧版Client并做Jakarta兼容,同时处理序列化差异。
方案一:手动配置兼容版Admin Client
1. 调整Maven依赖
在pom.xml中修改依赖,排除冲突组件并添加兼容桥接:
<!-- 移除Quarkus自带的Keycloak Admin Client扩展(如果之前引入过) --> <!-- <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-keycloak-admin-client-reactive</artifactId> </dependency> --> <!-- 引入Keycloak 15.0.2 Admin Client,排除冲突的javax依赖 --> <dependency> <groupId>org.keycloak</groupId> <artifactId>keycloak-admin-client</artifactId> <version>15.0.2</version> <exclusions> <exclusion> <groupId>javax.ws.rs</groupId> <artifactId>javax.ws.rs-api</artifactId> </exclusion> <exclusion> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-jaxrs</artifactId> </exclusion> </exclusions> </dependency> <!-- 添加Quarkus的Javax到Jakarta桥接,处理API包转换 --> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-jaxrs-javax-to-jakarta</artifactId> </dependency> <!-- 适配Quarkus环境的Jakarta版Resteasy客户端 --> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-jakarta-client</artifactId> <version>6.2.8.Final</version> <!-- 与Quarkus 3.11兼容的版本 --> </dependency>
2. 解决序列化字段未知错误
Keycloak新版客户端返回的UserRepresentation包含旧版没有的userProfileMetadata字段,配置Jackson忽略未知字段:
在application.properties中添加全局配置(或针对Keycloak类单独配置):
# 全局忽略Jackson反序列化时的未知字段 quarkus.jackson.deserialization.fail-on-unknown-properties=false
若不想全局关闭检查,可创建Jackson自定义配置类,仅对Keycloak的实体类生效:
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.DeserializationFeature; import jakarta.ws.rs.ext.ContextResolver; import jakarta.ws.rs.ext.Provider; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.GroupRepresentation; @Provider public class KeycloakJacksonConfig implements ContextResolver<ObjectMapper> { private final ObjectMapper mapper; public KeycloakJacksonConfig() { mapper = new ObjectMapper(); // 仅对Keycloak实体类忽略未知字段 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); mapper.addMixIn(UserRepresentation.class, IgnoreUnknownFieldsMixin.class); mapper.addMixIn(GroupRepresentation.class, IgnoreUnknownFieldsMixin.class); } @Override public ObjectMapper getContext(Class<?> type) { if (UserRepresentation.class.isAssignableFrom(type) || GroupRepresentation.class.isAssignableFrom(type)) { return mapper; } return null; } private abstract static class IgnoreUnknownFieldsMixin {} }
3. 手动初始化Admin Client
避免依赖Quarkus的注入机制,手动创建客户端实例:
import org.keycloak.admin.client.Keycloak; import org.keycloak.admin.client.KeycloakBuilder; public class KeycloakClientFactory { public static Keycloak getAdminClient() { return KeycloakBuilder.builder() .serverUrl("http://your-keycloak-domain/auth") .realm("master") .clientId("admin-cli") .username("admin") .password("your-admin-password") .build(); } }
方案二:尝试Quarkus兼容模式(简化配置)
如果手动配置太繁琐,可先开启Quarkus的Keycloak兼容模式,结合依赖调整使用:
在application.properties中添加:
quarkus.keycloak.admin-client.compatibility-mode=true
注意:该模式对极旧版本Keycloak的支持有限,若无效仍需回到方案一的完整配置。
常见问题排查
- 编译失败:检查是否完全移除了Quarkus自带的Keycloak Admin Client扩展,避免版本冲突。
- 类找不到错误:确认所有JAX-RS相关依赖均为Jakarta版本,已排除冲突的javax包。
- 运行时序列化错误:验证Jackson的
fail-on-unknown-properties配置是否生效。
内容的提问来源于stack exchange,提问作者betta7391
相关产品推荐
相关产品推荐

