WebSphere中部分Java @Schedule定时任务不触发问题求助
问题概述
我有6个结构完全一致的Java EJB调度器类,仅命名和业务逻辑不同,部署到WebSphere 9应用服务器后,只有3个能正常触发定时任务。具体表现:
- WebSphere控制台的
Enterprise Applications -> 应用 -> EJB JNDI names和Binding enterprise Bean with business interface to JNDI names中仅能看到这3个正常Bean - 应用安装时,相关JNDI配置步骤也只显示这3个Bean
- 部署生成的
ejb-jar_merged.xml仅包含这3个定时器类 - 手动创建
ejb-jar.xml显式声明所有EJB后,6个定时器均能正常工作,说明WebSphere的自动Bean扫描机制未识别到另外3个类。
相关代码示例
本地接口
import javax.ejb.Local; @Local public interface IScheduledProcessorBean { public void doProcessing(); }
定时器实现类(未正常工作的示例)
@Stateless @HousekeepingProcessor public class HousekeepingTimer implements IScheduledProcessorBean { public static final String className = "HousekeepingTimer"; @PersistenceContext(unitName = "WOTISEJB") private EntityManager em; /** * Default constructor. */ public HousekeepingTimer() { // Default Constructor } // Try not to clash with the other schedule timer flows. @Schedule(minute="20", hour="8-20", dayOfWeek="Mon-Fri", dayOfMonth="*", month="*", year="*", info="HousekeepingTimer", persistent=true) public void doProcessing() { Logger.getGlobal().fine(()->className + " called at: " + new java.util.Date()); try { // Specific logic goes here } catch (Exception e) { Logger.getGlobal().log(Level.SEVERE, "Scheduler failed for Housekeeping", e); } } }
自定义限定符注解
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import javax.inject.Qualifier; @Qualifier @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER}) public @interface HousekeepingProcessor { }
可能原因
- WebSphere EJB扫描的类路径/包过滤问题
WebSphere的自动EJB扫描可能对某些包路径存在隐性过滤:
- 未被扫描的3个类所在包未被标记为EJB组件包(比如缺少
beans.xml或包结构不符合默认扫描规则) - 构建工具打包时,未将这3个类正确纳入EJB模块的classpath,导致WebSphere无法发现它们
- 自定义限定符注解的识别偏差
虽然注解结构一致,但可能存在:
- 注解类的类加载异常,未被WebSphere的EJB容器正确加载
@Stateless与自定义限定符组合使用时,部分类未被容器判定为合法EJB
WebSphere部署缓存未更新
如果之前部署过仅包含3个EJB的版本,后续增量部署时容器缓存未刷新,导致新添加的类未被扫描到类字节码或命名异常
未被识别的类可能存在:
- 编译后的字节码损坏或存在隐性编译错误
- 类名/包名与WebSphere内部组件冲突,被容器忽略
解决思路
针对类路径/包扫描问题
- 检查所有定时器类的包结构,确保和正常工作的3个类在同级包下,或处于WebSphere默认扫描的EJB包范围内
- 解压部署包,验证未被识别的类是否存在于
WEB-INF/classes或对应JAR文件中,排查构建脚本的打包逻辑 - 在EJB模块的
META-INF目录下添加空的beans.xml,明确标记组件包:<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" bean-discovery-mode="all"> </beans>
针对自定义注解问题
- 检查所有自定义限定符注解的定义,确保包路径、元数据与
HousekeepingProcessor完全一致 - 暂时移除自定义注解后重新部署,验证未被识别的类是否能被容器发现,排除注解干扰
- 确保注解类本身被正确打包到应用中
针对缓存问题
- 在WebSphere控制台选择
Applications -> Application Types -> WebSphere enterprise applications -> 应用名称 -> Update,选择"Replace the entire application"并勾选"Delete existing cached files" - 重启WebSphere服务器,彻底清除容器级元数据缓存
针对类字节码或命名问题
- 重新编译未被识别的类,检查编译日志确认无错误,验证字节码文件完整性
- 修改未被识别类的类名或包名,避免与WebSphere内部组件重名后重新部署
长期稳定方案
- 保留
ejb-jar.xml显式声明所有EJB,避免依赖WebSphere自动扫描机制,确保部署一致性:<?xml version="1.0" encoding="UTF-8"?> <ejb-jar xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="3.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/ejb-jar_3_2.xsd"> <enterprise-beans> <session> <ejb-name>HousekeepingTimer</ejb-name> <ejb-class>com.yourpackage.HousekeepingTimer</ejb-class> <session-type>Stateless</session-type> <local>com.yourpackage.IScheduledProcessorBean</local> </session> <!-- 其他5个EJB的声明 --> </enterprise-beans> </ejb-jar>
内容的提问来源于stack exchange,提问作者simonalexander2005
相关产品推荐
相关产品推荐

