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
相关产品推荐
相关产品推荐

