升级pom.xml中Apache POI版本致GlassFish部署EJB引用错误
升级Apache POI至5.4.1后GlassFish部署MDB报错的排查与解决
问题概述
仅将项目中poi和poi-ooxml依赖版本从5.2.2升级至5.4.1后,在Docker部署的GlassFish环境中执行mvn clean install并部署应用时,出现如下错误:
remote failure: Error occurred during deployment: Exception while deploying the app [myApp] : Referencing error: This bundle has no bean of name [TransactionLogMdb]
涉及的MDB注解配置:
@MessageDriven(name = "TransactionLogMdb", activationConfig = { // acknowledgeMode may not be required as auto-acknowledge is the default setting for this config @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"), // Required config, found this value in glassfish-ejb-jar.xml @ActivationConfigProperty(propertyName = "destination", propertyValue = "TransactionLogQueue"), @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue") })
glassfish-ejb-jar.xml中的对应配置:
<ejb> <ejb-name>TransactionLogMdb</ejb-name> <jndi-name>some/pathTo/TransactionLogQueue</jndi-name> <mdb-connection-factory> <jndi-name>some/pathTo/TransactionLogConnectionFactory</jndi-name> </mdb-connection-factory> </ejb>
回滚至POI 5.2.2版本后部署恢复正常,需定位依赖升级影响EJB引用的原因并解决,且必须使用5.4.1版本。
可能原因
POI 5.2.2到5.4.1的版本迭代中,依赖链发生了变化:
- 引入了与GlassFish自带Java EE/Jakarta EE类库冲突的依赖(如ASM版本、JMS相关类),干扰了EJB容器对MDB bean的扫描与注册。
- 传递依赖引入的JAR包改变了应用类加载优先级,导致GlassFish无法正确识别MDB的注解配置。
解决方案
1. 排查并排除依赖冲突
执行Maven依赖树命令,查看POI 5.4.1引入的传递依赖:
mvn dependency:tree -Dincludes=org.apache.poi
重点检查是否存在ASM、javax.jms等与GlassFish容器冲突的依赖。若发现冲突,在pom.xml中排除相关依赖,示例如下:
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>5.4.1</version> <exclusions> <exclusion> <groupId>org.ow2.asm</groupId> <artifactId>asm</artifactId> </exclusion> <exclusion> <groupId>org.ow2.asm</groupId> <artifactId>asm-commons</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.4.1</version> <exclusions> <exclusion> <groupId>org.ow2.asm</groupId> <artifactId>asm</artifactId> </exclusion> <exclusion> <groupId>org.ow2.asm</groupId> <artifactId>asm-commons</artifactId> </exclusion> </exclusions> </dependency>
2. 配置类加载器优先级
在GlassFish的部署描述符中设置类加载器委托模式,让容器优先加载自身的Java EE类库:
- 若为Web应用,在
glassfish-web.xml中添加:
<glassfish-web-app> <class-loader delegate="true"/> </glassfish-web-app>
- 若为纯EJB模块,在
glassfish-ejb-jar.xml中添加:
<glassfish-ejb-jar> <class-loader delegate="true"/> </glassfish-ejb-jar>
3. 验证MDB类的完整性
确保MDB类满足以下要求:
- 为public非抽象类
- 实现
javax.jms.MessageListener接口并覆写onMessage方法 - 注解配置完整无遗漏(如示例中的
@MessageDriven及activationConfig)
4. 清理GlassFish容器缓存
Docker环境下,旧的类缓存可能导致部署异常,执行以下操作清理缓存:
- 进入GlassFish容器:
docker exec -it <glassfish-container-id> bash
- 删除缓存目录:
rm -rf /opt/glassfish/domains/domain1/generated /opt/glassfish/domains/domain1/cache
- 重启GlassFish域:
/opt/glassfish/bin/asadmin restart-domain
验证步骤
重新执行mvn clean install构建应用,部署至GlassFish后检查是否仍存在找不到TransactionLogMdb bean的错误。
内容的提问来源于stack exchange,提问作者josh-waa
相关产品推荐
相关产品推荐

