Jakarta Faces 4/TomEE10嵌套复合组件同名属性引发StackoverflowError
TomEE 10(Jakarta Faces 4.0)嵌套复合组件同名属性导致StackOverflowError问题解决
问题场景
从TomEE 9迁移至TomEE 10时,嵌套复合组件的内外层使用了同名属性responsiveScrollHeight,该场景在TomEE 9中可正常运行,但在TomEE 10解析EL表达式时触发StackOverflowError,核心错误栈如下:
java.lang.StackOverflowError at com.sun.faces.component.CompositeComponentStackManager.findCompositeComponentUsingLocation at com.sun.faces.facelets.el.ContextualCompositeValueExpression.pushCompositeComponent
外层组件简化代码:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:composite="jakarta.faces.composite" xmlns:lop="jakarta.faces.composite/lop"> <composite:interface> <composite:attribute name="responsiveScrollHeight" type="java.lang.Boolean" /> </composite:interface> <composite:implementation> <f:subview id="outer"> ... <lop:myComponent responsiveScrollHeight="#{cc.attrs.responsiveScrollHeight}"/> .. </f:subview> </composite:implementation>
内层组件myComponent代码:
<composite:interface> <composite:attribute name="responsiveScrollHeight" type="java.lang.Boolean" /> </composite:interface> <composite:implementation> <f:subview id="inner"> <p:dataTable .. scrollHeight="#{cc.attrs.responsiveScrollHeight}" /> </f:subview> </composite:implementation>
核心原因
TomEE 10搭载的Jakarta Faces 4.0(基于Mojarra)调整了复合组件EL表达式的解析逻辑,当嵌套组件存在同名属性时,EL解析器在查找cc(当前复合组件)上下文时陷入无限递归,最终导致栈溢出。而TomEE 9使用的Jakarta Faces 3.0无此解析逻辑问题。
解决方案
1. 明确指定父组件属性上下文
修改外层组件中对内层组件的属性传递代码,通过cc.parent明确引用外层复合组件的属性,避免EL解析时混淆内外层cc上下文:
<lop:myComponent responsiveScrollHeight="#{cc.parent.attrs.responsiveScrollHeight}"/>
内层组件的#{cc.attrs.responsiveScrollHeight}保持不变,解析时会准确指向自身属性,外层传递的是明确的父组件属性值,彻底打破递归循环。
2. 升级TomEE至最新补丁版本
该问题可能是Jakarta Faces 4.0的已知bug,尝试升级TomEE 10到最新维护版本(如10.1.x及以上),官方可能已修复复合组件属性上下文的递归解析问题。
3. 批量替换属性引用(可选)
如果上述方案无法生效,可通过IDE全局替换等工具,批量将外层组件中传递同名属性的表达式替换为带父上下文的版本,无需修改属性名称,减少逐个组件调整的工作量。
内容的提问来源于stack exchange,提问作者cyanotyp
相关产品推荐
相关产品推荐

