Spring Boot嵌入Keycloak报错:找不到ManagedCacheManagerProvider
问题背景
在Spring Boot应用中以嵌入式模式运行Keycloak时,触发以下运行时错误:
java.lang.RuntimeException: No org.keycloak.cluster.ManagedCacheManagerProvider found. If running in embedded mode set the [embedded] property to this provider.
已在META-INF/keycloak-server.json中配置对应属性:
"embedded": "org.keycloak.cluster.ManagedCacheManagerProvider",
运行环境:
- Java 21
- Spring Boot 3.2.4
- Keycloak 22.0.0
相关POM依赖
<dependencies> <!-- 其他依赖 --> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-jackson2-provider</artifactId> <version>6.2.4.Final</version> </dependency> <dependency> <groupId>org.keycloak</groupId> <artifactId>keycloak-dependencies-server-all</artifactId> <version>22.0.0</version> <type>pom</type> </dependency> <dependency> <groupId>org.keycloak</groupId> <artifactId>keycloak-crypto-default</artifactId> <version>22.0.0</version> </dependency> <dependency> <groupId>org.keycloak</groupId> <artifactId>keycloak-admin-ui</artifactId> <version>22.0.0</version> </dependency> <dependency> <groupId>org.keycloak</groupId> <artifactId>keycloak-services</artifactId> <version>22.0.0</version> </dependency> <dependency> <groupId>org.keycloak</groupId> <artifactId>keycloak-rest-admin-ui-ext</artifactId> <version>22.0.0</version> </dependency> </dependencies>
KeycloakApplication扩展类代码
public final class EmbeddedKeycloakApplication extends KeycloakApplication { @Setter private static KeycloakServerProperties keycloakServerProperties; @Override protected void loadConfig() { JsonConfigProviderFactory factory = new RegularJsonConfigProviderFactory(); Optional<Config.ConfigProvider> optional = factory.create(); Config.init(optional.orElseThrow(() -> new NoSuchElementException("No value present"))); } @Override protected ExportImportManager bootstrap() { final ExportImportManager exportImportManager = super.bootstrap(); createMasterRealmAdminUser(); createRealm(); return exportImportManager; } @KeycloakTransaction private void createMasterRealmAdminUser() { ApplianceBootstrap applianceBootstrap = new ApplianceBootstrap(KeycloakTransactionAspect.getSession()); AdminUser admin = keycloakServerProperties.getAdminUser(); applianceBootstrap.createMasterRealmUser(admin.username(), admin.password()); } @KeycloakTransaction @SneakyThrows private void createRealm() { RealmManager manager = new RealmManager(KeycloakTransactionAspect.getSession()); Resource lessonRealmImportFile = new ClassPathResource(keycloakServerProperties.getRealmImportFile()); manager.importRealm(JsonSerialization.readValue(lessonRealmImportFile.getInputStream(), RealmRepresentation.class)); } }
已确认loadConfig方法成功读取keycloak-server.json,optional存在有效值。
解决方案
1. 补充缺失的Infinispan模型依赖
org.keycloak.cluster.ManagedCacheManagerProvider类属于keycloak-model-infinispan模块,虽然引入了keycloak-dependencies-server-all pom依赖,但该模块未被自动引入,需手动添加:
<dependency> <groupId>org.keycloak</groupId> <artifactId>keycloak-model-infinispan</artifactId> <version>22.0.0</version> </dependency>
2. 校验配置文件结构
确保embedded属性位于keycloak-server.json的根节点下,而非嵌套在其他配置节点中,正确结构示例:
{ "realm": { "name": "master", "displayName": "Master" }, "embedded": "org.keycloak.cluster.ManagedCacheManagerProvider", // 其他配置项... }
3. 添加Infinispan缓存配置
嵌入式模式下Keycloak需要明确的缓存配置支持,在keycloak-server.json中添加:
"cache": { "default": { "backend": "local", "local": { "eviction": { "maxEntries": 10000, "strategy": "LRU" } } } }
4. 调整Spring Boot类加载顺序
Spring Boot的类加载机制可能干扰Keycloak内部类加载,在application.properties中添加:
spring.boot.classloading.exclude-filter=org.keycloak.**
或通过启动参数指定:
-Dspring.boot.classloading.exclude-filter=org.keycloak.**
5. 验证配置解析结果
在loadConfig方法中打印配置值,确认embedded属性被正确解析:
@Override protected void loadConfig() { JsonConfigProviderFactory factory = new RegularJsonConfigProviderFactory(); Optional<Config.ConfigProvider> optional = factory.create(); Config.ConfigProvider provider = optional.orElseThrow(() -> new NoSuchElementException("No value present")); System.out.println("Embedded provider config: " + provider.getConfig().get("embedded")); Config.init(provider); }
内容的提问来源于stack exchange,提问作者Mile Stanislavov

