You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

WebLogic类加载器与Maven依赖冲突:Spring Boot WAR部署求助

嘿,我太懂第一次跟WebLogic打交道的痛苦了——这货的类加载逻辑跟WildFly、Tomcat完全不是一个路子,父优先的策略简直是Spring Boot应用的“隐形坑”!你说的依赖明明在WAR里却提示缺失,90%就是WebLogic抢着加载自己带的旧版本类,把你的应用依赖给覆盖了。既然你已经尝试了weblogic.xml,大概率是配置没踩对要点,我给你梳理几个关键步骤:

1. 精准配置weblogic.xml的类加载优先级

WebLogic默认是父类加载器优先,也就是先加载它自身lib目录下的类,再加载你WAR包里的。要反转这个逻辑,必须在weblogic.xml里明确指定哪些包要优先用应用里的版本。

给你一个能解决大部分问题的示例配置,记得把你提示缺失的依赖包名补充进去:

<?xml version="1.0" encoding="UTF-8"?>
<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.7/weblogic-web-app.xsd">
    <!-- 核心配置:让WebLogic优先加载应用内的包 -->
    <container-descriptor>
        <prefer-application-packages>
            <!-- Spring全家桶必须优先加载,避免WebLogic自带的旧Spring类冲突 -->
            <package-name>org.springframework.*</package-name>
            <!-- 如果用了Jackson JSON,也要加,WebLogic自带的Jackson版本通常很老 -->
            <package-name>com.fasterxml.jackson.*</package-name>
            <!-- 这里填你提示缺失的依赖包,比如commons系列、validation等 -->
            <package-name>org.apache.commons.*</package-name>
            <package-name>javax.validation.*</package-name>
            <!-- 别忘了你的业务代码包,防止被WebLogic的类加载器误加载 -->
            <package-name>com.yourcompany.*</package-name>
        </prefer-application-packages>
        <!-- 可选:优先加载应用内的资源文件,比如SPI配置 -->
        <prefer-application-resources>
            <resource-name>META-INF/services/*</resource-name>
        </prefer-application-resources>
    </container-descriptor>
    <!-- 指定应用上下文根,避免和WebLogic默认应用冲突 -->
    <context-root>/your-app-context</context-root>
</weblogic-web-app>

重点提示:一定要把所有报错里提到的缺失类对应的包名都加到<prefer-application-packages>,比如报错找不到org.apache.commons.lang3.StringUtils,就加<package-name>org.apache.commons.*</package-name>

2. 检查Spring Boot WAR打包的正确性

确保你的WAR包是按照WebLogic要求打包的:

  • 启动类必须继承SpringBootServletInitializer并重写configure方法:
    @SpringBootApplication
    public class YourAppApplication extends SpringBootServletInitializer {
        @Override
        protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
            return application.sources(YourAppApplication.class);
        }
    
        public static void main(String[] args) {
            SpringApplication.run(YourAppApplication.class, args);
        }
    }
    
  • Maven/Gradle里要排除Tomcat依赖(WebLogic自带Servlet容器,避免冲突):
    Maven示例:
    <packaging>war</packaging>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- 编译时依赖Servlet API,打包时不包含 -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    

3. 验证类加载是否生效

可以在应用里加一个简单的接口,打印类加载器信息,确认你的依赖是由应用类加载器加载的:

@RestController
@RequestMapping("/debug")
public class ClassLoaderDebugController {
    @GetMapping("/classloader")
    public String checkClassLoader() {
        // 随便选一个你报错的类,比如Spring的ApplicationContext
        Class<?> targetClass = org.springframework.context.ApplicationContext.class;
        ClassLoader classLoader = targetClass.getClassLoader();
        StringBuilder sb = new StringBuilder();
        sb.append("类加载器层级(从当前类往上):<br>");
        while (classLoader != null) {
            sb.append("- ").append(classLoader.getClass().getName()).append("<br>");
            classLoader = classLoader.getParent();
        }
        return sb.toString();
    }
}

部署后访问这个接口,如果看到类似weblogic.servlet.internal.WebAppClassLoader的类加载器排在前面,说明配置生效了;如果全是WebLogic核心类加载器(比如weblogic.utils.classloaders.ChangeAwareClassLoader),说明你的prefer-application-packages没覆盖到这个类的包。

4. 其他容易踩的坑

  • 版本兼容性:WebLogic 12c只支持Spring Boot 2.x(基于Java EE),如果你用了Spring Boot 3.x(基于Jakarta EE),必须用WebLogic 14c及以上版本,否则会出现大量jakarta.*依赖缺失的错误。
  • 清理WebLogic缓存:WebLogic的缓存有时候会“记仇”,部署新包后旧的类还在生效。可以删除domain/servers/[你的服务器名]/tmpcache目录,然后重启服务器。
  • WAR包结构检查:解压WAR包,确认WEB-INF/lib下确实有你需要的依赖jar包,有时候Maven的<scope>设置错误(比如设成了provided)会导致依赖没打包进去。

内容的提问来源于stack exchange,提问作者Martin Mucha

火山引擎 最新活动