TomEE带ordering的web-fragment触发Jar排除SCI不加载问题咨询
问题根因
这个现象是TomEE(OpenEJB内核)的两套类路径扫描逻辑触发条件不同,叠加默认Jar排除规则的加载时机设计缺陷导致的:
扫描逻辑的分支触发规则
- 当类路径下不存在任何带
<ordering>节点的web-fragment.xml时,容器不会启动Servlet规范定义的Web片段排序流程,走简化的快速初始化扫描链路:这个阶段OpenEJB不会加载内置的Jar前缀排除列表,会全量扫描所有Jar内的ServletContainerInitializer服务声明、Web组件注解,因此命名为spring-前缀的Jar可以被正常识别,初始化器能正常执行。 - 当类路径下存在至少一个配置了
<ordering>(含<before><others/></before>或<after><others/></after>规则)的web-fragment.xml时,容器必须严格按照Servlet 3.0+规范执行Web片段优先级排序,此时会切换到严格扫描链路,自动加载OpenEJB内核内置的default.exclusions默认排除前缀列表,所有命中前缀(包括spring-、google-、snappy-java-、sshd-等)的Jar会被直接过滤,既不参与片段排序,也不会被扫描其中的ServletContainerInitializer配置、Web组件注解,最终表现为初始化器被完全忽略。
规则设计存在的问题
OpenEJB内置这个前缀排除列表的初衷,是提前过滤掉已知不会包含Java EE/Web组件的通用第三方依赖,减少排序阶段的扫描开销、避免不同Jar的片段配置产生排序冲突。但这个规则存在两个明显的设计问题:
- 规则仅靠Jar包名称前缀做粗粒度匹配,不会校验Jar内的实际内容,非常容易误伤命名恰好命中前缀的自研类库;
- 排除规则的加载逻辑仅绑定在Web片段排序流程上,导致规则生效与否完全取决于类路径下是否存在带排序配置的片段,行为表现不一致,排查成本极高。
低侵入规避方案
除了重命名Jar、修改全局Tomcat扫描配置两个高成本方案外,还有一个不需要上层应用改动任何配置的无侵入方案:在自研类库的META-INF目录下新增一个最简的web-fragment.xml,仅声明片段名称,不需要配置排序规则或其他组件,容器在排序预扫描阶段会直接将该Jar识别为合法的Web片段候选,跳过前缀排除校验,即可正常加载其中的ServletContainerInitializer。
最简配置示例:
<web-fragment xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd" version="3.0"> <name>your-custom-lib-name</name> </web-fragment>
内容的提问来源于stack exchange,提问作者Simon Hill
相关产品推荐
相关产品推荐

