Weblogic10.3.6集成Spring+CXF WS-Security遇类加载异常求助
看起来你遇到的是典型的应用服务器自带类与第三方依赖类加载冲突问题——Weblogic 10.3.6本身捆绑了旧版本的JAXB(2.1)和部分CXF相关组件,和你引入的Apache CXF新版本依赖产生了类加载优先级矛盾,进而引发LinkageError和UnmarshallerImpl相关异常。下面是具体的解决思路:
1. 强制Weblogic优先加载应用自身的依赖类
Weblogic允许通过weblogic.xml配置类加载策略,让应用优先使用自己lib目录下的第三方类,而非服务器自带的旧版本。你需要在WEB-INF目录下创建/修改这个文件,添加如下配置:
<weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.4/weblogic-web-app.xsd"> <container-descriptor> <prefer-application-packages> <!-- 优先加载应用中的Apache CXF全量包 --> <package-name>org.apache.cxf.*</package-name> <!-- 覆盖Weblogic自带的JAXB相关类 --> <package-name>javax.xml.bind.*</package-name> <package-name>com.sun.xml.bind.*</package-name> <!-- 如果还有XML Security相关冲突,也可以添加 --> <package-name>org.apache.xml.security.*</package-name> </prefer-application-packages> </container-descriptor> </weblogic-web-app>
这个配置会告诉Weblogic:加载这些包下的类时,优先从应用的WEB-INF/lib中查找,而非服务器的系统类库。
2. 清理Gradle依赖中的冲突传递包
你的CXF依赖可能会自动引入和Weblogic自带重复的JAR(比如jaxb-api、jaxb-impl),需要在build.gradle中排除这些传递依赖,避免部署包出现重复类:
dependencies { // CXF JAX-WS前端依赖 implementation('org.apache.cxf:cxf-rt-frontend-jaxws:3.5.4') { // 排除Weblogic已自带的JAXB相关依赖 exclude group: 'javax.xml.bind', module: 'jaxb-api' exclude group: 'com.sun.xml.bind', module: 'jaxb-impl' exclude group: 'com.sun.xml.bind', module: 'jaxb-core' } // CXF WS-Security核心依赖 implementation('org.apache.cxf:cxf-rt-ws-security:3.5.4') { // 按需排除冲突的传递依赖,比如xmlsec等 exclude group: 'org.apache.santuario', module: 'xmlsec' } // 其他Spring及应用业务依赖... }
注意:版本号请替换为你实际使用的CXF版本。
3. 验证UnmarshallerImpl的类加载来源
为了确认问题确实是类加载导致的,可以在代码中添加一段调试代码,打印UnmarshallerImpl的类加载器信息:
import javax.xml.bind.JAXBContext; import javax.xml.bind.Unmarshaller; // 在初始化JAXB的代码附近添加 JAXBContext context = JAXBContext.newInstance(YourTargetClass.class); Unmarshaller unmarshaller = context.createUnmarshaller(); System.out.println("UnmarshallerImpl 类加载器: " + unmarshaller.getClass().getClassLoader()); System.out.println("应用业务类加载器: " + YourTargetClass.class.getClassLoader());
如果两者的类加载器不一致,说明UnmarshallerImpl是被Weblogic的系统类加载器加载的,而你的业务类是应用类加载器加载的,这就会导致类型转换异常。此时需要调整weblogic.xml的配置,确保JAXB相关类由应用类加载器加载。
4. 考虑Weblogic原生WS-Security的替代方案
如果上述配置还是无法解决冲突,可以考虑改用Weblogic原生的WS-Security实现。Weblogic 10.3.6支持通过weblogic-webservices.xml配置WS-Security策略,这样可以避免和Apache CXF的WS-Security组件产生冲突,更贴合Weblogic的运行环境。
5. 检查部署包中的重复JAR
最后,解压你的WAR/EAR包,检查WEB-INF/lib目录下是否存在重复的JAR文件(比如同时有jaxb-impl-2.1.jar和jaxb-impl-2.3.jar),如果有,删除重复的旧版本JAR,只保留你需要的版本。
内容的提问来源于stack exchange,提问作者Pete Long

