JBoss AS 7.1 REST端点调用Keycloak Admin Client失败求助
我之前也踩过JBoss AS7.1和Keycloak Admin Client兼容的坑,结合你描述的现象——JUnit测试用jackson2正常、换jackson就出问题,部署到JBoss里直接失败,核心原因就是JBoss自带的Jackson 1.x和Keycloak Admin Client依赖的Jackson 2.x在类加载和JAX-RS提供者层面冲突了。下面给你几个针对性的解决思路:
1. 精准排除冲突依赖+配置JBoss部署结构
JBoss AS7.1默认绑定的是Jackson 1.x(也就是jackson-core-asl、jackson-mapper-asl这类包),而Keycloak Admin Client依赖的是Jackson 2.x(jackson-core、jackson-databind),两者的JAX-RS提供者会抢占上下文。你需要:
第一步:在pom.xml里排除Keycloak Admin Client自带的Jackson依赖
避免打包时把重复的Jackson包带进应用:
<dependency> <groupId>org.keycloak</groupId> <artifactId>keycloak-admin-client</artifactId> <version>你的Keycloak版本</version> <exclusions> <exclusion> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> </exclusion> <exclusion> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </exclusion> <exclusion> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> </exclusion> </exclusions> </dependency>
然后手动添加Jackson 2.x的依赖(如果需要打包到应用里):
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.10</version> <!-- 选和Keycloak兼容的版本 --> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.10</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.9.10</version> </dependency>
第二步:配置jboss-deployment-structure.xml排除JBoss自带的Jackson模块
在你的WEB-INF目录下创建这个文件,强制JBoss不加载自带的Jackson 1.x:
<jboss-deployment-structure> <deployment> <exclusions> <!-- 排除所有Jackson 1.x相关模块 --> <module name="org.codehaus.jackson.jackson-core-asl" /> <module name="org.codehaus.jackson.jackson-mapper-asl" /> <module name="org.codehaus.jackson.jackson-jaxrs" /> <module name="org.codehaus.jackson.jackson-xc" /> </exclusions> <!-- 如果你的JBoss已经部署了Jackson 2.x模块,可以直接依赖;否则跳过这部分,让应用自带的Jackson生效 --> <dependencies> <module name="com.fasterxml.jackson.core.jackson-core" slot="main" /> <module name="com.fasterxml.jackson.core.jackson-databind" slot="main" /> <module name="com.fasterxml.jackson.core.jackson-annotations" slot="main" /> </dependencies> </deployment> </jboss-deployment-structure>
2. 匹配Keycloak Admin Client和JBoss的兼容版本
JBoss AS7.1是比较老的容器,太新的Keycloak版本(比如10+)对Jackson和JAX-RS的依赖会更激进,容易出问题。建议降级到Keycloak 4.x或者3.x版本,比如3.4.3.Final,这些版本的Admin Client对老容器的兼容性更好。
3. 明确指定JAX-RS使用Jackson 2.x提供者
在你的REST应用的Application类里,手动注册Jackson 2.x的提供者,确保JAX-RS上下文优先使用它:
import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider; import javax.ws.rs.core.Application; import java.util.HashSet; import java.util.Set; public class YourRestApplication extends Application { @Override public Set<Class<?>> getClasses() { Set<Class<?>> classes = new HashSet<>(); // 注册你的REST端点类 classes.add(YourRestEndpoint.class); // 强制注册Jackson 2.x的JSON提供者 classes.add(JacksonJaxbJsonProvider.class); return classes; } }
4. 调试类加载问题(如果以上方法都不行)
可以开启JBoss的类加载调试日志,看看到底是哪个版本的Jackson类被加载了。在standalone.xml的日志配置里添加:
<logger category="org.jboss.modules"> <level name="DEBUG"/> </logger>
启动JBoss后,查看日志里的类加载记录,确认Jackson 2.x的类是否被优先加载,而不是JBoss自带的1.x。如果发现还是加载了1.x的类,说明你的排除配置没生效,需要检查jboss-deployment-structure.xml的路径和内容是否正确。
内容的提问来源于stack exchange,提问作者troger19

