JSF复合组件递归中的StackOverflowError

时间:2018-05-04 08:49:45

标签: jsf recursion primefaces jsf-2.2 composite-component

根据https://stackoverflow.com/a/8446728/1797006递归使用JSF复合组件nested:cif并使用c:if终止递归应该有效:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:cc="http://xmlns.jcp.org/jsf/composite"
      xmlns:nested="http://xmlns.jcp.org/jsf/composite/nested"
      xmlns:c="http://xmlns.jcp.org/jsp/jstl/core">
    <cc:interface>
        <cc:attribute name="theAttr"
                type="richtercloud.jsf.avoid.nested.rendered.evaluation.Entity0"
                required="true"/>
    </cc:interface>
    <cc:implementation>
        <h:outputLabel value="Hello World!"/>
        <c:if test="#{cc.attrs.theAttr.reference ne null}">
            <nested:cif theAttr="#{cc.attrs.theAttr.reference}"/>
        </c:if>
        <c:if test="#{cc.attrs.theAttr.reference eq null}">
            <h:outputLabel value="recursion terminated"/>
        </c:if>
    </cc:implementation>
</html>

如下调用:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:nested="http://xmlns.jcp.org/jsf/composite/nested">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <nested:cif theAttr="#{backingBean0.reference}"/>
    </h:body>
</html>

支持bean:

@Named
@ViewScoped
public class BackingBean0 implements Serializable {
    private Entity0 reference = new Entity0(new Entity0(null));

    public Entity0 getReference() {
        return reference;
    }

    public void setReference(Entity0 reference) {
        this.reference = reference;
    }
}

但是,我得到了

java.lang.StackOverflowError
    at java.util.HashMap.hash(HashMap.java:339)
    at java.util.HashMap.get(HashMap.java:557)
    at javax.faces.component.ComponentStateHelper.get(ComponentStateHelper.java:174)
    at javax.faces.component.UIComponentBase$AttributesMap.get(UIComponentBase.java:2386)
    at com.sun.faces.el.CompositeComponentAttributesELResolver$ExpressionEvalMap.get(CompositeComponentAttributesELResolver.java:393)
    at javax.el.MapELResolver.getValue(MapELResolver.java:199)
    at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
    at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
    at com.sun.el.parser.AstValue.getValue(AstValue.java:140)
    at com.sun.el.parser.AstValue.getValue(AstValue.java:204)
    at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:226)
    at org.jboss.weld.el.WeldValueExpression.getValue(WeldValueExpression.java:50)
    at com.sun.faces.facelets.el.ContextualCompositeValueExpression.getValue(ContextualCompositeValueExpression.java:158)
    at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
    at javax.faces.component.UIComponentBase$AttributesMap.get(UIComponentBase.java:2427)
    at com.sun.faces.el.CompositeComponentAttributesELResolver$ExpressionEvalMap.get(CompositeComponentAttributesELResolver.java:393)
    at javax.el.MapELResolver.getValue(MapELResolver.java:199)
    at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
    at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
    at com.sun.el.parser.AstValue.getValue(AstValue.java:140)
    at com.sun.el.parser.AstValue.getValue(AstValue.java:204)
    at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:226)
    at org.jboss.weld.el.WeldValueExpression.getValue(WeldValueExpression.java:50)
    at com.sun.faces.facelets.el.ContextualCompositeValueExpression.getValue(ContextualCompositeValueExpression.java:158)
    at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
    at javax.faces.component.UIComponentBase$AttributesMap.get(UIComponentBase.java:2427)
    at com.sun.faces.el.CompositeComponentAttributesELResolver$ExpressionEvalMap.get(CompositeComponentAttributesELResolver.java:393)
    at javax.el.MapELResolver.getValue(MapELResolver.java:199)
    at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
    at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
    at com.sun.el.parser.AstValue.getValue(AstValue.java:140)
    at com.sun.el.parser.AstValue.getValue(AstValue.java:204)
    at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:226)
    at org.jboss.weld.el.WeldValueExpression.getValue(WeldValueExpression.java:50)
    at com.sun.faces.facelets.el.ContextualCompositeValueExpression.getValue(ContextualCompositeValueExpression.java:158)
    at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
    at javax.faces.component.UIComponentBase$AttributesMap.get(UIComponentBase.java:2427)
    at com.sun.faces.el.CompositeComponentAttributesELResolver$ExpressionEvalMap.get(CompositeComponentAttributesELResolver.java:393)
    at javax.el.MapELResolver.getValue(MapELResolver.java:199)
    at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
    at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
    at com.sun.el.parser.AstValue.getValue(AstValue.java:140)
[a few more hundred lines]

当我在Entity0.getReference中放置调试器断点时,我发现它在StackOverflowError之前被调用了一次。

Afaik其他SO问题中涉及的唯一其他问题是using rendered to break the recursion,由于视图构建时间与视图渲染时间不同而无效。

我希望递归会导致&#34; Hello world!&#34;标签要显示两次,因为private Entity0 reference = new Entity0(new Entity0(null));定义的深度为2(Entity0是一个只有一个属性的类,它是对自身的引用)然后是&#34;递归终止标签& #34;

可以在https://gitlab.com/krichter/jsf-avoid-nested-rendered-evaluation找到SSCCE。

我在Payara 4.1.2.181上使用Primefaces 6.2。

0 个答案:

没有答案