Spring Security配置在WebSphere上触发cvc-complex-type.2.4.c错误求助
兄弟,我之前帮团队处理过几乎一模一样的WebSphere + Spring 5迁移问题,看你已经排查了一周,给你几个针对性的方向,应该能解决这个<http>元素找不到声明的问题:
1. 强制指定Spring Security XSD的版本
你现在的配置里用的是不带版本号的XSD地址,WebSphere很可能会偷偷加载服务器内置的旧版本XSD(比如Spring 3.x的),导致和你用的Spring 5.2.0不兼容。直接把schemaLocation改成带版本的:
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-5.2.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-5.2.xsd"
这样就能强制Spring使用对应版本的XSD,避免版本不匹配的问题。
2. 把WebSphere类加载器配置拉满(别只改个表面)
你说已经试过本地类优先,但WebSphere的类加载器坑很多,得把配置做细:
- 进WebSphere控制台找到你的应用,在类加载器设置里,把类加载顺序改成「父类最后加载(Parent Last)」,同时把WAR类加载器政策设为「每个WAR文件使用一个类加载器」。
- 另外,在WAR的
WEB-INF目录下新建ibm-web-ext.xml文件,内容如下:
<web-ext xmlns="http://websphere.ibm.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-web-ext_1_0.xsd" version="1.0"> <class-loader mode="PARENT_LAST"/> <war-class-loader-policy>SINGLE</war-class-loader-policy> </web-ext>
这个文件能强制应用完全使用自己的类加载器,彻底隔离WebSphere自带的旧Spring库。
3. 揪出Maven依赖里的隐藏冲突
你说移除spring-security-config.jar错误依旧,这说明肯定有其他依赖偷偷引入了旧版本的Spring Security类。赶紧跑mvn dependency:tree看依赖树,找有没有Spring 4.x版本的spring-security-core、spring-security-config,然后在pom.xml里把这些冲突的依赖排除掉,比如:
<dependency> <groupId>你的依赖groupId</groupId> <artifactId>你的依赖artifactId</artifactId> <version>你的版本</version> <exclusions> <exclusion> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> </exclusion> <exclusion> <groupId>org.springframework.security</groupId> <artifactId>spring-security-core</artifactId> </exclusion> </exclusions> </dependency>
另外一定要确保所有Spring相关依赖(spring-core、spring-context、spring-web等等)的版本都是5.2.0,别混着用。
4. 检查整个EAR和WebSphere全局的重复Jar
你只看了WAR的lib,但EAR里的其他模块、或者WebSphere的共享库里可能也有Spring Security的Jar,导致冲突:
- 解压你的EAR文件,检查所有模块的lib目录,把重复的Spring相关Jar删掉。
- 进WebSphere控制台看共享库配置,如果有全局的Spring库,要么删掉,要么把你的应用设置成不使用这个共享库。
5. 让XSD加载完全本地化
WebSphere解析XML时,如果本地找不到XSD,可能会尝试从外网下载,但服务器大概率没外网权限,导致XSD加载失败。你可以把Spring 5.2版本的spring-beans-5.2.xsd和spring-security-5.2.xsd放到WAR的WEB-INF/classes目录下,然后修改schemaLocation为本地路径:
xsi:schemaLocation="http://www.springframework.org/schema/beans classpath:spring-beans-5.2.xsd http://www.springframework.org/schema/security classpath:spring-security-5.2.xsd"
这样Spring就能直接从本地类路径加载XSD,不用依赖网络。
内容的提问来源于stack exchange,提问作者Nirro

