You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WebSphere Liberty 25.0.0.3/JDK17下Struts-Spring应用启动报错求助

解决方案

核心原因

WebSphere Liberty 25.0.0.3的应用初始化逻辑相较于24.0.0.12发生了变化,首次部署时Struts的StrutsConversionPropertiesProcessor会在Spring应用上下文(ApplicationContext)完成初始化前执行,导致调用containsBean时this.appContext为null;重启容器时Spring上下文已被缓存,因此能正常运行。你之前添加的ContextLoaderPlugIn属于Spring旧版Struts集成方案,不适用于Struts 6.x版本,因此无法解决问题。


具体修复步骤

1. 替换为Struts官方推荐的Spring集成方式

org.springframework.web.struts.ContextLoaderPlugIn是Spring 3.x就标记过时的组件,Struts 6.x需使用官方的struts2-spring-plugin实现集成:

  • 确保项目依赖中包含对应版本的struts2-spring-plugin(版本需与Struts 6.3.0.2匹配),移除spring-web-struts依赖。
  • 删除struts.xml中旧的ContextLoaderPlugIn配置,添加以下常量配置:
    <struts>
        <!-- 启用Spring作为Struts的对象工厂 -->
        <constant name="struts.objectFactory" value="spring" />
        <!-- 指定Spring上下文配置文件路径 -->
        <constant name="struts.spring.context" value="/WEB-INF/applicationContext.xml" />
    </struts>
    

2. 强制Spring上下文优先初始化

在web.xml中配置ContextLoaderListener,确保Spring上下文在Struts初始化前完成加载:

<web-app>
    <!-- Spring上下文加载监听器 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!-- 指定Spring配置文件路径 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
    
    <!-- Struts核心过滤器 -->
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

3. 调整WebSphere Liberty的启动与类加载策略

  • 在Liberty的server.xml中为应用设置启动优先级,确保当前应用优先初始化:
    <application id="your-app-name" name="your-app-name" location="your-app.war" startOrder="1"/>
    
  • 若存在类加载冲突问题,设置类加载器为parentLast,优先加载应用自身的依赖类:
    <application ...>
        <classloader delegation="parentLast"/>
    </application>
    

4. 延迟Struts转换处理器的初始化(备选方案)

若上述方案仍未解决,可自定义转换处理器,确保仅在Spring上下文可用时执行逻辑:

public class DelayedStrutsConversionPropertiesProcessor extends StrutsConversionPropertiesProcessor {
    @Override
    public void register(ConversionProperties conversionProperties) {
        // 等待Spring上下文初始化完成
        WebApplicationContext appContext = WebApplicationContextUtils.getRequiredWebApplicationContext(
                ServletActionContext.getServletContext()
        );
        // 手动注入appContext
        Field appContextField;
        try {
            appContextField = StrutsConversionPropertiesProcessor.class.getDeclaredField("appContext");
            appContextField.setAccessible(true);
            appContextField.set(this, appContext);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new RuntimeException("Failed to inject Spring ApplicationContext", e);
        }
        // 执行原逻辑
        super.register(conversionProperties);
    }
}

然后在struts.xml中配置使用自定义处理器:

<constant name="struts.conversion.processor" value="com.yourpackage.DelayedStrutsConversionPropertiesProcessor" />

验证方法

修改完成后重新构建镜像并部署到OpenShift的Liberty 25.0.0.3环境,首次启动后检查日志是否再出现appContext为null的报错,若无需重启即可正常运行则修复成功。

内容的提问来源于stack exchange,提问作者bikramjit naha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 18:12:43