基于TomEE嵌入式与MicroProfile容错的集成测试问题排查
排查Arquillian+嵌入式TomEE下SafeGuard注解失效的问题
这种嵌入式容器和常规服务器的行为差异确实挺让人挠头的,我之前也踩过类似的坑,来帮你一步步拆解可能的问题点:
1. 先把依赖配置捋清楚
首先得确认你的测试依赖是不是配齐了,版本也没冲突:
- 确保
org.apache.safeguard:safeguard-api和safeguard-impl都在测试依赖里,别漏了实现包——嵌入式容器不会像常规服务器那样自动加载lib目录下的包 - 检查Arquillian嵌入式TomEE的依赖(比如
org.apache.tomee:arquillian-tomee-embedded),版本要和你平时跑的TomEE完全一致,版本不兼容是重灾区 - 用
mvn dependency:tree查一下依赖树,看看有没有其他MicroProfile容错相关的库(比如microprofile-fault-tolerance-api)和SafeGuard抢地盘,嵌入式容器可能自带了API但没绑定SafeGuard的实现
2. 给Arquillian部署加必要的配置
嵌入式TomEE默认可能不会激活SafeGuard,得手动帮它一把:
- 检查你的
beans.xml,把bean发现模式设为all(嵌入式容器有时候默认是annotated,可能漏扫拦截器):<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.1" bean-discovery-mode="all"> </beans> - 或者在部署归档里加个
META-INF/microprofile-config.properties,强制开启SafeGuard:mp.fault.tolerance.safeguard.enabled=true - 还可以在
arquillian.xml里给嵌入式容器加系统属性,确保CDI扩展和MicroProfile容错都开着:<container qualifier="tomee-embedded"> <configuration> <property name="systemProperties"> openejb.cdi.plus=true mp.fault.tolerance.enabled=true </property> </configuration> </container>
3. 注意嵌入式容器的特性限制
嵌入式TomEE为了启动快,默认会关一些非核心特性,得手动打开:
openejb.cdi.plus=true这个属性一定要加,它会开启CDI的扩展支持,SafeGuard的拦截器就是靠CDI扩展工作的- 有些版本的嵌入式TomEE默认不处理
@Asynchronous注解,得确认CDI的异步拦截器有没有被注册——可以通过日志排查(后面会说)
4. 测试类本身的坑要避开
有时候不是容器的问题,是测试代码写得不对:
- 测试类一定要用
@RunWith(Arquillian.class),而且被测试的Bean要通过CDI注入获取,绝对不能直接new——直接new的话,CDI拦截器(包括SafeGuard的)根本不会生效 - 测试
@Asynchronous的时候,别忘了异步方法返回的是CompletableFuture或者类似的异步结果,测试方法要等结果返回再断言,不然测试会提前结束,看起来像是注解没生效 - 确保被测试的Bean在Arquillian的部署归档里,比如用
@Deployment方法打包的时候把Bean类加进去
5. 日志是最好的调试工具
如果上面的步骤都没解决,那就开日志找线索:
- 在
arquillian.xml里给嵌入式容器加日志配置:<property name="systemProperties"> org.apache.safeguard.level=DEBUG org.apache.openejb.cdi.level=DEBUG org.apache.tomee.microprofile.level=DEBUG </property> - 跑测试的时候看日志,重点找这几个信息:
- SafeGuard的
FaultToleranceInterceptor有没有被加载 - 你的Bean上的
@Timeout、@Asynchronous注解有没有被扫描到 - 有没有类加载失败、拦截器注册失败的报错
- SafeGuard的
6. 对比常规TomEE的配置找差异
把你常规运行的TomEE配置和嵌入式的对比一下:
- 看看常规TomEE的
conf/system.properties或者conf/openejb.xml里有没有CDI、MicroProfile相关的特殊配置,把这些配置复制到嵌入式容器的arquillian.xml里 - 确认常规TomEE的
lib目录里的SafeGuard相关jar包,和你测试依赖里的版本一致,嵌入式容器会不会缺了某个jar
最后给你个小技巧:试试把应用打包成完整的war包,然后用Arquillian部署这个war包,而不是动态生成归档。有时候嵌入式容器对动态生成的类支持不够好,用war包能更贴近常规服务器的运行环境。
内容的提问来源于stack exchange,提问作者Znas Me
相关产品推荐
相关产品推荐

